名称:Hibernate的配置与api操作、关联映射 说明:直接执行代码,自动建表
【package1】:com.csxiaoyao.crud hibernate的CRUD的api操作 【package2】:com.csxiaoyao.query 四种查询:主键查询、HQL(详解多种情况)、Criteria、本地SQL 【package3】:com.csxiaoyao.mapping 关联映射、inverse控制反转、cascade级联操作、一对一、组件、继承 【package4】:com.csxiaoyao.session session缓存的使用 【package5】:com.csxiaoyao.second_cache 二级缓存的使用 【package6】:com.csxiaoyao.compositeKey 复合主键映射 【package7】:com.csxiaoyao.utils 自动建表、创建Session的工厂及获取Session对象的抽取 【配置文件1】:hibernate.cfg.xml 主配置文件说明 【配置文件2】:Employee.hbm.xml 单列主键映射及普通字段类型说明 【配置文件3】:User.hbm.xml 多列主键映射配置 【配置文件4】:mapping下所有配置文件 关联映射
List getAll(int index, int count); 此外,在query.App_page中有详细的实现
|—- Configuration 配置管理类对象 ——– config.configure(); 加载主配置文件的方法(hibernate.cfg.xml),默认加载src/hibernate.cfg.xml ——– config.configure(“cn/config/hibernate.cfg.xml”); 加载指定路径下指定名称的主配置文件 ——– config.buildSessionFactory(); 创建session的工厂对象 |—- SessionFactory session的工厂(代表这个hibernate.cfg.xml配置文件) ——– sf.openSession(); 创建一个sesison对象 ——– sf.getCurrentSession(); 创建session或取出session对象 |—- Session session对象维护了一个连接(Connection), 代表与数据库连接的会话,Hibernate最重要的对象,只要使用hibernate与数据库操作,都用到这个对象 ——– session.beginTransaction(); 开启一个事务,hibernate要求所有的与数据库的操作必须有事务的环境,否则报错 |—- Transaction hibernate事务对象 【CRUD】 session.save(obj); 保存一个对象(EmployeeDaoImpl.save(obj)) session.update(obj); 更新一个对象(EmployeeDaoImpl.update(obj)) session.saveOrUpdate(obj); 保存或者更新(EmployeeDaoImpl.update(obj)) 没有设置主键,执行保存;有设置主键,执行更新操作;如果设置主键不存在报错 session.delete(id); 删除一个对象(EmployeeDaoImpl.delete(id)) 【主键查询】 session.get(Entity.class, id); 主键查询(EmployeeDaoImpl.findById(id)) session.load(Entity.class, id); 主键查询 (支持懒加载) 【HQL查询】 HQL、SQL查询区别: SQL: (结构化查询语句)查询的是表以及字段;不区分大小写 (EmployeeDaoImpl.getAll()、getAll(String)) HQL: hibernate query language 即hibernate提供的面向对象的查询语言,查询的是对象及对象属性;区分大小写 【Criteria查询】 完全面向对象的查询 【本地SQL查询】 复杂的查询,使用原生sql查询 (缺点: 不能跨数据库平台)
com.csxiaoyao.crud.HibernateTest.java
主配置文件中主要配置:数据库连接信息、其他参数、映射信息 常用配置查看源码:hibernate-distribution-3.6.0.Final\project\etc\hibernate.properties 【详细配置信息注释见代码】 自动建表说明:
#hibernate.hbm2ddl.auto create-drop 每次在创建sessionFactory时候执行创建表;当调用sesisonFactory的close方法的时候,删除表
#hibernate.hbm2ddl.auto create 每次都重新建表; 如果表已经存在就先删除再创建
#hibernate.hbm2ddl.auto update 如果表不存在就创建; 表存在就不创建;
#hibernate.hbm2ddl.auto validate (生成环境时候) 执行验证: 当映射文件的内容与数据库表结构不一样的时候就报错
sf = new Configuration()
.configure()
.addClass(User.class) //(测试) 会自动加载映射文件:User.hbm.xml
.buildSessionFactory();
一对多、多对一映射(one2many) 多对多映射(many2many) 一对一映射(one2one 多对一的特殊应用) 组件映射(component 多个bean合成一张表、基于主键/基于外键) 继承映射(extends 所有子类映射到一张表、每个类映射一张表、每个子类映射一张表)
(collection)用户与收货地址,一个用户对应多个地址
在一对多与多对一的关联关系中,保存数据最好的通过多的一方来维护关系,这样可以减少update语句的生成,从而提高hibernate的执行效率。 配置一对多与多对一:“双向关联” 只配置一对多:“单项一对多” 只配置多对一:“单项多对一” (配置了哪一方,哪一方才有维护关联关系的权限)
【Inverse控制反转属性】 Inverse属性,控制反转,用于维护关联关系,表示控制权是否转移(在一的一方起作用)
Inverse = false 不反转,当前方有控制权
Inverse = true 反转,当前方没有控制权
维护关联关系中,是否设置inverse属性: 1. 保存数据 如果设置控制反转,即inverse=true,然后通过部门方维护关联关系。在保存部门的时候,同时保存员工, 数据会保存,但关联关系不会维护,即外键字段为NULL 2. 获取数据 无影响 3. 解除关联关系
inverse=false,可以解除关联
inverse=true,当前方(部门)没有控制权,不能解除关联关系(不会生成update语句,也不会报错)
4. 删除数据
inverse=false,有控制权,可以删除。先清空外键引用,再删除数据。
inverse=true,没有控制权: 如果删除的记录有被外键引用,会报错,违反主外键引用约束。如果删除的记录没有被引用,可以直接删除。
【cascade级联操作属性】
none 不级联操作, 默认值
save-update 级联保存或更新
delete 级联删除
save-update,delete 级联保存、更新、删除
all 同上。级联保存、更新、删除
维护关联关系 设置inverse属性,在多对多种维护关联关系的影响 1. 保存数据
inverse=false,有控制权,可以维护关联关系,保存数据的时候会把对象关系插入中间表
inverse=true,没有控制权,不会往中间表插入数据
2. 获取数据 无影响 3. 解除关系
inverse=false,有控制权,解除关系就是删除中间表的数据
inverse=true,没有控制权,不能解除关系
4. 删除数据
inverse=false,有控制权,先删除中间表数据,再删除自身
inverse=true,没有控制权,如果删除的数据有被引用,会报错! 否则,才可以删除
1. 基于外键 mapping.one2one 多对一映射添加unique=”true”属性 2. 基于主键 mapping.one2one2
mapping.component
1. 所有子类映射到一张表 mapping.extends1 2. 每个类映射一张表 mapping.extends3 3. 每个子类映射一张表 mapping.extends2、mapping.extends4
Hibernate中缓存分:一级缓存、二级缓存
【概念】 1. Hibenate中一级缓存,也叫做session的缓存,可以在session范围内减少数据库的访问次数,只在session范围有效,Session关闭,一级缓存失效 2. 当调用session的save/saveOrUpdate/get/load/list/iterator方法的时候,都会把对象放入session的缓存中 3. Session的缓存由hibernate维护, 用户不能操作缓存内容。如果想操作缓存内容,必须通过hibernate提供的evit/clear方法操作
【特点】 只在(当前)session范围有效,作用时间短,效果不是特别明显;在短时间内多次操作数据库,效果比较明显 【api】
session.flush(); 让一级缓存与数据库同步
session.evict(obj); 清空一级缓存中指定的对象
session.clear(); 清空一级缓存中缓存的所有对象
【使用案例】 批量操作使用使用:
Session.flush(); // 先与数据库同步
Session.clear(); // 再清空一级缓存内容
Hibernate提供了基于应用程序级别的缓存, 可以跨多个session,即不同的session都可以访问缓存数据 【二级缓存使用步骤】 (1)开启二级缓存 (2)指定缓存框架 (3)指定类加入二级缓存 (4)测试二级缓存 【缓存策略】
<class-cache usage="read-only"/> 放入二级缓存的对象,只读;
<class-cache usage="nonstrict-read-write"/> 非严格的读写
<class-cache usage="read-write"/> 读写; 放入二级缓存的对象可以读、写;
<class-cache usage="transactional"/> (基于事务的策略)
get
: 及时加载,只要调用get方法立刻向数据库查询
load
: 默认使用懒加载,当用到数据的时候才向数据库查询
在真正使用数据的时候才向数据库发送查询的sql;调用集合的size()/isEmpty()方法,只是统计,不真正查询数据
【解决session关闭后使用懒加载数据报错】
// 方式1: 先使用一下数据
dept.getDeptName();
// 方式2:强迫代理对象初始化
Hibernate.initialize(dept);
// 方式3:关闭懒加载
设置lazy=false;
// 方式4: 在使用数据之后,再关闭session
Hibernate 自带一个连接池(只有一个连接),且支持C3P0连接池 【Hbm对C3P0连接池支持的核心类】
#hibernate.connection.provider_class org.hibernate.connection.C3P0ConnectionProvider
【配置连接池参数】
###########################
### C3P0 Connection Pool### 【Hbm对C3P0连接池支持】
###########################
#hibernate.c3p0.max_size 2 最大连接数
#hibernate.c3p0.min_size 2 最小连接数
#hibernate.c3p0.timeout 5000 超时时间
#hibernate.c3p0.max_statements 100 最大执行的命令的个数
#hibernate.c3p0.idle_test_period 3000 空闲测试时间
#hibernate.c3p0.acquire_increment 2 连接不够用的时候, 每次增加的连接数
#hibernate.c3p0.validate false