组件映射
持久化类的属性可能是一个对象,现在又一个Person
类,如下:
@Entity
@Table(name = "person_inf")
public class Person_obj {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private int age;
//Name对象
private Name name;
//省略set、get、构造函数
...
}
name
属性是一个Name
对象,查看Name
类:
@Embeddable
public class Name {
@Column(name = "person_firstname")
private String first;
@Column(name = "person_lastname")
private String last;
@Parent
private Person_obj owner;
//省略set、get、构造函数
...
}
为了让Name
可以做为持久化对象的属性使用,需要使用@Embeddable
注解,该注解不需要指定参数。同时需要在该该类中包含一个属性,该属性类型为持久化类,同时要使用@Parent
注解。
测试代码:
session.beginTransaction();
Person_obj personObj = new Person_obj();
personObj.setAge(29);
personObj.setName(new Name("hu", "wenze"));
session.save(personObj);
session.getTransaction().commit();
数据库数据:
mysql> select * from person_inf;
+----+-----+------------------+-----------------+
| id | age | person_firstname | person_lastname |
+----+-----+------------------+-----------------+
| 1 | 29 | hu | wenze |
| 2 | 29 | hu | wenze |
+----+-----+------------------+-----------------+
2 rows in set (0.00 sec)
可以看到数据表中多了2列,后两列是Name
类中的属性。
组件集合映射
持久化类的属性可能是一个集合,比如List
,并且List
的元素是一个对象,这种其实就是集合映射和组件映射的整合。
现在有一个Person
类,该类有一个List
属性,其元素为Name
类型; 有一个Map
属性,其键为String
,值为Score
类型。
Person
类:
@Entity
@Table(name = "person_inf")
public class Person_obj_list {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private int age;
@ElementCollection(fetch = FetchType.LAZY, targetClass = Score.class)
@CollectionTable(name = "score_inf",
joinColumns = @JoinColumn(name = "person_id", nullable = false))
@MapKeyClass(String.class)
@MapKeyColumn(name = "class_name")
@Column(name = "score_val")
private Map<String, Score> scores = new HashMap<>();
@ElementCollection(fetch = FetchType.LAZY, targetClass = Name.class)
@CollectionTable(name = "nick_inf",
joinColumns = @JoinColumn(name = "person_id", nullable = false))
@OrderColumn(name = "list_order")
private List<Name> nicks = new ArrayList<>();
//省略set、get、构造函数
...
}
Name
类:
@Embeddable
public class Name {
@Column(name = "person_firstname")
private String first;
@Column(name = "person_lastname")
private String last;
@Parent
private Person_obj_list owner;
//省略set、get、构造函数
...
}
Score
类:
@Embeddable
public class Score {
@Column(name = "Score_math")
private double math;
@Column(name = "Score_science")
private double science;
@Parent
private Person_obj_list owner;
//省略set、get、构造函数
...
}
测试代码:
session.beginTransaction();
Person_obj_list personObjList = new Person_obj_list();
personObjList.setAge(21);
personObjList.getNicks().add(new Name("hu", "wenze"));
personObjList.getNicks().add(new Name("hu1", "wenze"));
personObjList.getNicks().add(new Name("hu", "wenze1"));
personObjList.getScores().put("key2", new Score(1.5, 2.5));
personObjList.getScores().put("key1", new Score(3.5, 1.1));
session.save(personObjList);
session.getTransaction().commit();
数据库数据:
person_inf
表
mysql> select * from person_inf;
+----+-----+
| id | age |
+----+-----+
| 1 | 21 |
+----+-----+
1 row in set (0.00 sec)
持久化类的List
属性对应nick_inf
:
mysql> select * from nick_inf;
+-----------+------------------+-----------------+------------+
| person_id | person_firstname | person_lastname | list_order |
+-----------+------------------+-----------------+------------+
| 1 | hu | wenze | 0 |
| 1 | hu1 | wenze | 1 |
| 1 | hu | wenze1 | 2 |
+-----------+------------------+-----------------+------------+
3 rows in set (0.00 sec)
持久化类的Map
属性对应score_inf
表:
mysql> select * from score_inf;
+-----------+------------+---------------+------------+
| person_id | Score_math | Score_science | class_name |
+-----------+------------+---------------+------------+
| 1 | 3.5 | 1.1 | key1 |
| 1 | 1.5 | 2.5 | key2 |
+-----------+------------+---------------+------------+
2 rows in set (0.00 sec)
可以看到,组件集合属性映射就是组件映射+集合映射,理解好组件映射和集合映射后,很容易理解这种情况。