Hibernate3 第三天
第一天:三个准备、七个步骤
第二天:一级缓存、快照、多对多和一对多的配置
学习内容:
-
Hibernate的查询详解(各种检索(fetch)对象的方式)
1)条件查询分类(对象导航检索)。
2)HQLSQLQBC的各种查询(基础查询、条件查询、排序、分页、投影查询、统计分组、命名查询、离线查询等)。
-
Hibernate的抓取策略(查询优化)
1)延迟抓取和立即抓取策略
类级别的抓取策略
关联集合级别的抓取策略
2)批量抓取策略
学习目标:
-
掌握各种查询
-
掌握常用的抓取策略:懒加载、迫切连接、批量抓取
-
多表映射回顾和准备查询数据
-
多表映射回顾
-
创建Hibernate项目:
构建Hibernate环境:导入jar包、hibernate.cfg.xml、log4j.properties、util工具类。
创建包:cn.itcast.a_onetomany,配置一对多的实体类和hbm映射文件的编写:
实体类(Customer):
package cn.itcast.a_onetomany; import java.util.HashSet; import java.util.Set; public class Customer {
private Integer id; private String name; private String city;
//集合 //set:无需不重复 //也可以用list:有序重复 //配置hbm.xml的时候,如果类中用的是list集合的话,那边hbm中也可以使用<bag>标签配置集合 //<bag>:有序不重复,但是效率低下 private Set<Order> orders = new HashSet<Order>(); public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getCity() { return city; } public void setCity(String city) { this.city = city; } public Set<Order> getOrders() { return orders; } public void setOrders(Set<Order> orders) { this.orders = orders; } @Override public String toString() { return "Customer [id=" + id + ", name=" + name + ", city=" + city + "]"; } } |
实体类(Order):
package cn.itcast.a_onetomany; public class Order { private Integer id; private String name; private Double price;
private Customer customer ; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Double getPrice() { return price; } public void setPrice(Double price) { this.price = price; } public Customer getCustomer() { return customer; } public void setCustomer(Customer customer) { this.customer = customer; } @Override public String toString() { return "Order [id=" + id + ", name=" + name + ", price=" + price + "]"; } } |
hbm映射文件:
Customer.hbm.xml
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <hibernate-mapping> <!-- 配置java类与表之间的对应关系 --> <!-- name:类名:类对应的完整的包路径 table:表名 --> <class name="cn.itcast.a_onetomany.Customer" table="t_customer"> <!-- 主键 --> <id name="id"> <generator class="native"></generator> </id> <property name="name"></property> <property name="city"></property>
<set name="orders"> <key column="cid"></key> <one-to-many class="cn.itcast.a_onetomany.Order"/> </set>
</class> </hibernate-mapping> |
Order.hbm.xml
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <hibernate-mapping> <!-- 配置java类与表之间的对应关系 --> <!-- name:类名:类对应的完整的包路径 table:表名 --> <class name="cn.itcast.a_onetomany.Order" table="t_order"> <id name="id"> <generator class="native"></generator> </id> <property name="name"></property> <property name="price"></property>
<many-to-one name="customer" class="cn.itcast.a_onetomany.Customer" column="cid"></many-to-one> </class> </hibernate-mapping> |
核心配置文件中引入HBM映射配置:
<!-- 在核心配置文件中 引用 mapping 映射文件 --> <mapping resource="cn/itcast/a_onetomany/Customer.hbm.xml"/> <mapping resource="cn/itcast/a_onetomany/Order.hbm.xml"/> |
建表测试是否配置成功:
@Test public void createTable(){ HibernateUtils.getSessionFactory(); } |
-
准备查询数据
批量插入3个客户和相应的订单(共30个)
@Test @Test public void prepareData() { Session session = HibernateUtils.openSession(); session.beginTransaction();
//一个客户对应多个订单,一个客户对应10个订单 Customer customer = new Customer(); customer.setName("jack"); customer.setCity("北京");
session.save(customer);
for(int i=1;i<=10;i++) { Order o = new Order(); o.setName(customer.getName()+"的订单"+i); o.setPrice(i*10d);
o.setCustomer(customer); session.save(o); }
session.getTransaction().commit(); session.close(); } |
【扩展】
问题:如果你在大批量的插入数据的时候,可能会报内存溢出的错误!
原因:当save操作的时候,会将瞬时态转换为持久态,对象都放在了session的一级缓存中,如果超大量的数据,会撑爆一级缓存,导致内存溢出。
解决方案:
// 批插入的对象立即写入数据库并释放内存
if(i%10000==0){ //刷出到数据库 session.flush(); //清空一级缓存,释放内存 session.clear(); } |
【提示:】