一、Hibernate的关联关系映射(多对多) 在数据库表中如何表达多对多关系: 使用中间表,分别引用两方的ID。 在对象中如何表达多对多关系: 两方都使用集合表达。即两个对象中互相持有对方的集合的引用。 在配置文件中如何表达一对多关系: <!-- 配置多对多关联关系 --> <set name="courses" table="t_stu_cour"> <key column="stu_id"/> <many-to-many class="Course" column="cour_id"/> </set>
小结:
<set name="本方引用的集合名称" table="中间表表名" >
<key column="本方中间表列名称" />
<many-to-many class="对方的完整类名" column="对方中间表列名称" />
</set>
<!-- 配置多对多关联关系 --> <set name="students" table="t_stu_cour"> <key column="cour_id"/> <many-to-many class="Student" column="stu_id"/> </set> 操作:
inverse:本方是否要放弃维护外键关系(默认值是false)
cascade:是否需要级联操作(有5个值)(没有默认值)
save-update 级联保存和级联修改
delete 级联删除
delete-orphan 孤儿删除
all save-update + delete
all-delete-orphan save-update + delete + delete-orphan
注意:配置级联删除时,要小心!当双方都配置级联删除时,任意删除一条记录,整个关系链数据都会被删除。 二、加载(抓取)策略(优化查询) 1、加载策略种类: 延迟加载:等到使用的时候才会加载数据。 立即加载:不管使用不使用,都会立刻将数据加载。 2、加载策略的应用: 类级别的加载策略。 关联级别的加载策略。 3、类级别加载策略: get/load get:立即查询数据库,将数据初始化。 load:hbm文件中,class元素的lazy属性决定该方法的类级别加载策略,默认值是true。 true:先返回一个代理对象,使用代理对象的属性时,才去查询数据库。 false:load方法一执行就会发送sql语句,与get一致,会立即加载数据。 4、关联级别加载策略: 在查询有关联关系的数据时,加载一方的数据是否需要将另一方立即查询出。 默认是:与我关联的数据,在使用时才会被加载。 注意:下面所用的例子是:客户(一)和订单(多) ------------------------------------------------------------------------------------------------------------------------------ 一对多(集合的检索策略):根据客户去找订单 <set lazy:是否对set数据使用懒加载 true (默认值)对集合使用赖加载 false 集合将会被立即加载 extra 极其懒惰,在使用集合时,若调用size方法查询数量,则Hibernate会发送count语句,只查询数量,不加载集合内的数据 fetch:决定加载集合使用的sql语句种类 select (默认值)普通select语句查询 join 使用 表连接语句 查询集合数据,即使用 多表查询语句 集合数据 subselect 使用子查询语句,在一次加载多个客户的订单数据的情况下才有效 fetch lazy 结果 ------------------------ select true 都是默认值,会在使用集合(订单)时才加载,使用普通select语句查询集合数据 select false 立刻使用select语句加载集合数据 select extra 会在使用集合(订单)时才加载,普通select语句,如果你使用集合只是为了获得集合的长度,则Hibernate只会发送count语句查询集合长度 join true 因为查询集合(订单)时使用表连接语句查询,所以会立刻加载集合数据(与lazy属性无关了,lazy属性失效) join false 因为查询集合(订单)时使用表连接语句查询,所以会立刻加载集合数据(与lazy属性无关了,lazy属性失效) join extra 因为查询集合(订单)时使用表连接语句查询,所以会立刻加载集合数据(与lazy属性无关了,lazy属性失效) subselect true 会在使用集合(订单)时才加载,使用子查询语句查询集合(订单)数据 subselect false 会在查询客户时,立即使用子查询语句加载客户的订单数据 subselect extra 会在使用集合(订单)时才加载,子查询语句,如果你使用集合只是为了获取集合的长度,则Hibernate只会发送count语句查询集合长度 ------------------------------------------------------------------------------------------------------------------------------ 多对一:根据订单去找客户 <many-to-one lazy false 加载订单时,会立即加载客户数据 proxy 看客户对象的类加载策略来决定 no-proxy 不做研究 fetch select (默认值)使用普通select语句加载客户数据 join 使用表连接加载数据 fetch lazy 结果 ------------------------ select false 加载订单时,会立即加载客户数据,使用普通select语句加载客户数据 select proxy 客户的类加载策略为:lazy="false" 时, 同上 lazy="true" 时, 加载订单时,先不加载客户数据,使用客户数据时才加载客户数据 join false 使用表连接查询订单以及对应客户信息,lazy属性无效 join proxy 使用表连接查询订单以及对应客户信息,lazy属性无效 5、批量加载 <set batch-size:n 决定一次加载几个对象(客户)的集合数据,Hibernate会发送select ... in ...条件语句,加载多个客户的订单 6、检索总结 如下表所示: 三、查询方式总结 Hibernate查询分类: 1、get/load 根据OID检索 2、对象导航图检索 c.getOrders(); 3、Sql语句 createSqlQuery 4、Hql语句 createQuery 5、Criteria查询 createCriteria 1.通过OID检索(查询) get(int); 立即、如果没有数据返回null。 load(Class, int); 延迟,如果没有数据抛异常。 2.导航对象图检索方式(关联查询) customer.getOrders(); 3.Sql: Structured Query Language 结构化查询语言,原始Sql语句查询 SQLQuery sqlQuery = session.createSQLQuery("sql语句"); // 查询的是:表,表字段(列) sqlQuery.list(); 查询所有 sqlQuery.uniqueResult(); 查询一个 4.HQL: Hibernate Query Language Hibernate查询语言 Query query = session.createQuery("hql语句"); // 查询的是:对象,对象属性 5.QBC: Query By Criteria 条件查询,纯面向对象查询语言 Criteria criteria = session.createCriteria(Class); 四、HQL 详解【掌握】 4.1、HQL介绍 4.2、HQL查询所有客户 4.3、HQL选择查询 4.4、HQL投影查询(部分) 4.5、HQL排序 4.6、HQL分页 4.7、HQL绑定参数 4.8、聚合函数和分组 4.9、HQL连接查询 4.10、HQL命名查询 五、QBC 详解【了解】 5.1、QBC查询 5.2、QBC简单查询 5.3、QBC分页查询 5.4、QBC排序查询 5.5、QBC条件查询 5.6、离线查询(了解) 六、连接池、事务、锁 相关常见设置 6.1、整合c3p0(连接池) (了解) 6.2、事务 数据库中的锁 悲观锁(数据库提供实现):默认认为别人一定会要修改我使用的数据,那我就可以为我读取的数据加锁。 读锁/共享锁 => 读锁可被其他线程所共享,如果是读取的话大家都可以用这把锁读到数据。 select * from t_Customer lock in share mode;(读锁、共享锁) 写锁/排他锁 => 写锁不能共享,只要有人为数据加入了写锁,其他人就不能为数据加任何锁。 select * from t_Customer for update; (写锁、排它锁) 乐观锁(需要自己实现,但Hibernate帮我们实现了,我们只需配置一下就可以使用了):