博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Hhibernateu关联关系第一次
阅读量:5357 次
发布时间:2019-06-15

本文共 9163 字,大约阅读时间需要 30 分钟。

今天上午我们老师的陪伴下练习一下Hibernate种尤为重要的一部分(关联关系)

级联关系类图:

在这个案例中我们使用一个部门可以有多个员工及(员工——部门表)来映射实体间的微妙关系

首先回忆在SqlServer中我们能想起来的关系

one:一

to:对应关系

money:多

  1)1——>1       一对一 单项关联关系(one-to-one)

  2)1——>n      一对多单项关联关系(one-to-money)

  3)n——>1      多对一单项关联关系(money-to-one)

  4)1<——>n    一对多的双向关联关系 (one-to-money)

  5)1<——>n      一对多的双向自身关联关系(one-to-money) 

基本上就这几种基本的关系其中4由于2和3也已经做了对应关系所以可以做双向关联

至于第五个就有的玩了,写过易买网或者树状菜单的都知道一张表实现连级连动他的好处是可以无限分类第5类一般出现在树形的组织结构中。至于表之间的关系介绍到 这了

下面开始分析类图

第一组图:

在员工(实体)中植入部门的一个实体——>多个员工对应一个部门

第二组图:

在部门(实体)中植入员工的Set集合——>一个部门可以有多个员工

注意(实体)二字因为Hibernate可以是面向对象的编程尽管那些HQL长的像SQL但是还是有一定的差别的,在这里重述一下官网推荐使用  select开头的查询语句

-------------------------------------------------------------------开发第一站-------------------------------------------------------

起步式:

在我们的分层架构下创建entity层

本次案例使用这个实体类和映射文件来操作

环境:ideat和oracle(已经在oracle中创建好了名称为y2166的用户并且等待hibernate自动创建表结构)

(Dept)

import java.util.HashSet;import java.util.Set;public class Dept {    private Integer deptno;    private String deptname;    private Set
emps=new HashSet
(); public Set
getEmps() { return emps; }

(Emp)

public class Emp {    private Integer empno;    private String empname;    private  Dept dept;

(Dept.hbbm.xml)

(Emp.hbm.xml)

(HibeernateUtil工具类)本次案例全站使用自定义的工具类..初学者的福利

package cn.happy.day07.util;import org.hibernate.Session;import org.hibernate.SessionFactory;import org.hibernate.Transaction;import org.hibernate.cfg.Configuration;public class HibernateUtil {    //线程变量  get set    static  ThreadLocal
tl=new ThreadLocal
(); //有SeesionFactory static Configuration cfg=null; static SessionFactory sessionFactory; static Transaction tx; static { cfg=new Configuration().configure("hibernatethree.cfg.xml"); sessionFactory=cfg.buildSessionFactory(); } //01.获取连接 public static Session getSession(){ //01.从线程变量中尝试获取 Session session = tl.get(); if(session==null){ //用户第一次获取连接,发现线程变量中没有session创建一个,并放入线程变量 session=sessionFactory.openSession(); tl.set(session); } return session; } //02.释放连接 public static void close(){ Session session = tl.get(); if(session!=null){ //线程变量set成null tl.set(null); session.close(); } }}

以上案例都是已经经过测试的完整版如果有想做测试的请谨慎参考可能会影响实验结果

----------------------------------------------------------------------------------------------开始办----------------------------------------------------------------------

1.开发案例一:

关于映射文件中的属性会在后面详解

 需求:关联查询,多对一关联关系

分析:

 

多个员工对用一个部门,所以我们在员工表中植入单个部门对象

private  Dept dept;

注意一定要做get和set因为底层还是用到了set方法赋值的

因为是从多的一方像一的一方所以在Emp映射文件中如下:

name的属性是Dept类中dept字段class是类的全路径类型column是当前表Dept类中的属性

注意这里一个知识点

tip:通过实体类的构建我们发现并没有在Emp类中植入dept表的deptno属性,这是我们可以把deptno,deptname,统一看成是一个Dept实体

通过Class的属性Hibernate通过set访问器自动寻址deptno的尽管如次当我们单侧成功的时候依然还是发现在数据底层数据表中的Ep表中生成关系字段deptno

数据库截图:

 

 

测试方法

//关联查询  多对一单项关联1    @Test    public void testmoneytonoebydouble(){        //工具类        Session session = HibernateUtil.getSession();        //提供一个员工的编号        Emp load = session.load(Emp.class, 1);        System.out.println(load.getEmpname());        //隶属的部门        System.out.println(load.getDept().getDeptname());    }

结果:

使用ideat在空控制台打印输出结果

2.开发案例二:

 需求:使用级联保存部门的同时保存员工

分析:使用导航属性在部门中添加员工更改映射文件的属性

 

cascade="save-update"

注意如果不这样写在保存的时候会报一个错误

object references an unsaved transient instance - save the transient instance before flushing: cn.happy.day07.entity.Emp

原因就是没有开启连及(cascade)

测试方法

//保存部门的同时保存员工2    @Test    public  void savedeptandEmp(){        Session session = HibernateUtil.getSession();        Transaction tx=session.beginTransaction();        Dept dept=new Dept();        dept.setDeptname("测试部1");        Emp emp=new Emp();        emp.setEmpname("小军1");        dept.getEmps().add(emp);        session.save(dept);        tx.commit();    }

结果:

 

3.开发案例三:

需求:按照指定的部门对象,查询相关的emp对象

分析:一对多在部门中植入员工Emp对象

private Set
emps=new HashSet
();

使用Set无序集合关于Set集合使用案例:

package cn.happy.day08;/** * Created by CY on 2017/12/28. */public class Dog {    private  Integer dogage;    private  String  dogname;    @Override    public int hashCode() {        int result=17;        result =result * 31+dogage;        System.out.println(result+"1");        result =result * 31+dogname.hashCode();        System.out.println(result+"2");        return result;    }   @Override    public boolean equals(Object obj) {       Dog dog= (Dog)obj;       if (this.getDogname().equals(dog.getDogname())){           return  true;       }        return false;    }    public Integer getDogage() {        return dogage;    }    public void setDogage(Integer dogage) {        this.dogage = dogage;    }    public String getDogname() {        return dogname;    }    public void setDogname(String dogname) {        this.dogname = dogname;    }}

简单的配置就好了记住其中的属性

s.k.o/n.c.c

测试方法:

@Test    //按照指定的部门对象,查询相关的emp对象    public void t3() {        Session session = HibernateUtil.getSession();        String hql = "from Emp e where e.dept.deptno=1";        Query query = session.createQuery(hql);        List
list = query.list(); for (Emp item : list) { System.out.println(item.getEmpname()); } session.close(); }

结果:

4.开发案例四

需求:修改员工的同时修改部门  使用连及 caseode和inversit

分析: 前面我们已经分别在两个配置文件中添加相互映射所以我们直接构建实体并绑定关系来警醒修改

@Test    public void updatedept(){        Session session = HibernateUtil.getSession();        Transaction tx=session.beginTransaction();        Dept dept=new Dept();        dept.setDeptno(2);        dept.setDeptname("小买部");        Emp emp=new Emp();        emp.setEmpno(1);        emp.setEmpname("小贱贱");        dept.getEmps().add(emp);        session.saveOrUpdate(dept);        tx.commit();    }

结果:

5.开发案例五

需求:一对多双向关联(两种方法双向遍历)

分析:在配置前提的情况下分别使用HQL语句和 session.get方法

测试类:

@Test    public void onetomoneydouble(){        //检索部门的同时检索出员工        String hql="from Dept";        Session session = HibernateUtil.getSession();        Query query = session.createQuery(hql);        List
list = query.list(); for (Dept item:list) { System.out.println(item.getDeptname()); for (Emp it:item.getEmps()) { System.out.println(it.getEmpname()); } } //检索出员工的同时检索出部门 Emp emp = session.get(Emp.class, 1); System.out.println(emp.getDept().getDeptname()+"HH"); }

结果:

INFO: HHH000397: Using ASTQueryTranslatorFactoryHibernate:     /* from    Dept */ select        dept0_.deptno as deptno1_0_,        dept0_.deptname as deptname2_0_     from        y2166.Dept dept0_测试部2Hibernate:     select        emps0_.deptno as deptno3_1_0_,        emps0_.empno as empno1_1_0_,        emps0_.empno as empno1_1_1_,        emps0_.empname as empname2_1_1_,        emps0_.deptno as deptno3_1_1_     from        y2166.Emp emps0_     where        emps0_.deptno=?     order by        emps0_.empno desc测试部1Hibernate:     select        emps0_.deptno as deptno3_1_0_,        emps0_.empno as empno1_1_0_,        emps0_.empno as empno1_1_1_,        emps0_.empname as empname2_1_1_,        emps0_.deptno as deptno3_1_1_     from        y2166.Emp emps0_     where        emps0_.deptno=?     order by        emps0_.empno desc小军1开发部Hibernate:     select        emps0_.deptno as deptno3_1_0_,        emps0_.empno as empno1_1_0_,        emps0_.empno as empno1_1_1_,        emps0_.empname as empname2_1_1_,        emps0_.deptno as deptno3_1_1_     from        y2166.Emp emps0_     where        emps0_.deptno=?     order by        emps0_.empno desc小明小买部1Hibernate:     select        emps0_.deptno as deptno3_1_0_,        emps0_.empno as empno1_1_0_,        emps0_.empno as empno1_1_1_,        emps0_.empname as empname2_1_1_,        emps0_.deptno as deptno3_1_1_     from        y2166.Emp emps0_     where        emps0_.deptno=?     order by        emps0_.empno desc测试部Hibernate:     select        emps0_.deptno as deptno3_1_0_,        emps0_.empno as empno1_1_0_,        emps0_.empno as empno1_1_1_,        emps0_.empname as empname2_1_1_,        emps0_.deptno as deptno3_1_1_     from        y2166.Emp emps0_     where        emps0_.deptno=?     order by        emps0_.empno desc小军开发部HH

6.属性介绍:

cascade属性  问题:如何实现添加部门的同时自动添加员工?  解析:可以使用cascade(级联)方式Cascade取值:   None,save-update,delete和all   none:当Session操纵当前对象时,忽略其他关联的对象。它是cascade属性的默认值.   Save-update:当通过Session的save()、update()及saveOrUpdate()方法来保存或更新当前对象时,级联保存所有关联的新建的瞬时状态的对象,并且级联更新所有关联的游离状态的对象。 Delete:   当通过Session的delete()方法删除当前对象时,会级联删除所有关联的对象。   当通过Session的delete()方法删除当前对象时,会级联删除所有关联的对象。 All:    包含save-update,delete的行为。   注意点:级联也就是说当我们保存持久化对象A的时候自动帮我们保存持久化对象B。

2017年12月28日15点55分测试

转载于:https://www.cnblogs.com/lcycn/p/8135756.html

你可能感兴趣的文章
30分钟掌握ES6/ES2015核心内容(下)
查看>>
30分钟掌握ES6/ES2015核心内容(上)
查看>>
JavaScript、ES5和ES6的介绍和区别
查看>>
HTML响应式布局实现详解
查看>>
关于vue里页面的缓存
查看>>
vue中使用keepAlive组件缓存遇到的坑
查看>>
vue实例以及生命周期
查看>>
vue计算属性详解
查看>>
vue2.0中watch总结:普通监听和深度监听
查看>>
Vue中computed(计算属性)、methods、watch的区别
查看>>
Vue2实践computed监听Vuex中state对象中的对象属性时发生的一些有趣经历
查看>>
vue 使用axios 出现跨域请求的两种解决方法
查看>>
Vuex的基本原理与使用
查看>>
Vue使用Axios实现http请求以及解决跨域问题
查看>>
HTML5的常用的标签
查看>>
HTML的基本概念
查看>>
Mac下 nodejs 及 electron 安装
查看>>
批量压缩文件夹
查看>>
linux 常用安全设置整理
查看>>
I4-6 Sports and Extreme Sports Teacher:Lamb
查看>>