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)
    
posted @ 2020-03-21 11:10  Jimmyhe  阅读(122)  评论(0编辑  收藏  举报