一、主表与外键表的映射关系
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200502214544125.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NTYwMjIyNw==,size_16,color_FFFFFF,t_70)
+++ 外键表与主键表的关系
外键表的外键受到主键表的主键所约束。
+++ 集合映射
描述外键表与主键表的映射关系,有好几种方式。
本文只是讲解了集合映射。集合映射只能映射主键表的简单字段。
list集合映射:
映射的主键表只能有三个字段(主键、序列字段、简单字段)
array映射:
映射的主键表只能有三个字段(主键、序列字段、简单字段)
set映射:
映射的主键表只能有两个字段(主键、简单字段)
Map映射:
映射的主键表只能有三个字段(主键、简单字段、简单字段)
二、集合映射
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="cn.itcast.a_collection">
<class name="User" table="t_user">
<id name="userId" column="id">
<generator class="native"></generator>
</id>
<property name="userName"></property>
<!--
set集合属性的映射
name 指定要映射的set集合的属性
table 集合属性要映射到的表
key 指定集合表(t_address)的外键字段
element 指定集合表的其他字段
type 元素类型,一定要指定
-->
<set name="address" table="t_address">
<key column="uid"></key>
<element column="address" type="string"></element>
</set>
<!--
list集合映射
list-index 指定的是排序列的名称 (因为要保证list集合的有序)
-->
<list name="addressList" table="t_addressList">
<key column="uid"></key>
<list-index column="idx"></list-index>
<element column="address" type="string"></element>
</list>
<!-- 数组映射 -->
<array name="addressArr" table="a_address">
<key column="a_id"></key>
<list-index column="idx"></list-index>
<element column="a_address" type="string"></element>
</array>
<!--
map集合的映射
key 指定外键字段
map-key 指定map的key
element 指定map的value
元素必须存在,且顺序不能颠倒
-->
<map name="addressMap" table="t_addressMap">
<key column="uid"></key>
<map-key column="shortName" type="string" ></map-key>
<element column="address" type="string" ></element>
</map>
</class>
</hibernate-mapping>
2.1 集合映射的分类
+++ 集合映射:
1.List集合映射
2.Set集合映射
3.数组映射
4.Map映射
+++ 集合映射映射的表是外键表。且外键表只有简单几个字段。
1.Set集合映射的外键表(两个字段)
key:映射外键表的外键
element:映射外键表的其他字段。
2.List集合映射的外键表(三个字段)
key:映射外键表的外键
list-index:映射外键表的计数字段(从0开始)
element:映射外键表的其他字段。
3.Array数组映射的外键表,和List集合一致。(三个字段)
4.Map集合映射的外键表(三个字段)
key:映射外键表的外键
map-key:映射外键表的key字段。
element:映射外键表的其他字段。
集合映射,映射的集合元素,都是普通的类型, 不能映射对象类型?
2.2 集合数据的映射 – 综合案例
===>> StudentEntity.java
public class StudentEntity {
private int id;
private String name;
private Set<String> addressSet;
private List<String> addressList;
private String[] addressArr;
private Map<String,String> addressMap;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Set<String> getAddressSet() {
return addressSet;
}
public void setAddressSet(Set<String> addressSet) {
this.addressSet = addressSet;
}
public List<String> getAddressList() {
return addressList;
}
public void setAddressList(List<String> addressList) {
this.addressList = addressList;
}
public Map<String, String> getAddressMap() {
return addressMap;
}
public void setAddressMap(Map<String, String> addressMap) {
this.addressMap = addressMap;
}
public String[] getAddressArr() {
return addressArr;
}
public void setAddressArr(String[] addressArr) {
this.addressArr = addressArr;
}
}
===>> Student.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="org.jsoft.set" >
<class name="StudentEntity" table="stu1">
<!-- 主键 ,映射 -->
<id name="id" column="stu_id" >
<generator class="native"/>
</id>
<!-- 非主键,映射 -->
<property name="name" column="stu_name"></property>
<!-- set映射 -->
<set name="addressSet" table="s_address">
<!-- 外键 -->
<key column="s_id" ></key>
<element column="s_address" type="string"></element>
</set>
<!-- list映射 -->
<list name="addressList" table="l_address">
<key column="l_id"></key>
<list-index column="idx"></list-index>
<element column="l_address" type="string"></element>
</list>
<!-- 数组映射 -->
<array name="addressArr" table="a_address">
<key column="a_id"></key>
<list-index column="idx"></list-index>
<element column="a_address" type="string"></element>
</array>
<!-- map映射 -->
<map name="addressMap" table="m_address">
<key column="m_id"></key>
<map-key column="shortName" type="string" ></map-key>
<element column="address" type="string" ></element>
</map>
</class>
</hibernate-mapping>
===>> hibernate.cfg.xml
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<!-- 通常,一个session-factory节点代表一个数据库 -->
<session-factory >
<!-- 1. 数据库连接配置 -->
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/js</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">root</property>
<!--
数据库方法配置, hibernate在运行的时候,会根据不同的方言生成符合当前数据库语法的sql
-->
<property name="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</property>
<!-- 2. 其他相关配置 -->
<!-- 2.1 显示hibernate在运行时候执行的sql语句 -->
<property name="hibernate.show_sql">true</property>
<!-- 2.2 格式化sql -->
<property name="hibernate.format_sql">false</property>
<!-- 2.3 自动建表 -->
<property name="hibernate.hbm2ddl.auto">create</property>
<!-- 3. 加载所有映射 -->
<mapping resource="org/jsoft/set/Student.hbm.xml"/>
</session-factory>
</hibernate-configuration>
===>> Demo.java
public class Demo {
public static SessionFactory sf;
static {
sf=new Configuration()
.configure()
.buildSessionFactory();
}
@Test
public void testSaveSet() {
Set<String> addressSet=new HashSet<String>();
addressSet.add("江苏南京");
addressSet.add("浙江杭州");
List<String> list=new ArrayList<String>();
list.add("上海11");
list.add("北京11");
String[] arr=new String[] {"12","12"};
Map<String,String> map=new HashMap<String,String>();
map.put("l1", "l1");
map.put("l11", "l11");
StudentEntity stu=new StudentEntity();
stu.setName("hlp");
stu.setAddressSet(addressSet);
stu.setAddressList(list);
stu.setAddressMap(map);
stu.setAddressArr(arr);
Session session = sf.openSession();
Transaction tr = session.beginTransaction();
session.save(stu);
tr.commit();
}
}
1.3 集合数据的获取
1.获取对象数据时,外键表数据是懒加载的。不会自动获取外键表数据。
对象中包含主表数据和外键表数据。
查询对象数据时,只会查询主表数据。但不会查询外键表数据。
只有通过对象获取外键表数据时,才会查询数据库。
2.由于有完整的映射关系,所以通过对象获取外键表数据时,就会查询数据库。
@Test
public void testGet() throws Exception {
Session session = sf.openSession();
session.beginTransaction();
User user = (User) session.get(User.class, 3);
System.out.println(user.getUserId());
System.out.println(user.getUserName());
System.out.println(user.getAddressList());
session.getTransaction().commit();
session.close();
}
二、Set集合映射
<set name="address" table="t_address">
<key column="uid"></key>
<element column="address" type="string"></element>
</set>
set标签:映射主键表。
name 指定要映射的set类型的属性名
table 指定要映射的表名
key标签:指定主键表的主键字段。(外键表的外键字段由主键表的主键所约束)
column 配置字段名。字段名可以随便设置。它会自动由主表的id约束。
element标签:指定外键表的其他字段。
type 元素类型,一定要指定
===>> StudentEntity.java
public class StudentEntity {
private int id;
private String name;
private Set<String> addressSet;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Set<String> getAddressSet() {
return addressSet;
}
public void setAddressSet(Set<String> addressSet) {
this.addressSet = addressSet;
}
}
===>> Student.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="org.jsoft.set" >
<class name="StudentEntity" table="stu1">
<!-- 主键 ,映射 -->
<id name="id" column="stu_id" >
<generator class="native"/>
</id>
<!-- 非主键,映射 -->
<property name="name" column="stu_name"></property>
<!--
set集合属性的映射
name 指定要映射的set集合的属性
table 集合属性要映射到的表
key 指定集合表(t_address)的外键字段
element 指定集合表的其他字段
type 元素类型,一定要指定
-->
<set name="addressSet" table="s_address">
<!-- 外键 -->
<key column="s_id" ></key>
<element column="s_address" type="string"></element>
</set>
</class>
</hibernate-mapping>
===>> hibernate.cfg.xml
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<!-- 通常,一个session-factory节点代表一个数据库 -->
<session-factory >
<!-- 1. 数据库连接配置 -->
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/js</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">root</property>
<!--
数据库方法配置, hibernate在运行的时候,会根据不同的方言生成符合当前数据库语法的sql
-->
<property name="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</property>
<!-- 2. 其他相关配置 -->
<!-- 2.1 显示hibernate在运行时候执行的sql语句 -->
<property name="hibernate.show_sql">true</property>
<!-- 2.2 格式化sql -->
<property name="hibernate.format_sql">false</property>
<!-- 2.3 自动建表 -->
<property name="hibernate.hbm2ddl.auto">create</property>
<!-- 3. 加载所有映射 -->
<mapping resource="org/jsoft/set/Student.hbm.xml"/>
</session-factory>
</hibernate-configuration>
===>> Demo.java
public class Demo {
public static SessionFactory sf;
static {
sf=new Configuration()
.configure()
.buildSessionFactory();
}
@Test
public void testSaveSet() {
Set<String> addressSet=new HashSet<String>();
addressSet.add("江苏南京");
addressSet.add("浙江杭州");
StudentEntity stu=new StudentEntity();
stu.setName("hlp");
stu.setAddressSet(addressSet);
Session session = sf.openSession();
Transaction tr = session.beginTransaction();
session.save(stu);
tr.commit();
}
}
三、List集合映射
<list name="addressList" table="t_addressList">
<key column="uid"></key>
<list-index column="idx"></list-index>
<element column="address" type="string"></element>
</list>
list集合映射
key 映射外键表的外键字段
list-index 映射外键表的有序字段。必须存在
指定的是排序列的名称 (因为要保证list集合的有序)
element 映射外键表的其他字段。
三个字段必须存在,且顺序不能颠倒。否则报错
===>> StudentEntity.java
public class StudentEntity {
private int id;
private String name;
private List<String> addressList;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<String> getAddressList() {
return addressList;
}
public void setAddressList(List<String> addressList) {
this.addressList = addressList;
}
}
===>> Student.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="org.jsoft.set" >
<class name="StudentEntity" table="stu1">
<!-- 主键 ,映射 -->
<id name="id" column="stu_id" >
<generator class="native"/>
</id>
<!-- 非主键,映射 -->
<property name="name" column="stu_name"></property>
<!--
list集合映射
list-index 指定的是排序列的名称 (因为要保证list集合的有序)
-->
<list name="addressList" table="l_address">
<key column="l_id"></key>
<list-index column="idx"></list-index>
<element column="l_address" type="string"></element>
</list>
</class>
</hibernate-mapping>
===>> hibernate.cfg.xml
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<!-- 通常,一个session-factory节点代表一个数据库 -->
<session-factory >
<!-- 1. 数据库连接配置 -->
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/js</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">root</property>
<!--
数据库方法配置, hibernate在运行的时候,会根据不同的方言生成符合当前数据库语法的sql
-->
<property name="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</property>
<!-- 2. 其他相关配置 -->
<!-- 2.1 显示hibernate在运行时候执行的sql语句 -->
<property name="hibernate.show_sql">true</property>
<!-- 2.2 格式化sql -->
<property name="hibernate.format_sql">false</property>
<!-- 2.3 自动建表 -->
<property name="hibernate.hbm2ddl.auto">create</property>
<!-- 3. 加载所有映射 -->
<mapping resource="org/jsoft/set/Student.hbm.xml"/>
</session-factory>
</hibernate-configuration>
===>> Demo.java
public class Demo {
public static SessionFactory sf;
static {
sf=new Configuration()
.configure()
.buildSessionFactory();
}
@Test
public void testSaveSet() {
List<String> list=new ArrayList<String>();
list.add("上海11");
list.add("北京11");
StudentEntity stu=new StudentEntity();
stu.setName("hlp");
stu.setAddressList(list);
Session session = sf.openSession();
Transaction tr = session.beginTransaction();
session.save(stu);
tr.commit();
}
}
四、数组映射
<array name="addressArr" table="a_address">
<key column="a_id"></key>
<list-index column="idx"></list-index>
<element column="a_address" type="string"></element>
</array>
数组映射
key 映射外键表的外键字段
list-index 映射外键表的有序字段。
指定的是排序列的名称 (因为要保证list集合的有序)
element 映射外键表的其他字段。
三个字段必须存在,且顺序不能颠倒。否则报错
===>> StudentEntity.java
public class StudentEntity {
private int id;
private String name;
private String[] addressArr;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String[] getAddressArr() {
return addressArr;
}
public void setAddressArr(String[] addressArr) {
this.addressArr = addressArr;
}
}
===>> Student.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="org.jsoft.set" >
<class name="StudentEntity" table="stu1">
<!-- 主键 ,映射 -->
<id name="id" column="stu_id" >
<generator class="native"/>
</id>
<!-- 非主键,映射 -->
<property name="name" column="stu_name"></property>
<!-- 数组映射 -->
<array name="addressArr" table="a_address">
<key column="a_id"></key>
<list-index column="idx"></list-index>
<element column="a_address" type="string"></element>
</array>
</class>
</hibernate-mapping>
===>> hibernate.cfg.xml
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<!-- 通常,一个session-factory节点代表一个数据库 -->
<session-factory >
<!-- 1. 数据库连接配置 -->
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/js</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">root</property>
<!--
数据库方法配置, hibernate在运行的时候,会根据不同的方言生成符合当前数据库语法的sql
-->
<property name="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</property>
<!-- 2. 其他相关配置 -->
<!-- 2.1 显示hibernate在运行时候执行的sql语句 -->
<property name="hibernate.show_sql">true</property>
<!-- 2.2 格式化sql -->
<property name="hibernate.format_sql">false</property>
<!-- 2.3 自动建表 -->
<property name="hibernate.hbm2ddl.auto">create</property>
<!-- 3. 加载所有映射 -->
<mapping resource="org/jsoft/set/Student.hbm.xml"/>
</session-factory>
</hibernate-configuration>
===>> Demo.java
public class Demo {
public static SessionFactory sf;
static {
sf=new Configuration()
.configure()
.buildSessionFactory();
}
@Test
public void testSaveSet() {
String[] arr=new String[] {"12","12"};
StudentEntity stu=new StudentEntity();
stu.setName("hlp");
stu.setAddressArr(arr);
Session session = sf.openSession();
Transaction tr = session.beginTransaction();
session.save(stu);
tr.commit();
}
}
五、Map集合映射
<map name="addressMap" table="m_address">
<key column="m_id"></key>
<map-key column="shortName" type="string" ></map-key>
<element column="address" type="string" ></element>
</map>
map集合映射
key 映射外键表的外键字段
map-key 映射外键表的key。
element 映射外键表的其他字段。
三个字段必须存在,且顺序不能颠倒。否则报错
===>> StudentEntity.java
public class StudentEntity {
private int id;
private String name;
private Map<String,String> addressMap;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Map<String, String> getAddressMap() {
return addressMap;
}
public void setAddressMap(Map<String, String> addressMap) {
this.addressMap = addressMap;
}
}
===>> Student.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="org.jsoft.set" >
<class name="StudentEntity" table="stu1">
<!-- 主键 ,映射 -->
<id name="id" column="stu_id" >
<generator class="native"/>
</id>
<!-- 非主键,映射 -->
<property name="name" column="stu_name"></property>
<!-- map映射 -->
<map name="addressMap" table="m_address">
<key column="m_id"></key>
<map-key column="shortName" type="string" ></map-key>
<element column="address" type="string" ></element>
</map>
</class>
</hibernate-mapping>
===>> hibernate.cfg.xml
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<!-- 通常,一个session-factory节点代表一个数据库 -->
<session-factory >
<!-- 1. 数据库连接配置 -->
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/js</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">root</property>
<!--
数据库方法配置, hibernate在运行的时候,会根据不同的方言生成符合当前数据库语法的sql
-->
<property name="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</property>
<!-- 2. 其他相关配置 -->
<!-- 2.1 显示hibernate在运行时候执行的sql语句 -->
<property name="hibernate.show_sql">true</property>
<!-- 2.2 格式化sql -->
<property name="hibernate.format_sql">false</property>
<!-- 2.3 自动建表 -->
<property name="hibernate.hbm2ddl.auto">create</property>
<!-- 3. 加载所有映射 -->
<mapping resource="org/jsoft/set/Student.hbm.xml"/>
</session-factory>
</hibernate-configuration>
===>> Demo.java
public class Demo {
public static SessionFactory sf;
static {
sf=new Configuration()
.configure()
.buildSessionFactory();
}
@Test
public void testSaveSet() {
Map<String,String> map=new HashMap<String,String>();
map.put("l1", "l1");
map.put("l11", "l11");
StudentEntity stu=new StudentEntity();
stu.setName("hlp");
stu.setAddressMap(map);
Session session = sf.openSession();
Transaction tr = session.beginTransaction();
session.save(stu);
tr.commit();
}
}