hibernate 2

hibernate 2

持久化类

  • 持久化:将内存中的数据永久存储到关系型数据库

  • 编写规则

    • 提供无参构造方法:因为底层需要使用反射生成类的实例
    • 属性私有,对私有属性提供公有的get和set方法:因为底层会将查询到的数据进行封装
    • 属性尽量使用包装类的类型:因为包装类默认值与基本数据类型默认值不同
    • 持久化类要有一个唯一标识符OID与表的主键对应:因为hibernate通过OID区分内存中是否是同一个持久化类
    • 尽量不要使用final进行修饰:hibernate有延迟加载机制,这个机制会产生代理对象,hibernate产生代理对象使用的是字节码的增强技术完成的,其实也就是产生了当前类的一个子类对象实现,如果使用final修饰持久化类,就不能产生子类,也就不能产生代理对象,那么延迟加载机制(一种优化手段)也就失效
  • 主键生成策略

    • 自然主键:具有业务含有的字段如name
    • 代理主键:不具备业务含义
    • 策略
    名称描述
    increment用于long、short、int型,以递增的方式生成唯一标识符,每次加一,只有当没有其他进程向同一张表中插入数据时才能使用,不能在集群环境中使用,适用于代理主键
    identity采用底层数据库本身提供的主键生成标识符,条件是数据库支持自动增长数据类型,适用于代理主键
    sequence根据底层数据库序列生成标识符,条件是数据库支持序列,适用于代理主键
    uuid128位uuid算法生成标识符,能够在网络环境中生成唯一标识符,其uuid被编码为长度为32位的16进制字符串,不流行,因为占空间,适用于代理主键
    assigned由程序员负责生成标识符,如果不知道id元素的generator属性,默认使用该主键生成策略,适用于自然主键
    native根据底层数据库来选择identity、sequence、hile三种生成器中的一种
  • 持久化对象三种状态

    • 瞬时态(transient):也称临时态或者自由态
      • 由new命令创建、开辟内存空间的对象,不存在持久化标志OID,尚未与hibernate session关联,在数据库中没有记录,失去引用后被JVM回收,仅是一个信息携带的载体
    • 持久态(persistent)
      • 存在持久化标志OID,加入到session缓存中,并且相关联是session没有关闭,在数据库中有相对应的记录
    • 脱管态(detached)
      • 存在持久化标志,仍然与数据库中的数据存在关联,只是失去了与当前session的关联,发生改变时hibernate不能检测到
    • 区分:实体类new后即为瞬时态,session执行save等方法后进入持久态,session提交后即为脱管态(没有被session管理);另外,如果new后设置属性值,此时因为没有被session管理则进入脱管态
      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dwrIVBKw-1583938722055)(:storage\f491f6cf-8f76-41a9-b9c7-230f4aaf0e0c\3930d6ea.png)]
  • 持久化对象能够自动更新数据库

    Customer c = session.get(Customer.class, 1l);//持久化对象
    c.setName("xiao");
    //session.update(c); 不用手动调用
    ...
    

缓存

一级缓存

  • 一级缓存即session缓存,用来存放相互管理的java对象
  • 使用Hibernate查询对象时,首先使用对象属性的OID值在一级缓存中进行查找,如果找到则直接从一级缓存中取出使用,不会再查询数据库;没有则去数据库中查找相应数据
  • 可以减少对数据库的访问次数
  • 特点
    • 调用save()、update()、saveOrUpdate时,缓存中没有相应的对象,则自动从数据库中查询相应对象信息加入到一级缓存中
    • 调用session的load()、get()、以及Query接口的list()、iterator()方法时,会判断缓存中是否存在该对象,有则返回,不会查询数据库
  • 一级缓存的内部结构(快照区)
    • hibernate向一级缓存放入数据时,同时复制一份数据到快照中,当使用commit提交事务时,会清理session的一级缓存,这时会使用OID判断一级缓存中的对象和快照中的对象是否一致,如果两个对象中的属性发生变化,则会执行update方法,将缓存的内容同步到数据库并更新快照

事务控制

  • 特性
    • 原子性
    • 一致性
    • 隔离性
    • 持久性
  • 并发问题
    • 脏读:读取到未提交的数据
    • 不可重复读:数据更新导致多次查询不一致
    • 虚读\幻读:读取到已经提交的insert数据,导致多次查询结果不一致
  • 隔离级别
    • 读未提交(read uncommitted 1级)
    • 已提交读(Read committed, 2级)
    • 可重复读(repeatable read, 4级)
    • 序列化/串行化(Serializable,8级)
  • 配置文件中设置事务隔离级别
    <property name="hibernate.connection.isolation">隔离级别,用数字表示</property>
    
  • 保证service开启的事务使用的session对象和DAO中多个操作使用的是同一个session对象
    • 业务层获取session并将session作为参数传递到DAO
    • 使用ThreadLocal将业务层获取的Sessio绑定到当前线程,然后在DAO中获取Session时,都从当前线程中获取(最优)
  • Hibernate提供的三种管理Session对象的方法
    • Session对象的生命周期与本地线程绑定
    • Session对象的生命周期与JTA事务绑定
    • Hibernate委托程序管理Session对象的生命周期
  • 配置文件中,hibernate.current_session_context_class属性用于指定Session管理方式
    • thread
    • jta
    • managed

其他API

Query

  • 代表面向对象的查询操作,通常使用session.createQuery()方法接收HQL语句,然后调用Query的list()或uniqueResult()方法执行查询
    //select all
    Query query = session.createQuery("from Customer");
    List<Customer> list = query.list();
    
    //条件查询
    Query query = session.createQuery("from Customer where name = ?");
    query.setString(0,"xiao");
    List<Customer> list = query.list();
    
    Query query = session.createQuery("from Customer where name = :aaa and age=:bbb");
    query.setString("aaa","xiao");
    query.setString("bbb",12);
    query.setFirstResult(3);
    query.setMaxResults(3);
    List<Customer> list = query.list();
    

Criteria

//查询所有记录
Criteria c = session.createCriteria(Customer.class);
List<Customer> list = c.list();
//条件查询
Criteria c = session.createCriteria(Customer.class);
criteria.add(Restrictings.eq("name","xiao"));
...
List<Customer> list = c.list();
//条件查询
Criteria c = session.createCriteria(Customer.class);
criteria.setFirstResult(3);
criteria.setMaxResults(3);
...
List<Customer> list = c.list();

SQLQuery

SQLQuery s = session.createSQLQuery("sql语句");
s.addEntity(customer.class);
List<Object[]> list = s.list();
for(Object[] o:list){
  ...
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值