一、hibernate中实体规则
实体类创建的注意事项
1.持久化类提供无参数构造
2.成员变量私有,提供get、set方法访问,需提供属性(属性就是get、set方法)
3.持久化类中的属性,应尽量使用包装类型(可以表示null,在插如数据库中有作用)
4.持久化类需要提供oid(主键属性)与数据库中主键列对应
5.不需要final修饰class(原因:hibernate使用cglib代理生成代理对象,如果被final修饰将无法生成代理)
主键类型
1.自然主键(少见)
表的业务列中,有某业务列符合,必须有且不重复的特征时,该列可以作为主键使用
2.代理主键(常见)
表的业务列中,没有某业务列符合,必须有且不重复的特征时,创建一个没有业务意义的列做为主键
主键生成策略
1.代理主键
indentity:主键自增,有数据库来维护主键值,录入时不需要指定主键
sequence:Oracle中的主键生成策略
increment(了解):主键自增,由hibernate来维护,每次插入前会先查询表中的id的最大值,+1作为新主键插入
hilo(了解):高低位算法,主键自增,有hibernate来维护,开发时不使用
native:hilo + sequence + indeyity 自动三选一策略
uuid:产生随机字符串作为主键,主键类型必须为String类型
2.自然主键
assigned:自然主键生成策略,hibernate不会管理主键值,由开发人员自己录入
二、hibernate中的对象状态
对象分为三种状态
1.瞬时状态
没有id,没有与session关联
2.持久化状态
有id,与session有关联
3.游离|托管状态
有id,没有与session关联
代码
@Test
public void save() {
Session session = HibernateUtils.openSession();
Transaction tx = session.beginTransaction();
Customer c = new Customer(); // 没有id,没有与session对象关联 => 瞬时状态
session.save(c); // 持久化状态,有id,与session对象关联
tx.commit();
session.close(); // 游离|托管状态,有id,没有关联
}
三种状态的转换图
三、hibernate一级缓存
缓存:提高效率,hibernate中的一级缓存也是为了提高操作数据库的效率
四、hibernate中的事务
事务特性
a原子性
c一致性
i隔离性(事务并发的时候隔离级别)
d持久性
事务并发问题
1、脏读
2、不可重复读
3、幻、虚读
事务的隔离级别
读未提交:出现的问题1、2、3
读已提交:出现的问题2、3
可重复读:出现的问题3(mysql默认级别)
串行化:没有问题,会极大的降低效率
如何在hibernate中指定隔离级别
在hibernate主配置中
<!--specify a JDBC isolation level-->
hibernate.connection.isolation 1|2|4|8
数据库中存储级别是一个字节
0001 1 读未提交
0010 2 读已提交
0100 4 可重复读
1000 8 串行化
项目中如何管理事务
业务开始之前打开事务,业务执行之后提交事务,执行过程中出现异常,回滚事务
在dao层操作数据库需要用到session对象,在service控制事务也是使用session对象完成,我们要确保dao层和service层使用的是同一个session对象
在hibernate中确保使用同一个session的问题,hibernate已经帮我们解决了,我们开发人员只需要调用sf.getCurrentSession()方法获得与当前线程绑定的session对象
注意:调用getCurrentSession()方法必须配合主配置中的一项配置,如下
指定session与当前线程绑定
hibernate.current_session_context_class thread
通过getCurrentSession()方法获得session对象,当事务提交时session会自动关闭,不需要手动close关闭
五、hibernate中的批量查询
HQ查询-hibernate Query Language(支持多表查询,但一般是不复杂时使用)
// 1、书写HQL语句
String hql = "form Customer"; // 查询所有的Customer对象
// 2、根据HQL语句创建查询对象
Query query = session.createQuery(hql);
// 3、根据对象获得查询结果
List<Customer> list = query.list(); // 返回list结果
// query.uniqueResult();//返回唯一的查询结果
// ?占位符
String hql = "form Customer where cus_id = ?"; // 查询所有的Customer对象
//设置参数
session.setParamter(0, 1)// hibernate ?占位符索引从0开始,jdbc从1开始
// :占位符
String hql = "form Customer where cus_id = :cus_id";
session.setParamter("cus_id", 1)// hibernate :占位符直接输入占位名字
// 分页查询
query.setFirstResult(0);// 第一条数据开始的位置,0是索引
query.setMaxResult(20);// 设置查询结果最大条数,想当与pagesize
Criteria查询-hibernate自创的无语句查询(单表查询)
Criteria criteria = session.createCriteria(Customer.calss); //查询所有的Customer对象
List<Customer> list = criteria.list();// 返回list结果
// criteria.uniqueResult();// 返回唯一查询结果
// 条件查询
// > gt
// >= ge
// < lt
// <= le
// == eq
// != ne
// in in
// between and between
// like like
// is not null isNotNull
// is null isNull
// or or
// and and
criteria.add(Restrictions.eq("cus_id", 1))// 查询cus_id为1的对象
// 聚合函数
criteria.setProjection(Projections.rowCount);// count函数
// 分页查询
criteria.setFirstResult(0);// 第一条数据开始的位置,0是索引
criteria.setMaxResult(20);// 设置查询结果最大条数,想当与pagesize
原生SQL查询(复杂业务查询)
// 书写sql语句
String sql = "select * from customer";
// 创建sql查询对象
SQLQuery query = session.createSQLQuery(sql);
// 指定结果集封装到指定对象中
query.addEntity(Customer.class);
// 调用方法查询结果
List<Customer> list = query.list();
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。