知乎专栏 |
@ElementCollection 很像 @OneToMany,甚至有些场景可以相互替代,@ElementCollection 更适合 List/Set/Map/Array 等数据类型,而 @OneToMany 是对应一个实体。
ElementCollection 缺点是,不能对集合表进行 CURD操作
import javax.persistence.*; import java.util.*; import javax.persistence.*; @Entity public class Employee { @Id @GeneratedValue(strategy = GenerationType.AUTO) private int id; private String name; @ElementCollection private Set<Address> address = new HashSet<Address>(); }
import javax.persistence.*; @Embeddable public class Address { private String province; private String city; private String state; }
List 集合
@ElementCollection(targetClass = String.class) //指定集合中元素的类型 @CollectionTable(name = "school_inf", joinColumns = @JoinColumn(name="pid",nullable = false)) //表示外键不能为空 @Column(name = "school_name") //指定表中保存集合元素的列名 @OrderColumn(name = "list_order") //索引列 private List<String> schools = new ArrayList<String>();
数组集合
@Entity @Table public class Student { @Id @Column @GeneratedValue(strategy = GenerationType.IDENTITY) private Integer sid; private String name; private Integer age; @ElementCollection(targetClass=String.class) //集合中元素的类型 @CollectionTable(name = "school", joinColumns = @JoinColumn(name="sid",nullable = false))//指定外键的名称为sid,并且不能为空 @Column(name = "school_name") //指定schools属性,在表中的列名 @OrderColumn(name = "array_order") private String[] schools = new String[3]; }
Map 集合
@Entity @Table(name = "student") public class Student { @Id @Column @GeneratedValue(strategy = GenerationType.IDENTITY) private Integer sid; private String name; private Integer age; @ElementCollection(targetClass = Float.class) //对于Map类型的属性:指定的是Value的类型 @CollectionTable(name = "score_info", joinColumns = @JoinColumn(name="sid", nullable = false)) @MapKeyClass(String.class) // 指定Map中key的类型 @MapKeyColumn(name="suject") //指定索引列,也就是key的列名 @Column(name = "score") //映射保存Map, Value的列名 private Map<String, Float> scores = new HashMap<String, Float>(); //科目和成绩 }
Set 集合
@ElementCollection private final Set<String> address = new HashSet<String>();
@ElementCollection @CollectionTable(joinColumns = @JoinColumn(name = "pid", nullable = false)) private Set<Status> address = new HashSet<Status>();
package cn.netkiller.domain; import jakarta.persistence.*; import lombok.Data; import org.hibernate.annotations.Comment; import org.hibernate.annotations.DynamicInsert; import org.hibernate.annotations.DynamicUpdate; import java.io.Serial; import java.io.Serializable; import java.util.Date; import java.util.HashSet; import java.util.Set; @Entity @Table @DynamicUpdate @DynamicInsert @Data @Comment("Stable Diffusion Lora 表") public class Lora implements Serializable { @Serial public static final long serialVersionUID = 1L; @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "id", unique = true, nullable = false, insertable = false, updatable = false, columnDefinition = "int unsigned") @Comment("主键") private Long id; @Column(unique = true, nullable = false, insertable = true, updatable = true) @Comment("模型名称") private String name; @Comment("模型描述") private String description; @ElementCollection(fetch = FetchType.EAGER) private Set<String> keyword = new HashSet<String>(); @Comment("状态") private boolean status; @Column(insertable = false, updatable = false, columnDefinition = "TIMESTAMP DEFAULT CURRENT_TIMESTAMP") @Comment("创建时间") private Date ctime; @Column(nullable = true, insertable = false, updatable = false, columnDefinition = "TIMESTAMP NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP") @Comment("修改时间") private Date mtime; }
package cn.netkiller.repository; import cn.netkiller.domain.Lora; import org.springframework.data.repository.CrudRepository; import org.springframework.stereotype.Repository; import java.util.Optional; import java.util.Set; @Repository public interface LoraRepository extends CrudRepository<Lora, Integer> { }
package cn.netkiller.controller; import cn.netkiller.domain.Lora; import cn.netkiller.repository.LoraRepository; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import java.util.Optional; import java.util.Set; @RestController @Slf4j @RequestMapping("/lora") public class LoraController { @Autowired private LoraRepository loraRepository; @GetMapping("test") public Lora test() { Lora lora = new Lora(); lora.setName("中国风"); lora.setDescription("中国风格图片"); lora.setKeyword(Set.of("茶", "武术", "剪纸")); loraRepository.save(lora); lora = new Lora(); lora.setName("二次元"); lora.setDescription("二次元风格图片"); lora.setKeyword(Set.of("日本", "机甲", "手办")); loraRepository.save(lora); return lora; } @GetMapping("query") public Iterable<Lora> query() { Iterable<Lora> lora = loraRepository.findAll(); return lora; } }