首页 > 技术文章 > hibernate详细教程(一对多操作,多对多不讲)

csh520mjy 2019-06-17 18:53 原文

一、Hibernate的一对多关联映射紧跟上文

1. 创建数据库和表

CREATE TABLE `linkman` (

  `lkm_id` bigint(32) NOT NULL AUTO_INCREMENT COMMENT '联系人编号(主键)',

  `lkm_name` varchar(16) DEFAULT NULL COMMENT '联系人姓名',

  `lkm_cust_id` bigint(32) DEFAULT NULL COMMENT '客户id',

  `lkm_gender` char(1) DEFAULT NULL COMMENT '联系人性别',

  `lkm_phone` varchar(16) DEFAULT NULL COMMENT '联系人办公电话',

  `lkm_mobile` varchar(16) DEFAULT NULL COMMENT '联系人手机',

  `lkm_email` varchar(64) DEFAULT NULL COMMENT '联系人邮箱',

  `lkm_qq` varchar(16) DEFAULT NULL COMMENT '联系人qq',

  `lkm_position` varchar(16) DEFAULT NULL COMMENT '联系人职位',

  `lkm_memo` varchar(512) DEFAULT NULL COMMENT '联系人备注',

  PRIMARY KEY (`lkm_id`),

  KEY `FK_linkman_lkm_cust_id` (`lkm_cust_id`),

  CONSTRAINT `FK_linkman_lkm_cust_id` FOREIGN KEY (`lkm_cust_id`) REFERENCES `customer` (`cust_id`) ON DELETE NO ACTION ON UPDATE NO ACTION

) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

 

 

2. 创建likman实体类

private int lkm_id;

private String lkm_name;

private int lkm_cust_id;

private String lkm_gender;

private String lkm_phone;

private String lkm_mobile;

private String lkm_qq;

private String lkm_email;

private String lkm_position;

private String lkm_memo;

 

private Customer customer;

3. 映射文件

多方:

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping package="com.itheima.bean">

<class name="LinkMan" table="linkman">

<id name="lkm_id" column="lkm_id">

<!-- generator:主键生成策略 -->

<generator class="native"></generator>

</id>

 

<property name="lkm_name" column="lkm_name" ></property>

<property name="lkm_gender" column="lkm_gender" ></property>

<property name="lkm_mobile" column="lkm_mobile" ></property>

<property name="lkm_phone" column="lkm_phone" ></property>

<property name="lkm_qq" column="lkm_qq" ></property>

<property name="lkm_email" column="lkm_email" ></property>

<property name="lkm_position" column="lkm_position" ></property>

<property name="lkm_memo" column="lkm_memo" ></property>

<!-- 一对多关系配置,配置  一 得一方 -->

<many-to-one name="customer" class="com.itheima.bean.Customer" column="lkm_cust_id"></many-to-one>

</class>

</hibernate-mapping>

一方:

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping package="com.itheima.bean">

<class name="Customer" table="customer">

<id name="cust_id" column="cust_id">

<!-- generator:主键生成策略 -->

<generator class="native"></generator>

</id>

 

<property name="cust_name" column="cust_name" ></property>

        <property name="cust_source" column="cust_source" ></property>

        <property name="cust_industry" column="cust_industry" ></property>

        <property name="cust_level" column="cust_level" ></property>

        <property name="cust_phone" column="cust_phone" ></property>

        <property name="cust_mobile" column="cust_mobile" ></property>

        

        <!-- 配置一对多,多方得对象 -->

        <set name="linkMans">

        <!-- 多方的关联外键 -->

        <key column="lkm_cust_id"/>

        <!-- 一方指向多方 -->

         <one-to-many class="com.itheima.bean.LinkMan"/>

        </set>

</class>

</hibernate-mapping>

 

4. 核心配置文件

添加:<mapping resource="com/itheima/bean/LinkMan.hbm.xml" />

5. 编写测试类

级联添加操作:

@Test

public void test1() {

Session session = HibernateUtils.OpenSession();

Transaction transaction = session.beginTransaction();

 

//创建两个客户

Customer customer1 = new Customer();

customer1.setCust_name("陈少华");

Customer customer2 = new Customer();

customer2.setCust_name("娃哈哈");

 

//创建三个联系人

LinkMan linkMan1 = new LinkMan();

linkMan1.setLkm_memo("凤姐");

LinkMan linkMan2 = new LinkMan();

linkMan2.setLkm_memo("如花");

LinkMan linkMan3 = new LinkMan();

linkMan3.setLkm_memo("旺财");

 

//设置关系

linkMan1.setCustomer(customer1);

linkMan2.setCustomer(customer1);

linkMan3.setCustomer(customer2);

 

//提交添加

session.save(linkMan1);

session.save(linkMan2);

session.save(linkMan3);

session.save(customer1);

session.save(customer2);

 

//事务提交

transaction.commit();

session.close();

}

级联操作:

 

/**

 * 保存客户 级联联系人

 */

@Test

public void test3() {

Session session = HibernateUtils.OpenSession();

Transaction transaction = session.beginTransaction();

 

Customer customer = new Customer();

customer.setCust_name("我爱刘德华");

LinkMan linkMan = new LinkMan();

linkMan.setLkm_memo("大妹妹");

 

//关系

linkMan.setCustomer(customer);

 

//提交

session.save(linkMan);

session.save(customer);

//事务提交

transaction.commit();

 

 

/**

 * 保存联系人级联客户

 */

@Test

public void test4() {

Session session = HibernateUtils.OpenSession();

Transaction transaction = session.beginTransaction();

 

 

Customer customer = new Customer();

customer.setCust_name("李德华");

LinkMan linkMan = new LinkMan();

linkMan.setLkm_memo("大小姐");

 

//关系

linkMan.setCustomer(customer);

//保存

session.save(linkMan);

//事务提交

transaction.commit();

session.close();

}

 

级联删除:删除一边,同时删除另一边

 

/**

 * 删除客户级联联系人常用

 */

@Test

public void test5() {

Session session = HibernateUtils.OpenSession();

Transaction transaction = session.beginTransaction();

 

Customer customer = session.get(Customer.class, 6);

session.delete(customer);

 

//事务提交

transaction.commit();

session.close();

 

}

 

6. 一对多设置了双向关联产生多余的SQL语句

   解决多余的SQL语句

   单向维护:

   使一方放弃外键维护权:

   一的一方放弃。set上配置inverse=true”(重要)

 

二、Hibernate对多关联映射自行百度就行了,还想往下看???????

 

一、Hibernate的抓取策略(优化)

 

延迟加载的概述

 

什么是延迟加载

 

延迟加载:lazy(懒加载)。执行到该行代码的时候,不会发送语句去进行查询,在真正使用这个对象的属性的时候才会发送SQL语句进行查询。

 

延迟加载的分类

 

 类级别的延迟加载

 

   指的是通过load方法查询某个对象的时候,是否采用延迟。session.load(Customer.class,1l);

 

   类级别延迟加载通过<class>上的lazy进行配置,如果让lazy失效

 

   lazy设置为false

 

   将持久化类使用final修饰

 

   Hibernate. Initialize()

 

 关联级别的延迟加载

 

   指的是在查询到某个对象的时候,查询其关联的对象的时候,是否采用延迟加载。

 

  Customer customer = session.get(Customer.class,1l);

 

  customer.getLinkMans();----通过客户获得联系人的时候,联系人对象是否采用了延迟加载,称为是关联级别的延迟。

 

   抓取策略往往会和关联级别的延迟加载一起使用,优化语句。

 

抓取策略

 

抓取策略的概述

 

 通过一个对象抓取到关联对象需要发送SQL语句,SQL语句如何发送,发送成什么样格式通过策略进行配置。

 

   通过<set>或者<many-to-one>上通过fetch属性进行设置

 

   fetch和这些标签上的lazy如何设置优化发送的SQL语句

 

<set>上的fetchlazy

 

 fetch:抓取策略,控制SQL语句格式

 

   select :默认值,发送普通的select语句,查询关联对象

 

   join :发送一条迫切左外连接查询关联对象

 

   subselect :发送一条子查询查询其关联对象

 

 lazy:延迟加载,控制查询关联对象的时候是否采用延迟

 

   true :默认值,查询关联对象的时候,采用延迟加载

 

   false :查询关联对象的时候,不采用延迟加载

 

   extra :及其懒惰。

 

  在实际开发中,一般都采用默认值。如果有特殊的需求,可能需要配置join

 

<many-to-one>上的fetchlazy

 

 fetch :抓取策略,控制SQL语句格式。

 

   select :默认值,发送普通的select语句,查询关联对象。

 

   join :发送一条迫切左外连接。

 

 lazy :延迟加载,控制查询关联对象的时候是否采用延迟。

 

   proxy :默认值,proxy具体的取值,取决于另一端的<class>上的lazy的值。

 

   false :查询关联对象,不采用延迟。

 

   no-proxy :(不会使用)

 

  在实际开发中,一般都采用默认值。如果有特殊的需求,可能需要配置join

 

 

 

推荐阅读