Hibernate 笔记三
来源:互联网 发布:安卓连接mysql软件 编辑:程序博客网 时间:2024/05/22 06:11
一对多知识点
一对多关系Set排序
Set集合 TreeSet 二叉树 自己定义排序规则HashSet 默认排序方式 hashcode进行排序指定 order-by="price desc"
一对多删除表数据
一对多关系List讲解
<!--orderList是Customer中的成员属性 --> <list name="orderList" table="t_order"> <!-- cid是外键对应的列 --> <key column="cid"></key> <!-- list_index指集合条目的索引值 --> <index column="list_index" type="string"></index> <!--指定一对多的全路径 --> <one-to-many class="com.example.hibernate.domin2.Order" /> </list>
一对多关系中的属性配置
cascade:级联:
测试
org.hibernate.TransientObjectException:object references an unsaved transient instance 对象引用了一个未保存的示例对象
配置信息
all : 所有情况下均进行关联操作。 none:所有情况下均不进行关联操作。这是默认值。 save-update:在执行save/update/saveOrUpdate时进行关联操作。 delete:在执行delete时进行关联操作。
总结:
如果操作‘多方’,就在多方的xml中配置,如果操作 ‘一方’,就在‘一方’配置xml最好两方都配置 all
inverse
在hibernate中通过对 inverse 属性的值决定是由双向关联的哪一方来维护表和表之间的关系. inverse=false 的为主动方,inverse=true 的为被动方结论:在映射一对多的双向关联关系时,应该在one方把inverse属性设为true,这可以提高性能。
多对多
一个学生学习多个课程一个课程被多个学生学习<!-- 多对多 指定第三张表名--> <set name="curseSet" table="t_student_curse" cascade="save-update" inverse="true"> <!-- 指定外键列名 --> <key column="sid"></key> <!-- 指定自己的在第三张表中的id --> <many-to-many column="cid" class="com.example.hibernate.domin2.Curse"> </many-to-many> </set>
一对一
主键一对一
<!-- 在主键上声明外键策略 并指定关联的外键的名称 --><id name="id" type="integer"> <!--数据库中t_customer id列 --> <column name="id"></column> <generator class="foreign"> <param name="property">idCard</param> </generator></id><!-- 指定一对一,配置约束 --><one-to-one name="idCard" constrained="true"></one-to-one>
外键一对一
多端唯一,通过一个属性 unique=ture。<!--使用多对一的属性,同时指定unique --><many-to-one name="idCard" column="cardId" unique="true"></many-to-one>
注解配置
对象状态
持久化状态
save方法能够将临时状态转化程持久化状态
使用get或者load方法获取的对象肯定是持久化状态
位于session缓存中
oid 不为空位于session缓存中当执行查询时,持久化对象和数据库中的相关记录session在清理缓存时,会根据持久化对象的属性变化,来同步更新数据库中的内容在同一个session实例的缓存中,数据库表中的每条记录只对应唯一的持久化对象。
临时状态
new 对象时为临时状态
在使用代理主键的情况下,oid通常为null,不处于session的缓存中在数据库中没有对应的记录
删除状态
当调用session的delete方法时,对象状态就变成了删除状态
OID 不为 null 从一个 Session实例的缓存中删除 Session 已经计划将其从数据库删除, Session 在清理缓存时, 会执行 SQL delete 语句, 删除数据库中的对应记录 一般情况下, 应用程序不该再使用被删除的对象
游离状态
当调用session.close();session的缓存被清空,缓存中所有对象都会变成游离对象,生命周期结束
session的evict()方法能够从缓存中删除一个持久化对象,从而时该持久化对象变成游离对象,当session的缓存中保存了大量的持久化对象,会消耗很多内存空间,为了提高性能,调用evict方法,从缓存中删除一些对象
oid不为null不处于session缓存中一般有持久化对象转化成游离对象
代码示例
@Testpublic void add() { // 获取session Session session = sf.openSession(); Transaction transaction = session.beginTransaction(); // 创建customer对象,并设置内容 // 1 刚刚创建对象---临时状态--- Customer customer = new Customer(); customer.setName("赵六"); // 存储到session中 // 2将对象保存到session中----持久化状态----, session.save(customer); // 3 删除 对象 删除状态 session.delete(customer); // 提交事务 transaction.commit(); session.close(); //4 当session关闭之后,对象变成游离状态 System.out.print(customer.getId()+"-----");}
对象状态之间转换
持久化对象和游离状态转换
//持久化状态和游离状态之间转换(了解)Session s = sf.openSession();Transaction tr = s.beginTransaction();Customer c1 = (Customer)s.get(Customer.class, 1);//产生select语句s.evict(c1);//将持久对象转换成游离对象s.update(c1);//将游离对象转换成持久对象Customer c2 = (Customer)s.get(Customer.class, 1); tr.commit();//先执行s.flush,然后再提交事务s.close();
Session操作数据库的方法总结
save()方法:
将临时对象转换持久对象
update()方法:将游离对象转换持久对象
注意:当 update() 方法关联一个游离对象时, 如果在 Session 的缓存中已经存在相同 OID 的持久化对象, 会抛出异常
evict()方法:
将持久对象转换成游离对象
saveOrUpdate()方法:
存在save方法和update方法的特征
get() load()
都可以根据给定的 OID 从数据库中加载一个持久化对象区别:1:当数据库中不存在与 OID 对应的记录时, load() 方法抛出 ObjectNotFoundException 异常, 而 get() 方法返回 null2:两者采用不同的延迟检索策略
Session缓存管理
lazy 懒加载介绍
- 概念介绍
立即检索: 立即加载检索方法指定的对象,对应配置文件中lazy=false
延迟检索: 延迟加载检索方法指定的对象,对应配置文件中lazy=true
测试立即检索和延迟检索的代码,注意只有load()方法进行查询的时候,会产生延迟检索。
模型类设置为final修饰将无法生成代理对象
get()方法:立即检索,只要调用get方法查询数据库,马上执行sql语句,查询对应的结果 load()方法:会产生延迟检索,调用load()方法的时候,不会马上查询数据库,而是产生一个代理对象, 代理对象中只初始化对象的OID,不会初始化其他的属性值 而是调用其他属性值的时候,例如c.getName(),此时才会组织sql语句,查询数据库,返回对应的结果 load()方法如何立即检索呢? 只需要更改 class name="xxx" table="xxx" lazy="false"> 使用load方法可以对性能进行优化,如果只想获取oid的值(比如删除),此时会采用load()方法比get()更适合,因为不需要查询数据库,就可以获取oid
load方式访问游离状态的对象
org.hibernate.LazyInitializationException: could not initialize proxy - no SessionCustomer c = (Customer)s.load(Customer.class, 1); if(!Hibernate.isInitialized(c)){ System.out.println(c.getClass()); System.out.println(c.getId()); System.out.println(c.getName()); 调用Hibernate.initialize(),将代理对象放置到方法中,此时就会查询数据库,返回对应的真实对象 Hibernate.initialize(c); System.out.println(c.getName()); }
检索策略
立即检索
优点:不管对象处于持久化状态还是游离状态,都方便使用缺点:select 会直接将所有字段都查询出来 关联查询时,可能会查出没必要查询出的对象,浪费内存优先使用场景:应用程序需要立即访问到对象
延迟检索
优点:可以自行决定查询哪些对象,降低内存消耗缺点:应用程序使用游离状态的对象时,必须保证其已经被初始化优先使用场景:应用程序不需要立即访问到对象的属性,比如只想获取到对象的oid,做删除操作。 一对多或者多对多关联时
管理Session(Session与本地线程绑定):
Hibernate 3 自身提供了三种管理 Session 对象的方法 Session 对象的生命周期与本地线程绑定 thread Session 对象的生命周期与 JTA 事务绑定 jta* Hibernate 委托程序管理 Session 对象的生命周期 managed
在hibernate的配置文件中,设置session与本地线程绑定的代码
<property name="hibernate.current_session_context_class">thread</property>测试Session与本地线程绑定 public void testSessionThread(){// Session s1 = sf.openSession();// Session s2 = sf.openSession(); Session s1 = sf.getCurrentSession(); Session s2 = sf.getCurrentSession(); System.out.println(s1==s2);//false:此时说明2个Session不是一个对象;true:2个Session是一个对象(与本地线程绑定)// s1.close(); // s2.close(); }这里:不再调用sessionFactory.openSession().而是调用sessionFactory. getCurrentSession().获取session对象.从当前的线程提取session,* 当前线程如果存在session对象,取出直接使用* 当前线程如果不存在session对象,获取一个新的session对象和当前的线程绑定
阅读全文
0 0
- hibernate学习笔记(三)
- hibernate学习笔记(三)
- hibernate学习笔记三
- hibernate学习笔记三
- Hibernate学习笔记三
- hibernate学习笔记(三)
- Hibernate学习笔记三
- Hibernate 笔记大全三
- Hibernate学习笔记(三)
- Hibernate 笔记三
- hibernate学习笔记三
- hibernate笔记(三)------many2many
- Hibernate学习笔记(三)
- Hibernate复习笔记(三)
- Hibernate学习笔记(三)
- hibernate学习笔记(三)
- Hibernate 学习代码/笔记 (三)
- Hibernate学习笔记(三)
- java学习之路(7)- 方法与递归
- win10-ubuntu16 双系统引导盘错误记录
- IntelliJ IDEA详细配置和使用教程(适用于Java开发人员)
- Java中的标识符命名规范
- 对并发编程的同步/异步,阻塞/非阻塞的理解
- Hibernate 笔记三
- jdbcTemple批量操作
- 对OSI网络模型的理解
- 信号(二)
- 【CSS模块化】(1) webpack之Local Scope
- 收集苹果(dp)
- 关于第三次创业的想法
- Hibernate 笔记四
- LintCode python 小白4-Big Integer Addition