Hibernate-2
hibernate中的实体规则
实体类创建的注意事项
1、持久化类提供无参数构造
2、成员变量私有,提供共有get/set方法访问,需提供属性
3、持久化类中的属性,应尽量使用包装类型
4、持久化类需要提供oid,与数据库中的主键列对应
5、不要用final修饰Class(hibernate使用cglib代理生成代理对象,代理对象是继承被代理对象。如果被final修饰将无法生成代理)
主键类型
自然主键(少见):表的业务列中,有某业务列符合“必须有并且不重复”的特征时,该列可以作为主键使用。
代理主键(常见):表的业务列中,没有某业务列符合“必须有并且不重复”的特征时,创建一个没有业务意义的列作为主键。
代理生成策略
代理主键
identity:主键自增,由数据库来维护主键值,录入时不需要指定主键。
sequence:Oracle中的主键生成策略。
increment(了解):主键自增,由hibernate来维护,每次插入前会先查询表中id最大值。+1作为新主键值。
hilo(了解):高低位算法,主键自增。由hibernate维护,开发时不使用。
native:hilo+sequence+identity自动三选一策略。
uuid:产生随机字符串作为主键,主键类型必须为String类型。
自然主键:assigned:自然主键生成策略。hibernate不会管理主键值,由开发人员自己录入。
hibernate中的对象状态
对象分为三种状态
瞬时状态:没有id,没有在session缓冲中。
持久化状态:有id,在session缓存中。
游离|托管状态:有id,没有在session缓存中。
学习对象三种状态的结论:将我们希望同步到数据库的数据,对应的对象转换为持久化状态。
起点——>瞬时状态(new)
瞬时状态——>持久化状态(save)
持久化状态——>瞬时状态(delete)
起点——>持久化状态(get)
持久化状态——>游离|托管状态(close)
游离|托管状态——>持久化状态(update)
hibernate进阶——一级缓存
缓存:提高效率。hibernate中的一级缓存也是为了提高操作数据库的效率。
提高效率手段1:提高查询效率
提高效率手段2:减少不必要的修改语句发送
hibernate中的事务
事务
事务特性:原子性、一致性、隔离性、永久性
事务并发问题:1、脏读;2、不可重复读;3、幻读;
事务的隔离级别:读未提交(123);读已提交(23);可重复读(MySQL默认级别 3);串行化(没有问题)
知识点1:如何在hibernate中指定数据库的隔离级别
<!-- 指定hibernate操作数据库时的隔离级别
#hibernate。connection。isolation 1|2|4|8
0001 1 读未提交
0010 2 读已提交
0100 4 可重复读
1000 8 串行化
-->
<property name="hibernate.connection.isolation">4</property>
知识点2:在项目中如何管理事务
业务开始之前打开事务,业务执行之后提交事务,执行过程中出现异常,回滚事务。
在dao层操作数据库需要用到session对象。在service控制事务时也是使用session对象完成。我们要确保dao层和service层使用同一个session对象。
在hibernate中,确保使用同一个session的问题,hibernate已经帮我们解决了,我们开发人员只需要调用sf.getCurrentSession()方法即可获得与当前线程绑定的session对象。
注意1:调用getCurrentSession方法必须配合主配置中的一段配置
<!--指定session与当前线程绑定-->
<property name="hibernate.current_session_context_class">thread</property>
注意2:通过getCurrentSession方法获得的session对象,当事务提交时,session会自动关闭。不要手动调用close关闭。
crm项目中
service层
public void save(Customer c){
Session session = HibernateUtils.getCurrentSession();
//打开事务
Transaction tx = session.beginTransaction();
//调用Dao保存客户
try{
customerDao.save(c);
}catch(Exception e){
e.printStackTrace();
tx.rollback();
}
//关闭事务
tx.commit();
}
Dao层
public void save(Customer c){
//1、获得session
Session session = HibernateUtils.getCurrentSession();
//2、执行保存
session.save(c);
}
Hibernate中的批量查询
HQL查询-hibernate Query Language(多表查询,但不复杂时使用)
Hibernate独家查询语言,属于面向对象的查询语言
基本查询
//1>书写HQL语句
String hql = "from cn,itheima.domain.Customer ";
String hql = "from Customer"; //查询所有Customer对象
//2>根据HQL语句创建查询对象
Query query = session.createQuery(hql);
//3>根据查询对象获取查询结果
List<Customer> list = query.list(); //返回list结果
//query.uniqueResult();//接受唯一的查询结果
条件查询
?占位符
//1>书写HQL语句
String hql = "from Customer where cust_id = ?";//查询所有Customer对象
//2>根据HQL语句创建查询对象
Query query = session.createQuery(hql);
//设置参数
//query.setLong(0,1l);
query.setParameter(0,1l);
//3>根据查询对象获得查询结果
Customer c = (Customer)query.uniqueResult();
命名占位符
//1>书写HQL语句
String hql = "from Customer where cust_id = :cust_id "; //查询所有Customer对象
//2>根据HQL语句创建查询对象
Query query = session.createQuery(hql);
//3>设置参数
query.setParameter("cust_id",1l);
//3>根据查询对象获得查询结果
Customer c = (Customer)query.uniqueResult();
分页查询
//1>书写HQL语句
String hql = "from Customer "; //查询所有Customer对象
//2>根据HQL创建查询对象
Query query = session.createQuery(hql);
//设置分页信息limit?,?
query.setFirstResult(1);
query.setMaxResult(1);
//3>根据查询对象获得查询结果
List<Customer> list = query.list();
练习:客户列表
请求——>ListCustomerServlet
1、调用service查询客户列表;2、将列表数据放入request域;3、转发到list页面显示列表
——>CustomerService
List<Customer> getAll(); 事务处理; 调用dao
——>CustomerDao
List<Customer> getAll();
HQL或Criteria