A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

就业班_JavaEE_day39_42_Hibernate

一 概述
    封装jdbc;dao层;orm框架;
    orm 对象关系映射    类 -- 表   属性 -- 字段  对象---记录
    用面向对象的思想来操作数据库


二 快速入门
    1 导包
    required
    jpa--适配器jar包
    驱动包
    3个日志包
    如果用到c3p0 导入c3p0包
    2 配置文件
    src下 hibernate.cfg.xml   
    domain 下 xx.hbm.xml
    都可以在解压包中的project中找到。
    3创建数据库
    4 创建domain类
    5 configuration -- sessionfactory -- session -- transaction -- save update delete get/load -- commit -- 释放资源


三 二个配置文件
    hibernate.cfg.xml
    <hibernate-configuration>
         <!-- 1 必选 数据库连接4要素 -- >
         <property name="">xxxxxx</property>
          driverClass
          url
          username
          password
          <!-- 2 可选 hibernate参数配置 -- >
          dialect
          show_sql
          美化sql
          hbm2ddl update
          //如果用到sesssion.getcurrentsession. 需要添加current_session_context_class配置。
          <!-- 3 必选 映射文件引入 -- >
          <mapping  resource="" />
    </hibernate-configuration>
    补充:hibernate默认内置了一个连接池,如果要使用c3p0 则要添加c3p0的相关配置
            <!-- 设置连接提供者 -->
            <property name="hibernate.connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider</property>
            <!-- c3p0连接池的配置 -->
            <property name="hibernate.c3p0.max_size">20</property> <!-- 最大连接数 -->
            <property name="hibernate.c3p0.min_size">5</property> <!-- 最小连接数 -->
            <property name="hibernate.c3p0.timeout">120</property> <!-- 超时 -->
            <property name="hibernate.c3p0.idle_test_period">3000</property> <!-- 空闲连接 -->
    可以从projects/etc/hibernate.properties 拷贝
    xxx.hbm.xml 映射文件
    <hibernate-mapping>
        <class name="domain类全路径" table="表名">
            <id name="类属性" column="表字段">
                <generator >
                     通常采用二种  native 智能匹配    uuid
                </generator>
            </id>
            <property  name="类属性" column="表字段">
            </property>
        </class>
        
        //还可以配置query
    </hibernate-mapping>


四常用API
    configuration   加载hibernate.cfg.xml
    sessionfatory    sesison工厂 一个项目创建一个 后续spring进行管理 服务器启动就创建
    session             类似于jdbc中的connection    opensession    getcurrentsesison    save update delete get/load saveorupdate
    补充:opensesion  getcurrentsession 区别
        1 opensesion每次都打开一个新的session  getcurrentsession则在第一次调用时打开一个新的,后续调用使用同一个。
        2 opensession需要手动close     getcurrentsesion 不需要手动close 事务提交或者回滚会自动close
        如果使用getcurrentsession 则要在cfg中添加如下设置,来指定contextclass
        <!-- 设置seesion和线程绑定 需要配合SessionFactory的getCurrentSession()使用 -->
        <property name="hibernate.current_session_context_class">thread</property>
        使用getcurrentsession必须开启事务。
    transaction       做增删改操作必须开启事务。
         
五 持久化类
    1 po  javabean+hbm
    2 编写规范:
        1 属性不要用基本类型
        2 private 属性 并提供给 public getset方法
        3 无参数构造
        4 定义与数据库对应的主键属性 比如oid
        5 po类不要用final修饰 因为hibernate中会通过cglib来产生子类代理,如果定位为final则表示该类不能别继承
    3 主键生成策略
        xxx.hbm.xml中配置主键生成策略
        mysql identity
        oracle sequence
        native 智能匹配
        uuid  32位字符串
    4     po类的三种状态
        瞬时态  ---  > 持久态 --->游离态
        new  瞬时态   --->save,saveorupdate   持久态  ---> 从一级缓存中移除,session.close() clear() evict()   游离态
                                    get load find query    持久态

六 缓存
    一级缓存 session  
     优化,减少访问数据库的次数。 Map key=持久化类对象  value=快照(快照特点,产生后将不会发生改变)
     一级缓存的API
      session.clear()   清空缓存
      session.evict(obj)    清除缓存中指定对象
      session.refresh(obj)  重新查询数据库,覆盖缓存中的key和value
    二级缓存 sessionfatory 不用
   
    持久化类具有更新数据库的能力。
   
七关系映射
    一对一
    表            1 唯一外键    2  主键也作为外键指向另外一方的主键。
    java类       互相持有对方的引用
    一对多
    表       多的一方添加外键
    java类
    一方  添加set集合  
    多方  添加一方对象引用
    多对多
    表        中间表 二个一对多
    java类      二边添加set集合
   
    一对多hbm.xml中的配置和级联操作
    一方customer
    <set name="orders">
        <key column="customer_id"></key>  //外键
        <one-to-many class="Order全路径"></one-to-many>
    </set>
    多方Order
    <many-to-one name="customer" class="Cutomer全路径" column="customer_id"></many-to-one>
    级联操作
    在一方的set中添加 cascade属性
        save-update   级联保存
        eg:
            Customer customer  = new Customer();
            Order order1 = new Order();
            Order order2 = new Order();
            customer.getOrders().add(order1);
            customer.getOrders().add(order2);
            order1.setCustomer(customer);
            order2.setCustomer(customer);
            session.save(customer);
            
        注意 双向关联时 如果没有添加inverse=true。则一方也会维护外键,针对每条order记录进行update操作,这样会影响性能。所以在一方添加inverse=true
        当做级联保存时,要添加双向关联,否则添加一方时,多方外键将为null。
        
        delete             级联删除
        eg:
            Customer customer  = session.get(Customer.class,1);
            session.delete(customer);
        delete-orphan   删除孤儿   不使用delete,而是将多的一方从set集合中移除。
        eg:
            Customer customer  = session.get(Customer.class,1);
            Order order1 = session.get(Order.class,1);
            customer.getOrders().remove(order1);
        all   = save-update+delete
        all-delete-orphan = all+ delete-orphan
        
八 注解开发
    1po基本配置
    类
    @Entity
    @Table(name="表名")
    属性
        主键
        @Id
        @generatedValue(strategy)  不配置strategy默认是native  也可以指定strategy=generationType.identity
        @column 普通列 也可以不写
            @Temporal(TemporalType.timestamp) 可以用来给date属性添加注解 data  time datetime  与mysql类似。
        @Transient 属性不出现表字段中
    所有的注解配置,在hibernate.cfg.xml中都需要通过mapping class 来引入类。
        
    2 一对多配置
     一方
     @onetomany   targetentity=  mapedby=  orphra=true 指定删除孤儿的cascade
     @cascade
     多方
     @manytoone  targetclass=  
     @joincolumn 指定外键
     
    3 多对多配置
    A方
    假设A方放弃外键维护
    @mangtomany(targetclass B方class  mappedby 另一方对本方的引用)
    @cascade(只能指定save-update)
    B方
    维护外键
    @manytomany(tragetclass 一方的class )
    @jointable(name=“中间表名”joincolumns={本方在中间表的外键} inversejoincolumn={对方在中间表的外键})
   
    4 一对一配置  唯一外键方式 可以想象成一对多
    A方
    假设A方放弃外键维护
    @onetoone(targetclass=B方class mappedby=B方对本方的引用)
    @cascade() 用hibernate的cascade 。 cascade添加在一方。
    B方
    @onetoone(targetclass=A方class)
    @joincolumn(指定外键)
   
九 5种查询
    oid     get() 立即查询 load()  延迟查询
    hql
        
        1 查询所有   from Student      list
        2 分页查询   from Student    setfirstresult begin记录索引从0开始   setmaxresults 设置每页显示多少行。  list
        3 条件查询   
            A from Student where name=?   setParameter(0,xxx)   索引从0开始 与jdbc的preparestement不同jdbc中从1开始。 list
            B from Student where name=:name  setParameter("name",xxx)   list
            如果能确定返回一条记录。 则可以不使用list 而使用uniqueResult
            排序
            分组
        4查询指定列(投影查询)
            1 在student类中给出Student(name)构造和无参数构造;
            2 select new Student(name) from Student
            3 list
        5 命名查询
            在hbm.xml中添加query
            <query name="">
            hql
            </query>
            session.getnamedquery(query的名字)
            
    qbc
        1 查询所有   createcriteria(Student.class)    list
        2 分页查询   createcriteria(Student.class)    setfirstresult begin记录索引从0开始   setmaxresults 设置每页显示多少行。  list
        3 条件查询   
            > createcriteria(Student.class)   add(Restrictions.eq("name","zhangshan"))    list
            Restrictions.and(Restrictions.eq(),Restrictions.eq())
            排序 criteria.addOrder(Order.desc("xxxx"));
            分组 criteria.setProjection(Projections.projectlist().add(Projections.sum("money")).add(Projections.groupproperty("c")));
            如果能确定返回一条记录。 则可以不使用list 而使用uniqueResult
        4 离线查询
            在action中创建detachedcriteria
            detachedcriteria dc  = DetachedCriteria.forclass(Student.class);
            //添加条件
            在dao中动态获取
            Criteria c = dc.getExecutableCriteria(session)
    对象导航
    本地sql
     createsqlquery(String sql)   addEntity(Student.class)
     
十 多表查询及hibernate优化
   1 sql中多表查询复习
   2 hql中多表查询
           迫切内连接  select distinct c from Customer c  inner join fetch c.orders where xx
           迫切左外连接 select distinct c  from Customer c  left join fetch c.orders where xx
           迫切连接查询的出的是已经封装好的对象 , 同时如果查询的是一方数据需要注意去重。
    3 事务的复习
    4 hibernate中通过getcurrentsession来保证session是同一个对象,用于事务操作。底层通过threadlocal来实现。
    5 hibernate优化
            一级缓存优化
                批量操作时,手动清除缓存
            查询策略(用默认的就行,默认都是延迟加载和单表查询)
                 A 类级别上的     
                @Proxy(lazy=false/true)   默认是true即延迟加载  比如load 延迟加载返回的是一个cglib生成的代理对象,只有主键标识,其它数据都为null。
                通过hibernate.initalize(xxx) 来初始化一个代理对象 在spring中通过OpenSessionInViewFilter来解决延迟加载问题
                B 关联级别     
                   查询到某个对象,获得其关联的对象或属性,这种称为关联级别检索。
                    在一方的set集合上配置
                       @fetch(select,subselect,join) 表示关联查询的sql语句形式。 默认是select
                       @lazycollection(true,false,extra)  extra表示及其懒惰  默认是true
                   在多方的一方对象引用上配置
                      @fetch(select,join)  默认select
                      @lazytoone(false,proxy ) proxy 默认值 是否采用延迟,需要另一方的类级别延迟策略来决定
                   n+1问题

0 个回复

您需要登录后才可以回帖 登录 | 加入黑马