zoukankan      html  css  js  c++  java
  • Hibernate 干货2



    @ORM框架
     对象关系映射,用于实现面向对象编程语言里不同系统的数据之间的转换

    @实例
    public void demo01(){
      User user = new User();
      user.setUsername("haha");
      user.setPassword("123");

      //加载配置文件获得核心配置对象
      Configuration config = new Configuration().configure("配置文件");
      //获得工厂SessionFactory,相当于连接池
      SessionFactory factory = config.buildSessionFactory();
      //获得回话session,相当于链接Connection
      Session session  = factory.openSession();
      //开启事务
      Transaction transaction = session.beginTransaction();
      //操作
      session.save(user);
      //提交事务 | 回滚事务
      transaction.commit();
      //释放资源
      session.close();
      //关闭工厂
      factory.close();
    }

    PO:persistent object ,用于与数据库交互数据
    BO:Business object 业务数据对象
    VO: value Object 值对象

    @Configuration配置对象
      1:提供构造 new Configuration() hibernate 将自动加载hibernate.properties
      2:提供方法 configure() 将加载src下的hibernate.cfg.xml
      3:扩展api configure(String) 加载执行目录下的xml文件
      4:手动加载配置文件
        //手动加载指定的配置文件
        config.addResource("com/shikun/hello/User.hbm.xml");
        //手动加载指定类,对应的映射文件
        config.addUser(user.class);

    @SessionFactory工厂
     1:SessionFactory相当于java web连接池,用于管理所有session
     2:获得方式:config.buildSessionFactory();
     3:sessionFactory hibernate缓存配置信息(数据库配置信息,映射文件)
     4:SessionFactory线程安全,可以是成员变量,多个线程同时访问
     5://打开一个新的回话 session
        factory.openSession();
        //获得当前线程中绑定的会话session
        factory.getCurrentSession();
      6:hibernate支持,将创建session绑定到本地线程中,底层使用ThreadLoacl,在程序之   间共享session
        1:必须在hibernate.cfg.xml配置
        <property name="hibernate.current_session_context_class">thread</property>
        2:如果提交或回滚事务,底层将自顶关闭session


    @Session会话
      1:Session相当于JDBC的Connection会话
      2:session单线程,线程不安全,不能编写成员变量
      3:session api
         1:save 保存 2:update 更新 3:delete:删除
         4:get:通过id查询,如果没有 null
         5:load 通过id查询,如果没有跑异常
         6:createQuery("hql") 获得Query对象
         7:createCriteria(class) 会的Criteria对象

    @Transaction事务
      1:开启事务  beginTransaction()
      2:获得事务 getTransaction()
      3:提交事务  commit()
      4:回滚事务 rollback()

    @Query对象
      1:hibernate执行hql语句
      2:hql语句:hibernate提供面向对象查询语句,使用对象和属性进行查询
      3:获得session.createQuery("hql");
      4:方法:
        list() 查询所有
        uniqueResult():获得一个结果,如果没有查询到返回null,如果查询多条抛异常
        setFirstResult(int) 分页,开始索引数startIndex
        setMaxResult(int) 分页,每页显示个数 pageSize


    @Criteria对象
      1:QBC(query by criteria),hibernate提供春面向对象查询语言
      2:获得方式:Criteria criteria = session.createCriteria(User.class);
      3:eq :等于 gt:大于 ge:大于等于 lt:小于 le:小于等于 like:模糊查询


    @hibernate基本配置
     <property name="hibernate.connection.driver_class>com.mysql.jdbc.Driver</property>
     <property name="hibernate.connection.url">jdbc:mysql://db</property>
     <property name="hibernate.connection.username">root</property>
     <property name="hibernate.connection.password">123</property>
     //与本地线程绑定
     <property name="hibernate.current_session_context_class">thread</property>
     //方言:不同的数据库,生成sql语句提供依据
     <property name="hibernate.dialect">org.hibernate.dialect.MySQL5Diaelct</property>
     //sql语句
     <property name="hibernate.show_sql">true</property>
     <property name="hibernate.format_sql">true</property>
     //表生成策略
     <property name="hibernate.hbm2ddl.auto">create</property>
     //验证
     <property name="javax.persistence.validation.mode">none</property>
     //添加映射文件
     <mapping resource="com/shikun/hello/User.hbm.xml"/>


    @hibernate中持久化类
     1:持久化对象的唯一标识OID
       1:javaan地址区分同一个类的不同对象
       2:关系数据库用主键区分同一条记录
       3:Hibernate使用OID来建立内存中的对象和数据库中记录的对应关系
       4:对象的OID和数据库的标的主键对应,由hibernate来为OID赋值
      2:区分自然主键和代理主键
      主键需要具备:不为空,不能重复,不能改变
        1:自然主键:在业务中,某个属性符合主键的三个要求,该属性可以作为主键列
        2:代理主键:在业务中,不存符合以上三个条件的属性,就增加一个没有意义的列    作主键
      3:基本数据与包装类型
        1:基本类型无法表达null,默认为0
        2:包装类默认值是null


    @主键生成策略
     <id>配置主键,name:属性名称 access=““ 设置使用属性还是字段
        column=”“ 表的列名  length=“” 长度  type=“” 类型
     <generator>class 属性用于设置主键生成策略
       1:increment 由hibernate自己维护自动增长
       2:identity hibernate磁层采用数据库本身自动增长列
       3:sequence hibernate底层采用数据库序列
       4:Hilo
       5:native:根据底层数据库的能力选择 identity,sequence或者Hilo中的一个
       6:uuid 采用字符串唯一值,代理主键,由hibernate维护
       7:assigned 自然主键,由程序自己维护

    @对象状态
      hibernate规定三种状态:瞬时态,持久态,脱管态
      1:瞬时态:transient,session没有缓存对象,数据库也没有对应记录,OID没有值
      2:持久态:persistent,session缓存对象,数据库最终会有记录 OID特点:有值
      3:脱管态:detached,session没有缓存对象,数据库有记录 OID有值
      4:状态转换
         1:瞬时态转换持久态  一般操作:save方法,saveOrUpdate
         2:瞬时态转换脱管态  一般操作:通过setId方法设置数据

    @一级缓存
     1:又称为session级别的缓存,当获得一次会话session,hibernate在session中创建多    个集合map,用于存放操作数据po对象,为程序优化服务,如果之后需要相应的数据,  
     hibernate优先从session缓存中获取,如果有就使用;如果没有在查询数据库。当session关闭时,一级缓存销毁
     2:清除缓存
        session.evict(对象);
     3:快照:与一级缓存一样的存放位置,对一级缓存数据备份,保证数据库的数据与一级   缓存的数据必须一致。如果一级缓存修改了,在执行commit提交时,将自动刷新一集缓存,执行update语句,将一级缓存的数据更新到数据库
     4:refresh 刷新:保证一级缓存的数据与数据库的数据保证一致将执行select语句查询数据库,将一级缓存中的数据覆盖掉,只要执行refresh都将执行select语句

    @PO对象操作
      1save&persist
       save方法:瞬时态转换持久态,会初始化OID
         1:执行save方法,立即触发insert语句,从数据库获得主键的值OID值
         2:执行save方法前,设置OID将忽略
         3:如果执行查询,session缓存移除了,在执行save方法,将执行insert
         4:persist方法不会立即得到ID,所以执行sql语句的时机要靠后
      2:update :脱管态 转换 持久态
         1:如果OID在数据存放的,将执行update语句
         2:如果OID不存在将抛异常
      3:saveOrUpdate:判断是否有OID
         代理主键:
         1:如果没有OID,将执行insert语句
         2:如果有OID,将执行update语句
         自然主键:
         1:先执行select语句,查询是否存放
         2:如果不存在,将执行insert
         3:如果存在,将执行update


    @多表设计
    一对多:主表必须主键和从表必须外键,主表的主键与从表外键形成主外键关系
    多对多:提供中间表,提供2个字段(外键)分别对应两个主表

    @关联关系映射
      1:一对多实现:一个客户,拥有多个订单
         private Set<Order> orderSet = new HashSet<Order>();
         配置文件
         1:确定容器 set<set>
         2: name确定对象属性名
         3:确定从表外键的名称
         4:确定关系,及另一个对象的类型
         注意:在hibernate中可以只进行单项配置,每一个配置项都可以完整的描述彼此关系,一般情况采用双向配置,双方都可以完成描述表与表之间关系
         <set name="orderSet" cascade="delete-orphan">
           <key column="customer_id"></key>
           <one-to-many class="com.shikun.Order"/>
         </set>
         多对一:多个订单属于一个客户
         private Customer customer;
         配置文件
         1:name 确定属性名称
         2:class 确定自定义类型
         3:column 确定从表的外键名称
         <many-to-one name="custoemr" class="com.shikun.Customer" column="customer_id"></many-to-one>

      2:双向关联,使用inverse
        <set name="orderSet" inverset="true">
           <key column="customer_id"></key>
           <one-to-many class="com.shikun.Order"/>
        </set>
      3:级联操作
        1:save-update 级联保存或更新
           <set name="orderSet" cascade="save-update">
           </set>
        2:delete 级联删除
         <set name="orderSet" cascade="delete">
         </set>
        3:孤儿删除:一对多关系,存在父子关系,主表可以成为父表多表也可以成为子表
               客户和订单接触关系后,外键被设置成null,此时订单就是孤儿,两者单独存在 孤儿删除,当订单称为孤儿,一并删除,客户仍存在
          主表不能删除,从表已经引用(关联)的数据
          从表不能添加,主表不存在的数据
           <set name="orderSet" cascade="delete-orphan">
           </set>
      4:多对多映射
         配置多对多关联映射
         Course.hbm.xml
         <set name="students" table="stu_cour">
            <key column="cno"/>
            <many-to-many class="com.shikun.Student" column="sno"/>
         </set>
         Student.hbm.xml
          <set name="course" table="stu_cour">
            <key column="sno"/>
            <many-to-many class="com.shikun.Course" column="cno"/>
          </set>


    @抓取策略
        1:检索方法
          a:立即检索:立即查询,在执行查询语句时,立即查询所有的数据
          b:延迟检索:延迟查询,在执行查询语句之后,在需要时在查询(懒加载)
        2:检索策略
          a:类级别检索:当前的类的属性获取是否需要延迟
          b:关联级别的检索:当前类关联另一个类是否需要延迟
        3:类级别检索
          a:get :立即检索,get方法一执行,立即查询所有字段的数据
          b:load:延迟检索,默认情况,load方法执行后,如果只使用OID的值不进行查询
              如果要使用其他属性值将lazy默认值TRUE,为FALSE,表示立即检索
        4:关联级别检索
          a:一对多或多对多
             1:容器<set>提供两个属性:fetch,lazy
                fetch:确定使用sql格式
                lazy:关联对象是否延迟
             2:fetch:join,select,subselect
                join:底层使用迫切左外链接,lazy无效
                select:使用多个select语句
                subselect:使用子查询
             3:lazy:FALSE,true,extra
                false:立即
                TRUE:延迟
                extra:极其懒惰
           b:多对一:<many-to-one fetch="" lazy="">
              1:fetch:取值:join,select
                join:底层使用迫切左外链接
                select:多条select语句
              2:lazy取值:FALSE,proxy,no-proxy,no-proxy
                FALSE:立即
                proxy:采用关联对象,类级别检索的策略
        5:批量查询
           1:批量查询使用in语句减少查询语句的个数
              select * from order where customer in(?,?,?,?,?)
           2:<set batch-size="5">:5表示括号中?个数



    @HQL:Hibernate Query Language 描写对象操作一种查询语句,查询的是对象的属性
        1:查询所有客户
           1:使用简单类名,存在自动导包
             session.createQuery("from 简单类名");
           2:使用全限定类名
             session.createQuery("from com.shikun.简单类名");
        2:选择查询
           1:指定数据,cid,OID民称
           2:使用id
           3:对象别名
           4:查询所有项
        3:投影查询
           1:默认
              a:单列使用List<object>
              b:多列需要List<Object[]>
        4:order by  asc|desc
        5:分页
            startIndex = (pageNum -1 )* pageSize
            //pageNum 当前页
            query.setFirstResult();
            //pageSize:每页显示个数
            query.setMaxResults()       
        6:绑定参数
            1:setXxx(int,object)
            2:setXxx(String,object)
            3:setParameter(int|string,object)
        7:聚合函数和分组
            1:count(*|别名|oid)
        8:连接查询
           1.交叉连接 ,等效 sql 笛卡尔积
           2.隐式内连接,等效 sql 隐式内连接
           3.内连接,等效sql内连接
           4.迫切内连接,hibernate底层使用 内连接。
           5.左外连接,等效sql左外连接:底层是使用sql的左外链接,hibernate进行数据   自动封装,将一条记录封装给两个对象
           6.迫切左外连接,hibernate底层使用 左外连接  left outer join fetch ,底层使用sql的左外链接,hibernate将一条记录封装给一个对象,将另一条数据封装给另一个对象,并将对象2关联到对象1,默认查询的数据重复
              去重复
              select distinct c from Customer left outer join fetch c.orderSet
           7.右外连接,等效sql右外连接
         9:命名查询
           全局:session。getNamedQuery("queryName");
           局部:session.getNamedQuery("className.queryName"); 需要使用类的全限定名称


    @QBC
        1:QBC查询:Query By Criteria 条件查询,面向对象的查询的方式
        2:QBC简单的查询:session.createCriteria(Customer.class);
        3: QBC分页的查询:
           criteria.setFirstResult(10);
           criteria.setMaxResults(10);
        4:QBC排序查询:
           criteria.addOrder(org.hibernate.criterion.Order.asc(""));
        5:QBC条件查询
           criteria.add(Restrictions.eq("属性","值"));
           //模糊查询
           criteria.add(Restrictions.like("属性","条件"));
        6:离线查询:DetachedCriteria 离线查询对象,不需要session,在web
               或service层拼凑,将此对象传递给dao层
            DetachedCriteria detachedCtiteria = DetachedCriteria.forClass(Customer.class);


    @整合c3p0连接池
        <property name="hibernate.connection.provider_class">org.hibernate.connection.C3P0ConnectionProcider</property>


    @事务
       悲观锁:丢失更新发生,采用数据库锁机制
       读锁:共享锁 select ... from ... lock in share mode;
       写锁:排它锁 select ... from ... for update
         session.get(Customer.class,1,LockMode.UPGRADE);
       乐观锁:丢失更新肯定不会发生,在po对象|表中提供一个字段,一般Integer在hbm.xml文件配置<version name="...">,用于表示记录,如果版本不一致,不允许操作


     @二级缓存:降低应用程序直接读写硬盘的频率
        1:hibernate提供缓存机制:一级缓存,二级缓存
           一级缓存:session级别缓存,在一次请求中共享数据
           二级缓存:sessionFactory级别缓存,整个应用程序共享一个会话工厂
        2:SessionFactory的缓存两部分:内置缓存:使用一个Map,用于存放配置信息,预    定义HQL语句,提供给Hibernate框架自己使用,对外只读的,不能操作 ; 外置缓存:使用另一个Map,用于存放用户自定义数据,默认不开启,外置缓存hibernate只提供规范,需要第三方实现类,外置缓存又称为二级缓存
        3:二级缓存内部结构
          由四部分组成:类级别缓存,集合级别缓存,时间戳缓存,查询缓存
        4:并发访问策略
          1:transactional:事务型
          2:read-write:读写型
          3:nonstrict-read-write:非严格读写型
          4:read-only:只读型
        5:二级缓存提供商
        EHCache:           可作为进程(单机)范围内的缓存,存放数据的物理介质可以是内存或硬盘, 对   Hibernate 的查询缓存提供了支持。--支持集群。
    ?OpenSymphony `:可作为进程范围内的缓存, 存放数据的物理介质可以是内存或硬盘, 提供了丰富的缓存数据过期策略, 对 Hibernate 的查询缓存提供了支持
    ?SwarmCache: 可作为集群范围内的缓存, 但不支持 Hibernate 的查询缓存
    ?JBossCache:可作为集群范围内的缓存, 支持 Hibernate 的查询缓存
        6:开启二级缓存
          <property name="hibernate.cache.user_second_level_cache">true</property>
          确定提供商
          <property name="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</property>
          确定缓存内容
          <class-cache usage="read-write" class=""/>
          //集合缓存
           <collection-cache usage="read-write" collertion=""/>
        7;类缓存:只存放数据 一级缓存:存放对象本身
        8:集合缓存:只存放关联对象OID的值,集合操作,将从集合缓存获得内容,此时只   能获得OID的值,然后从类缓存查询指定对象
        9:时间戳:任何操作都在时间戳中记录操作时间,如果不一致,将触发select语句 10:查询缓存:又称为三级缓存,将HQL语句与查询结果进行绑定,通过HQL相同语句可以缓存内容,默认情况Query对象枝江查询结果存放在一级和二级缓存,查询缓存就是让Query可以从二级缓存获得内容         
           1:开启查询缓存
           <property name="hibernate.cache.use_query_cache">true</property>
           2:在查询query对象,设置缓存内容
           Query q = s.createQuery("from student");
           q.setCacheable(true);


    原文:https://blog.csdn.net/github_37473774/article/details/71211299

  • 相关阅读:
    [转载]代码里的命名规则:错误的和正确的对比
    解决WINDOWS 8 应用下载错误
    为什么这儿TemplateBinding不起作用了—研究WPF Binding(一)
    WINDOWS 8 使用与配置汇总(不断更新)
    Mac 安装和配置Maven
    CentOS 8 安装 Sublime Text 3
    CentOS8 安装 Chrome浏览器
    CentOS 8 防火墙相关命令
    CentOS8 安装Nginx
    java.lang.NoClassDefFoundError: org/apache/commons/beanutils/BeanUtils
  • 原文地址:https://www.cnblogs.com/gu-bin/p/10420474.html
Copyright © 2011-2022 走看看