hibernate学习概要
一、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();