zoukankan      html  css  js  c++  java
  • java web hibernate自学day2

    持久化类 = java类 + 映射文件

    编写规则
    • 对持久化类提供一个无参数的构造方法,hibernate底层需要反射生成实例。
    • 属性私有,对私有属性提供public的get,set方法
    • 对持久化类提供一个唯一表示oid和数据库主键关联
    • 持久化类中属性尽量使用包装类类型
    • 持久化类不要使用final进行修饰,因为如果该类不能被继承,也就无法产生代理对象,延迟加载也会失效。
    主键生成策略
            <id name="cust_id" column="cust_id">
                <!--本地存储-->
                <generator class="native"></generator>
            </id>
    
    • increment 提供自动增长机制,适用于short,int,long。不要在多线程中使用,会导致主键重复。因为使用的是select max(id)
    • identity 使用数据库底层的自动增强机制
    • sequence 适用于序列的方式 orcale支持序列
    • native 本地策略,可以在identity和sequence之间切换
    • Assigned 由程序本身控制
    持久化类的三种状态
    • 瞬时态

      这种对象没有唯一的标识oid,没有被session管理

      • 创建 new
      • 转为持久 save,saveOrUpdate
      • 转为脱管 给创建的对象设置id
    • 持久态

      有唯一的oid,被session管理,可以自动更新数据库

      • 创建 get() load() find() iterate()
      • 转为瞬时 delete()
      • 转为脱管 session.close() clean() evict(obj)
    • 脱管态

      有唯一的id,没有被session管理

      Customer customer = new Customer(); //瞬时态
      customer.setCust_name("dwight");
      session.save(customer); //持久胎
      
      transaction.commit();
      session.close();
      System.out.println(customer.getCust_name()); // 脱管态
      
      • 创建 new.obj.setid
      • 转为持久 update , saveOrupdate
      • 转为瞬时 new.setid(null)

    一级缓存

    跟session生命周期一致

    指session缓存的java集合,用来存放相互管理的java对象,在使用hibernate查询的时候,首先会使用对象的oid值,在hebernate的一级缓存中进行查找,如果找到匹配oid值的对象,就会从一级缓存中取出使用,不会使用数据库查询,当调用close时会清空。

    利用一级缓存作为key,快照区作为value。如果改变了一级缓存,则在commit时比较键值是否相同,如果不相同则会修改数据库。

    session.clear(). session.evict(obj)可以清空一级缓存

    事务

    • 脏读:一个事物读到另一个事物未提交的数据
    • 不可重复读:一个事物读到另一个事物已经提交的update数据,导致前一个事物多次查询结果不一致
    • 幻读:一个事物读到另一个事物已经提交的insert数据,导致前一次事物多次查询结果不一致

    事务的隔离级别

    • 读未提交:以上问题都会发生
    • 读提交:解决脏读,但是不可重复读和幻读都可能发生 orclae
    • 重复读:解决不可重复读和脏读,但是幻读会发生 mysql
    • 序列化:解决所有读问题,不能事物的并发
    设置隔离级别

    在hibernate.cfg.xml中

    1 读未提交

    1. 读提交

    2. 重复读

    3. 序列化

    <property name='hibernate.connection.isolation'>4</property>
    
    保证serivce层连接
    1. 向下传递DButils

    2. 使用ThreadLocal对象

      将连接绑定到当前线程中,在dao方法中,通过当前线程获得当前线程连接

      在hibernate框架内部绑定好了ThreadLocal

      sessionFactory中提供了一个方法getCurrentSession获取当前连接

    1. 配置
            <!--配置当前线程绑定session-->
            <property name="hibernate.current_session_context_class">thread</property>
            
    2. 调用
        public static Session getCurrentSession(){
            return sf.getCurrentSession();
        }
        此session不需要close()
    

    Query HQL

            String sql = "from Customer";
            // 条件查询
            String sql1 = "from Customer where cust_name like ?0";
    
            Query query = session.createQuery(sql1);
    
            // 分页查询
            query.setFirstResult(0); //从第几页开始
            query.setMaxResults(3);  //每页数量
    
            query.setParameter(0,"d%");
            List<Customer> list = query.list();
            for (Customer customer : list) {
                System.out.println(customer.getCust_name());
            }
    

    一对多建表

    1. 在持久化类中通过一的一方的对象和多方的集合来关联,
    private string cust_name;
    private Man man;   man时多的一方
    ...
    private Set<Cust> cust
    
    1. 配置文件

      // 配置多对一的关系,放置的是一的一方的对象
      <many-to-one name="一的一方属性名称" class="一的一方类的全路径" column="在多的一方表的外键名称"></many-to-one>
      
      // 配置一对多的映射,放置的是多的一方的集合
      在class标签中
      <set name="多的一方集合的属性名称" cascade="save-update"> //级联可以在任意一方设置
      	<key colume=多的一方外键的名称""></key>
      	<one-to-many class="多的一方类的全路径"/>
      <set>
      
    2. 编辑关系

      linkman.setCustomer()
      customer.getLinkMans().add(linkMan)
      
      两边必须都要保存
      
    3. 级联操作

      cascade=save-update,delete
      
    解决一对多 sql语句多余

    在配置文件中,修改一的一方外键维护权,在多的一方配置inverse

    <set name="多的一方集合的属性名称" cascade="save-update" inverse="true">
    

    注意:在保存的时候,如果save(一的一方),级联到多的一方也保存, 多的一方可以维护外键,即可成功,反之,如果save(多的一方),级联到一的一方,那么会没有主键。所以保存的时候要保存一的一方。

    多对多建表

    两个关联的类都应该放置对方的集合

    # 比如用户表和角色表
    private Set<User> users = new HashSet<User>();
    ...
    private Set<Role> roles = new HashSet<Role>();
    
    • 配置文件

      <set name="对方的集合属性名称" table="中间名称">
      	<key column="当前对象对应中间表的外键的名称"/>
      	<many-to-many class="对方类的全路径" column="对方的对象对应中间表的外键的名称"/>
      </set>
      
    • 保存操作

      创建角色
      Role role1 = new Role();
      role1.setRole_name("研发部")
      user1.getRoles().add(role1);
      // 多对多建立了双向的关系,必须有一方放弃外键维护,一般是被动方放弃,比如角色,所以要在Role表中添加inverse=true
      session.save(user1)
      
  • 相关阅读:
    学以致用十九-----shell脚本之引号
    学以致用十八-----shell脚本之基础概念及变量
    学以致用十七-----shell脚本之比较数字和字符串及if else
    学以致用十六-----Centos7.2编译安装mysql5.6.22
    学以致用十五-----前端里注意事项一
    学以致用十四-----打造一个简单的vim IDE
    学以致用十三-----Centos7.2+python3+YouCompleteMe成功历程
    json、javaBean、xml互转的几种工具介绍
    android课程第一节(TextView控件使用)
    Android Please ensure that adb is correctly located at问题解决
  • 原文地址:https://www.cnblogs.com/jimmyhe/p/12537205.html
Copyright © 2011-2022 走看看