Hibernate的一对多的关系查询
不管一对多还是多对一,在另一个实体类中声明一个实体类对象属性来封装数据,
将查询的多个表的数据封装这个实体类的对象里面,通过配置来说实现。
配置的步骤
- 创建一个可以存储多个表数据的实体类,实体类根据数据库的关系建立映射关系
在Customer的实体类中添加多一个属性
//将外表的查询数据封装到一个实体类中,然后用一个集合来封装
private Set<Linkman> linkmans =new HashSet<>();
public Set<Linkman> getLinkmans() {
return linkmans;
}
public void setLinkmans(Set<Linkman> linkmans) {
this.linkmans = linkmans;
}
将查询的多个表的数据封装这个实体类的对象里面,通过配置来说实现。
Customer的映射文件中配置关系,就不用我们手动封装数据
注意:
1. 必须知道为什么配置set标签,因为客户实体类就是使用Set集合!
1. 必须知道为什么需要配置外键,因为任何的数据库关系都是通过外键建立的
set标签:用于配置实体类的Set集合
- name:用于指定*set集合的属性名*,通过属性名对应配置是属于哪一个set
key标签:用于设置两个表关联的外键
- column:设置外键的字段名
<!-- 配置一对多的关系 -->
<!--
set标签:用于配置实体类的Set集合
name:用于指定set集合的属性名,通过属性名对应配置是属于哪一个set
-->
<set name="linkmans">
<!--
key标签:用于设置两个表关联的外键
column:设置外键的字段名
-->
<key column="lkm_cust_id"></key>
<!--
one-to-many声明关系
声明关联的是一对多的关系
class属性:指定集合的元素的类型
-->
<one-to-many class="com.entity.Linkman" />
</set>
然后在hbm中写上linkman的mapping映射文件
注意:不要忘了在Hibernate.cfg.xml里面加载
测试代码:
//需求:通过ID查询一条客户表的记录,同时查询该记录的对应的联系人的信息!
@Test
public void get(){
//1.获得操作对象
Session session = HibernateUtils.getSession();
//2.通过OID获得对象
Customer customer = session.get(Customer.class, 2L);
System.out.println("客户名:"+customer.getCustName());
Set<Linkman> linkmans = customer.getLinkmans();
for(Linkman linkman:linkmans){
System.out.println("联系人名"+linkman.getLkmName());
}
//6.关闭连接
session.close();
}
代码
两个持久化类
Customer
public class Customer {
private Long custId;//bigint(32) NOT NULL AUTO_INCREMENT COMMENT '客户编号(主键)',
private String custName;//varchar(32) NOT NULL COMMENT '客户名称(公司名称)',
private String custSource;//varchar(32) DEFAULT NULL COMMENT '客户信息来源',
private String custIndustry;//varchar(32) DEFAULT NULL COMMENT '客户所属行业',
private String custLevel;//varchar(32) DEFAULT NULL COMMENT '客户级别',
private Set<Linkman> linkmans = new HashSet<Linkman>();//封装一对多的数据
public Set<Linkman> getLinkmans() {
return linkmans;
}
public void setLinkmans(Set<Linkman> linkmans) {
this.linkmans = linkmans;
}
get()/set()......
}
Linkman
public class Linkman {
private Long lkmId;//主键
private String lkmName;
private Long lkmCustId;//外键
private String lkmGender;
private String lkmPhone;
private String lkmMobile;
private String lkmEmail;
private String lkmQq;
private String lkmPosition;
private String lkmMemo;
get()/set()......
}
配置的映射文件
Customer.hbm.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "hibernate-mapping-3.0.dtd" >
<hibernate-mapping>
<!-- 配置实体类名和表名的关系 -->
<!--
name:字段类的全限制名,就是包含包名的类名
table:制定实体类对应的表明
class标签:作用,用于设置实体类和表的关系
-->
<class name="com.entity.Customer" table="cst_customer">
<!-- 实体类属性名和数据表字段名的关系 -->
<!-- ID字段 -->
<id name="custId" column="cust_id">
<!--
id必须制定逐渐生成策略
主键生成策略,所谓的主键生成策略就是生成主键字段值的方式
generator:主键生成策略通过generator标签设置
native:本地的,就是使用数据库自身的自增长策略
-->
<generator class="native"></generator>
</id>
<!-- 普通字段 -->
<property name="custName" column="cust_name"></property>
<property name="custSource" column="cust_source"></property>
<property name="custIndustry" column="cust_industry"></property>
<property name="custLevel" column="cust_level"></property>
<!-- 配置一对多的关系 -->
<!--
set标签:用于配置实体类的Set集合
name:用于指定set集合的属性名,通过属性名对应配置是属于哪一个set
-->
<set name="linkmans">
<!--
key标签:用于设置两个表关联的外键
column:设置外键的字段名
-->
<key column="lkm_cust_id"></key>
<!--
声明关系
声明关联的是一对多的关系
class属性:指定集合的元素的类型
-->
<one-to-many class="com.entity.Linkman" />
</set>
</class>
</hibernate-mapping>
Linkman.hbm.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "hibernate-mapping-3.0.dtd" >
<hibernate-mapping>
<class name="com.entity.Linkman" table="cst_linkman">
<id name="lkmId" column="lkm_id">
<generator class="identity"></generator>
</id>
<property name="lkmName" column="lkm_name"></property>
<property name="lkmCustId" column="lkm_cust_id"></property>
<property name="lkmGender" column="lkm_gender"></property>
<property name="lkmPhone" column="lkm_phone"></property>
<property name="lkmMobile" column="lkm_mobile"></property>
<property name="lkmEmail" column="lkm_email"></property>
<property name="lkmQq" column="lkm_qq"></property>
<property name="lkmPosition" column="lkm_position"></property>
<property name="lkmMemo" column="lkm_memo"></property>
</class>
</hibernate-mapping>
总配置文件hibernate.cfg.xml
两个hbm.xml都要加载
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "hibernate-configuration-3.0.dtd" >
<!-- 跟标签 -->
<hibernate-configuration>
<!-- 配置一个数据库连接 -->
<session-factory>
<!--
四个要素
property标签:用于设置框架的启动需要的属性
任何框架的环境参数,都可以在代码里面可以找到,一般配置文件的包名
一般都在这些包名中cfg,conf,config,build
-->
<!-- 驱动 -->
<property name="hibernate.connection.driver_class">org.gjt.mm.mysql.Driver</property>
<!-- 连接字符串 -->
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/hibernate01</property>
<!-- 用户名 -->
<property name="hibernate.connection.username">root</property>
<!-- 密码 -->
<property name="hibernate.connection.password">root</property>
<!-- 显示SQL语句 -->
<property name="hibernate.show_sql">true</property>
<!-- 格式化显示SQL语句 -->
<property name="hibernate.format_sql">true</property>
<!--
数据库的方言默认根据连接的信息自动加载了,可以不用配置,但自动加载并不是最优化的,建议配置的方言和数据库的引擎以及版本一致
-->
<property name="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</property>
<!-- 加载映射文件 -->
<mapping resource="com/entity/hmb/Customer.hbm.xml"/>
<mapping resource="com/entity/hmb/Linkman.hbm.xml"/>
</session-factory>
</hibernate-configuration>