hibernate级联
很多同学在进行编程学习时缺乏系统学习的资料。本页面基于hibernate级联内容,从基础理论到综合实战,通过实用的知识类文章,标准的编程教程,丰富的视频课程,为您在hibernate级联相关知识领域提供全面立体的资料补充。同时还包含 h6、hack、hadoop 的知识内容,欢迎查阅!
hibernate级联相关知识
-
Java面试题:Hibernate的二级缓存与Hibernate多表查询我们来看两个有关Java框架之Hibernate的面试题,这是关于Hibernate的常考知识点。1、请介绍一下Hibernate的二级缓存解题按照以下思路来回答:(1)首先说清楚什么是缓存;(2)再说有了hibernate的Session就是一级缓存,即有了一级缓存,为什么还要有二级缓存;(3)最后再说如何配置Hibernate的二级缓存。缓存就是把以前从数据库中查询出来和使用过的对象保存在内存中(一个数据结构中),这个数据结构通常是或类似Hashmap,当以后要使用某个对象时,先查询缓存中是否有这个对象,如果有则使用缓存中的对象,如果没有则去查询数据库,并将查询出来的对象保存在缓存中,以便下次使用。下面是缓存的伪代码:引出hibernate的第二级缓存,用下面的伪代码分析了Cache的实现原理。Dao{hashmap map =new map();User getUser(integer id){User user = map.get(id)if(user ==null){user = session.
-
Java面试题:Hibernate的二级缓存与Hibernate多表查询我们来看两个有关Java框架之Hibernate的面试题,这是关于Hibernate的常考知识点。1、请介绍一下Hibernate的二级缓存解题按照以下思路来回答:(1)首先说清楚什么是缓存;(2)再说有了hibernate的Session就是一级缓存,即有了一级缓存,为什么还要有二级缓存;(3)最后再说如何配置Hibernate的二级缓存。缓存就是把以前从数据库中查询出来和使用过的对象保存在内存中(一个数据结构中),这个数据结构通常是或类似Hashmap,当以后要使用某个对象时,先查询缓存中是否有这个对象,如果有则使用缓存中的对象,如果没有则去查询数据库,并将查询出来的对象保存在缓存中,以便下次使用。下面是缓存的伪代码:引出hibernate的第二级缓存,用下面的伪代码分析了Cache的实现原理。Dao{hashmap map =new map();User getUser(integer id){User user = map.get(id)if(user ==null){user = session.
-
Hibernate一级缓存测试分析Hibernate 一级缓存测试分析Hibernate的一级缓存就是指Session缓存,此Session非http的session会话技术,可以理解为JDBC的Connection,连接会话,Session缓存就是一块内存空间,用来存放相互管理的java对象,在使用Hibernate查询对象的时候,首先使用对象的OID(Object ID)在Hibernate 的一级缓存空间进行查找,如果通过OID匹配到了对象,就直接从一级缓存中取出使用,如果没有找到匹配该OID值的对象,这才会进行查询数据库。当从数据库中查询数据的时候,该数据就会被放入到Session缓存中,目的就是为了减少数据库的访问次数,从而提高性能。Hibernate缓存特点当应用程序调用Session接口的 save(), update(), saveOrUpdate() 时候,如果缓存中没 有相应的对象,Hb就会自动的把查询信息加入到缓存。当应用程序调用Session接口的 load(), get(), list() 等查询方法的时候,会进行
-
myeclipse试用小记----Hibernate多对一双向关联(2)myeclipse试用小记----Hibernate多对一双向关联(2) 在上篇文章“myeclipse试用小记----Hibernate多对一单向关联(1)”中,讲到了“Hibernate多对一单向关联”,现在我打算把这个做成双向的,也就是多对一双向关联,看看myeclipse是如何实现的。 环境、数据库还和上篇文章的一样。只是表中的数据清空了。 注意:对于有外键的表,清空数据有两种方法:第一是先drop掉外键约束后,进行清除。第二种是先清除从表数据(orders),然后清除主表的数据(customers),具体我及不说了,有空我在写写数据库外键约束的方面的文章,这点也很重要的。 步骤1、清除orders、customers两表数据。2、用myeclipse新建web工程sx_d2y,加入hibernate支持。3、同时选中orders、customers生成实体Bean和mapping文件,并对mapping做小的改动。4、写两个测试类,分别保存Orders对象和
hibernate级联相关课程
hibernate级联相关教程
- 2.5 级联操作 Hibernate 提供的级联操作带来了很多方便。但是,特别是在双向关联映射的情况下,不要把两边的级联操作全部打开,否则会把不该删除的数据删除掉。测试数据被级联删除倒无所谓,真实数据被删除了,可能就欲哭无门。
- 4. 一对多关联映射中的级联操作 什么是级联操作?关系型数据库中由主外键维系的两张表,具有主从关系。如学生表和班级表,班级班是主表,学生表是从表。类似于删除某一个班级的信息,则需要先删除所在班的学生信息,再删除班级信息,这个操作就是级联操作。所谓级联操作,指操作一张表时,是否会牵连到与之有关联的其它表。现在,咱们是使用 Hibernate 进行数据操作,不可能还要劳驾自己亲力亲为吧。只需要做些简单配置,就可以让 Hibernate 自动做级联操作。进入班级类,修改代码如下:@OneToMany(targetEntity=Student.class,mappedBy="classRoom",cascade=CascadeType.REMOVE) public Set<Student> getStudents() { return students; }很简单,只需要使用 @OneToMany 的 cascade 属性,就能让 Hibernate 明白如何做级联操作。默认情况下,没有级联效应。cascade 是一个枚举类型:public enum CascadeType { ALL, PERSIST, MERGE, REMOVE, REFRESH, DETACH}ALL: 级联所有操作;PERSIST: 级联新增;MERGE: 级联更新或者新增;REMOVE: 级联删除;REFRESH: 级联刷新;DETACH: 级联分离。测试删除班级实例:HibernateTemplate<ClassRoom> hibernateTemplate = new HibernateTemplate<ClassRoom>(); hibernateTemplate.template(new Notify<ClassRoom>() { @Override public ClassRoom action(Session session) { ClassRoom classRoom=(ClassRoom)session.get(ClassRoom.class, new Integer(1)); session.delete(classRoom); return null; } });如果不添加 cascade 相关说明,因为有学生引用班级信息,班级信息是不能被删除的。添加后再测试,查看表中内容:班级以及班级所在学生信息全部删除!删除班级时能级联删除学生,反过来,删除学生能删除班级吗?想法很好,实践是检验真理的唯一手段,学生类中修改成如下代码:@ManyToOne(targetEntity=ClassRoom.class,cascade=CascadeType.REMOVE) @JoinColumn(name="classRoomId") public ClassRoom getClassRoom() { return classRoom; }测试实例:HibernateTemplate<Student> hibernateTemplate = new HibernateTemplate<Student>(); hibernateTemplate.template(new Notify<Student>() { @Override public Student action(Session session) { Student stu=(Student)session.get(Student.class, new Integer(2)); session.delete(stu); return stu; } });结果很残酷!学生被删除了,班级也被删除了!级联级联,只要设置了级联,不管删除学生还是班级,只要在对应表中有引用关系的数据就会被删除。现在,学生类、班级类中的级联删除都打开了。如果对下面情形的数据(编号 1、2 的学生的班级编号都为 1)进行删除操作,则会发生什么事情?数据库中的数据如下:测试删除编号为 1 的学生:HibernateTemplate<Student> hibernateTemplate = new HibernateTemplate<Student>(); hibernateTemplate.template(new Notify<Student>() { @Override public Student action(Session session) { Student stu=(Student)session.get(Student.class, new Integer(1)); session.delete(stu); return stu; } });进入 MySql,查看一下:天呀!这是级联还是株连呀,太让人后怕,数据都没有了。删除学生时,会级联删除和学生有关的班级,班级删除时,又会查看学生表中是否还存在与班级有关联的学生,有,则一刀下去,连根拔起。Hibernate 有点刹不住车,产生了级联连锁反应。针对上面的测试,如果班级表的级联关闭,执行测试代码,请问结果又会怎样?本节课程,讲解了级联删除,级联添加的内容留到下节课继续展开。
- 3. 级联删除 前面讲解双向一对多的时候,也提到了级联删除。最大的印象就是,如果双方都打开了级联删除,删除时就如同推倒了多米诺骨牌的第一张牌,整个数据链都会删除。多对多关联比一对多关联多了一张中间表,在进行级联删除的时候,到底会发生什么事情?在此也有必要拿出来说一说。为了不让事情的发展如山崩一样不可控制,先打开学生类的级联操作功能:private Set<Course> courses=new HashSet<Course>(); @ManyToMany(targetEntity = Course.class,cascade=CascadeType.ALL) @JoinTable(name = "score", joinColumns = @JoinColumn(name = "stuId", referencedColumnName = "stuId"), inverseJoinColumns = @JoinColumn(name = "courseId", referencedColumnName = "courseId")) public Set<Course> getCourses() { return courses; }这里使用 CascadeType.ALL。来一段测试实例,删除刚才添加的 HibernateTemplate 同学。他会说我好悲惨,才进来没有多久。HibernateTemplate<Student> hibernateTemplate = new HibernateTemplate<Student>(); hibernateTemplate.template(new Notify<Student>() { @Override public Student action(Session session) { // 查询学生 Student student =(Student)session.get(Student.class, new Integer(23)); session.delete(student); return null; } });无惊无喜,一切按照预先的设想进行。删除学生时,中间表中与此学生有关联的信息,也就是说此学生选修的课程信息也自动被删除了。但是,会有一个想法,如果删除课程,则中间表中记录的与此课程有关的信息是否会自动删除呢?OK!开始行动之前,可别忘记在课程类中打开级联操作选项:嘿嘿!现在两边的级联操作功能都已经打开。private Set<Student> students=new HashSet<Student>(); @ManyToMany(targetEntity = Student.class, mappedBy = "courses",cascade=CascadeType.ALL) public Set<Student> getStudents() { return students; }打开后,执行删除 C 课程的实例,谁让 C 不好学了。HibernateTemplate<Course> hibernateTemplate = new HibernateTemplate<Course>(); hibernateTemplate.template(new Notify<Course>() { @Override public Course action(Session session) { // 查询学生 Course course =(Course)session.get(Course.class, new Integer(2)); session.delete(course); return null; } });这只是一个很简单的代码,但是却发生如雪崩一样的事件。到底发生了什么事情?大家进入 MySql 看看就知道了。3张表中空空如也,所有数据都没有了。就如同前面讲解一对多的级联删除一样。同样适用于多对多关联映射之中。因两边都已经打开了级联,删除操作如同无法控制的坏情绪,删除课程时,以中间表为连接,反复来往于三张表,把相关信息全部删除。所以,使用级联时一定要小心,否则,小心脏真的有点受不了。
- 3. 双向一对多关联映射 需求:查询班级时,想知道班上有多少名学生,又应该如何映射?进入班级类,添加如下属性:private Set<Student> students;使用集合属性 students,描述了一个班有多名学生。为什么使用 Set 集合?因为一个班级内不可能出现两个完全相同的学生对象。这还仅仅只是 OOP 层面上的关系,还需要告诉 Hibernate 应该如何填充数据。添加下面代码:private Set<Student> students;@OneToMany(targetEntity=Student.class,mappedBy="classRoom")public Set<Student> getStudents() { return students;}@OneToMany:很直白的说明了一个班级会有多名学生,指引 Hibernate 在填充数据时,要找到所有学生,别遗漏了;属性 mappedBy=“classRoom”: 告诉 Hibernate,班级和学生之间的关系在学生类中已经说的够明白了,应该不需要再废话了吧。OK!把前面的测试实例改为查询班级信息:HibernateTemplate<ClassRoom> hibernateTemplate = new HibernateTemplate<ClassRoom>(); hibernateTemplate.template(new Notify<ClassRoom>() { @Override public ClassRoom action(Session session) { ClassRoom classRoom=(ClassRoom)session.get(ClassRoom.class, new Integer(1)); System.out.println("班级名称:"+classRoom.getClassRoomName());System.out.println("------我是分隔线------------------------"); System.out.println("班级学生人数:"+classRoom.getStudents().size()); return classRoom; } });查看控制台输出结果:Hibernate: select classroom0_.classRoomId as classRoo1_0_0_, classroom0_.classRoomDesc as classRoo2_0_0_, classroom0_.classRoomName as classRoo3_0_0_ from ClassRoom classroom0_ where classroom0_.classRoomId=?班级名称:c1911------我是分隔线------------------------Hibernate: select students0_.classRoomId as classRoo6_0_1_, students0_.stuId as stuId1_1_1_, students0_.stuId as stuId1_1_0_, students0_.classRoomId as classRoo6_1_0_, students0_.stuName as stuName2_1_0_, students0_.stuPassword as stuPassw3_1_0_, students0_.stuPic as stuPic4_1_0_, students0_.stuSex as stuSex5_1_0_ from Student students0_ where students0_.classRoomId=?班级学生人数:2会发现一个很有意思的地方。Hibernate 查询班级时,构建了两条 SQL。先查询班级,当需要学生信息时,才构建查询学生的 SQL。大家应该也猜出来了,当从学生表查询班级表时,Hibernate 采用的是立即策略。当查询从班级表查询到学生表时,Hibernate 采用的是延迟加载策略。采用延迟加载都只有一个目的,需要时加载,提高响应速度。现在,学生类和班级类的映射配置信息,能让 Hibernate 自动从学生表查询到班级表,也能从班级表查询到学生表。这种 2 个实体类中的映射关系就称为双向一对多关联映射。无论是 @ManyToOne 还是 @OneToMany 注解都有 fetch 属性,可以设置的值有 2 个选择:FetchType.EAGERFetchType.LAZY。所以,在双向一对多关联映射可以选择是否启用延迟加载,这和一对一关联映射中是一样的,就不在此重复复述。是否采用延迟加载,由项目逻辑决定。
- 3. 对象级联 OOP 代码中经常会出现类似于 A 对象引用 B 对象,B 对象引用 C 对象的现象。 类似于现实生活中的小王有一辆汽车,汽车有一把钥匙……如果每一个用户都有一辆汽车,用 OOP 描述,意味着 User 类中有一个对 Car 的引用类型属性。public class User { private String userName; private String userPassword; private Car car; //……}假设 Car 类结构如下:public class Car {private String carType;private String carColor;//……}在注册时,除了要输入用户信息之外,还需要指定用户所拥有的汽车类型、颜色。那么,控制器是否能自动绑定用户以及汽车数据?Tips: 为什么注册时要输入汽车信息,不要纠结,只是一个用来说明问题的例子。答案是肯定的。只需要在表单页面中添加如下代码,控制器端不做任何修改。如此,除了能接收用户数据外,还能接收汽车的信息。<form action="user/register" method="post"> 用户名:<input type="text" value="" name="userName" /> <br /> 密码:<input type="password" value="" name="userPassword" /> <br /> 汽车类型:<input type="text" value="" name="car.carType" /> <br /> 汽车颜色:<input type="text" value="" name="car.carColor" /> <br /> <input type="submit" value="注册" name="btnRegister" /> <input type="reset" value="重置" name="btnReset" /></form>也就是说,Spring MVC 支持对象级联自动数据绑定。Spring MVC 支持多层级的对象级联。
- 启动二级缓存 在 Hibernate 的主配置文件中启动并指定二级缓存的实现者;<property name="cache.use_structured_entries">true</property><property name="cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</property>添加 EhCache 相关的 JAR 包。这些 JAR 包都可以在下载的 Hibernate 框架包的 lib 文件夹中找到;ehcache-core-2.4.3.jar;hibernate-ehcache-4.2.0.Final.jar。在项目的 src 中添加 EhCache 缓存框架的配置文件 ehcache.xml;这个配置文件可以在下载的 Hibernate 框架包中的 project 目录下的 etc 中找到。此配置文件中的内容用来配置缓存管理相关信息。<ehcache> <diskStore path="java.io.tmpdir"/> <defaultCache maxElementsInMemory="10000" eternal="false" timeToIdleSeconds="120" timeToLiveSeconds="120" overflowToDisk="true" /> </ehcache> 配置说明:maxElementsInMemory: 缓存最大数目;eternal : 缓存是否持久;overflowToDisk : 是否保存到磁盘,当系统当机时;timeToIdleSeconds : 当缓存闲置 n 秒后销毁;timeToLiveSeconds : 当缓存存活 n 秒后销毁。在需要缓存的实体类上添加 @cache 注解 @Cache(usage=CacheConcurrencyStrategy.TRANSACTIONAL,include="all",region="student") 只有被 @Cache 注解的实体才会被存储进二级缓存中,此注解有一个 usage 属性,用来配置缓存的策略,是一个枚举类型,有如下几种选择:CacheConcurrencyStrategy.NONE;CacheConcurrencyStrategy.NONSTRICT_READ_WRITE: 非严格读写缓存;CacheConcurrencyStrategy.READ_ONLY: 只读缓存;CacheConcurrencyStrategy.READ_WRITE: 读写缓存;CacheConcurrencyStrategy.TRANSACTIONAL: 事务缓存。Region 指定二级缓存中的区域名,默认为类或者集合的名字。include 有几个选项,non-lazy 当属性延迟抓取打开时,标记为 lazy=“true” 的实体的属性可能无法被缓存。做完上面的事情后,再执行前面的两个 Session 对象查询同一个学生的代码,再查看控制台上的信息:Hibernate: select student0_.stuId as stuId1_1_0_, student0_.classRoomId as classRoo5_1_0_, student0_.stuName as stuName2_1_0_, student0_.stuPassword as stuPassw3_1_0_, student0_.stuSex as stuSex4_1_0_ from Student student0_ where student0_.stuId=?学生姓名:Hibernate--------------第二次查询------------------学生姓名:Hibernate第一次查询时,需要发送 SQL 请求,第二查询时,不再发送 SQL 请求,因为查询过的信息已经被存储在了二级缓存中,Hibernate 会直接从缓存查询。二级缓存并不支持缓存 Blob 类型的数据。
hibernate级联相关搜索
-
h1
h6
hack
hadoop
halt
hana
handler
hanging
hash
hashtable
haskell
hatch
hbase
hbuilder
hdfs
head
header
header php
headers
headerstyle