Hibernate--核心配置

核心API:
 PO对象:Persistent Objects,持久对象,hibernate用于操作持久对象的,每一个持久对象都具有一个映射文件
 VO value object 值对象,一般用于web层
 BO business object 业务对象,一般用于service层
 PO 持久对象,一般用于dao层
---综合的称呼:JavaBean
 OID:每一个PO对象有存在一个唯一标识,是hibernate用于区分PO对象的。
 Java区分对象:地址不同,如果new两个对象,java不同的。
 hibernate po对象:使用OID进行区分的,及时new两个对象,只要OID值相同,hibernate认为是一个对象。
 OID用于存表中主键值的。

核心配置文件:
hibernate.cfg.xml ,xml文件可以配置更多内容。
hibernate.properties ,内容必须是k/v,且key不能重复。一般不使用。
 参考文件:\hibernate-distribution-3.6.10.Final\project\etc\ hibernate.properties
Configuration:构造方法:new Configuration() ,将自动加载hibernate.properties文件
加载配置主配置文件方法
 configure() 用于加载src下的 hibernate.cfg.xml ,【常用】;configure(String )  可以加载指定位置下的,自定义主配置文件
加载映射文件方法
config.addResource(“booming/xxx.hbm.xml”) 加载xml文件;config.addClass(User.class) 加载类对应xml文件
注意:hibernate.cfg.xml  <mapping>  、addResource 、addClass 三个只能使用一个。
代码:
//1 加载配置文件
  Configuration config = new Configuration().configure();
  // * 如果hibernate.cfg.xml 配置 <mapping> 一并加载了映射文件。
  // * 没有配置映射,需要手动加载
  // 方式1:加载xml配置文件,等价 <mapping resource="cn/xxx/a_hello/User.hbm.xml"/>
  //config.addResource("cn/xxx/a_hello/User.hbm.xml");
  // 方式2:加载指定类对应的映射
  config.addClass(User.class);

SessionFactory:
Configuration对象根据当前的配置信息生成 SessionFactory对象
SessionFactory 对象中保存了当前的数据库配置信息和所有映射关系以及预定义的SQL语句
SessionFactory 对象是线程安全的。会话工厂给hibernate提供会话(连接),之后sessionfactory使用只需要提供一个实例。线程安全不存在线程并发访问问题。(底层使用ThreadLocal 在线程之间共享数据的)
一般情况下,为了保证整个程序只有一个工厂,提供工具类用于初始化工厂。

Session:
相当于JDBC中的Connection连接。
Session 是应用程序与数据库之间交互操作的一个单线程对象,是 Hibernate 运作的中心
Session是线程不安全的,存在线程并发访问问题。【避免使用成员变量】。
所有持久化对象PO必须在 session 的管理下才可以进行持久化操作
 PO对象只有跟session绑定,才有PO对象特点。
Session 对象有一个一级缓存,用于缓存PO对象。
方式1:openSession() 新的会话
  Configuration config = new Configuration().configure();
  SessionFactory factory =config.buildSessionFactory();
  // 方式1:打开一个新的会话Session
  Session session = factory.openSession();
  Session session2 = factory.openSession();
  System.out.println(session == session2);//false
方式2:getCurrentSession() 获得本地线程需要将session绑定到本地线程
 Configuration config = new Configuration().configure();
  SessionFactory factory =config.buildSessionFactory();
  //方式2:获得本地线程中绑定session (在一个线程中共享session)
  // * 注意:如果要使用 getCurrentSession()必须在hibernate.cfg.xml 配置
  Session session = factory.getCurrentSession();
  Session session2 = factory.getCurrentSession();
  System.out.println(session == session2); //true
hibernate.cfg.xml配置:
<!-- 将session绑定到本地线程,写法固定-->
<property name="hibernate.current_session_context_class">thread</property>
session 需要关闭的,session.close();

Transaction:
开启事务:conn.setAutoCommit(false);
 提交事务:conn.commit()
 回滚事务:conn.rollback();
代表数据库操作的事务对象

提交事务的方式:
提供变量:
Configuration config = new Configuration().configure();
  SessionFactory factory =config.buildSessionFactory();
  Session session = factory.openSession();
  //开启事务
  Transaction transaction = session.beginTransaction();
  //提交事务
  transaction.commit();
  //或 回滚事务
  //transaction.rollback();
  session.close();
使用getTransaction()方法:
Configuration config = new Configuration().configure();
  SessionFactory factory =config.buildSessionFactory();
  Session session = factory.openSession();
  try {
   //开启事务
   session.beginTransaction();  
   //.........
   //提交事务
   session.getTransaction().commit();
  } catch (Exception e) {
   //回顾
   session.getTransaction().rollback();
  }
  session.close();
增删改查:
save() 保存
update() 更新
saveOrUpdate(...)  保存或更新
delete 删除
get 通过id查询
createQuery(...).list() 查询所有
Session session = factory.openSession();
  session.beginTransaction();
  
  // * createQuery("hql语句")
  // * hql语句:hibernate query language ,hibernate查询语句,面向对象查询语句
  // ** 与sql语句对比:hql使用类名和属性名称,sql使用 表名和字段名。
  // ** 注意:默认情况类的属性名 和表的字段 一样。
  Query query = session.createQuery("from User");
  //查询所有
  List<User> allUser = query.list();
  for (User user : allUser) {
   System.out.println(user);
  }
  session.getTransaction().commit();
  session.close();
分页
query.setFirstResult()
query.setMaxResults()
Session session = factory.openSession();
  session.beginTransaction();
  //分页
  // * mysql --> select ... from   limit 开始索引,每页显示个数
  Query query = session.createQuery("from User");
  // ** 设置分页数据 -- 第一页
  // 1)开始索引
  query.setFirstResult(2);  //第一页 0 , 第二页2
  // 2)每页显示个数
  query.setMaxResults(2);  //第一页 2 , 第二页2
  List<User> allUser = query.list();
  for (User user : allUser) {
   System.out.println(user);
  }
  session.getTransaction().commit();
  session.close();
qbc:session.createCriteria(User.class).list()
Session session = factory.openSession();
  session.beginTransaction();
  //QBC : query by criteria , hibernate提供纯面向对象查询方式。
  // * Criteria 和 Query 提供api相同的
  Criteria criteria = session.createCriteria(User.class);
  criteria.setFirstResult(0);
  criteria.setMaxResults(2);
  List<User> allUser = criteria.list();
  for (User user : allUser) {
   System.out.println(user);
  }
  session.getTransaction().commit();
  session.close();

主配置文件详解:
<session-factory>
  <!-- 1.基本4项 -->
  <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
  <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/h_day01_db</property>
  <property name="hibernate.connection.username">root</property>
  <property name="hibernate.connection.password">1234</property>
  
  <!-- 2 将session绑定到本地线程 -->
  <property name="hibernate.current_session_context_class">thread</property>
  
  <!-- 3 方言 , 方言 + 映射文件 提供hibernate如何生存sql语句 (查询语句)
   * 配置的方言就是hibernate不同的实现类 hibernate3.jar/org/hibernate/dialect
  -->
  <property name="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</property>
  
  <!-- 4 sql显示,格式化 -->
  <property name="hibernate.show_sql">true</property>
  <property name="hibernate.format_sql">true</property>
  
  <!-- 5 如何生成表,由hibernate自动创建。
   在学习中使用,开发不用。开发时先创建表,然后编写配置hbm文件
    create-drop , 运行程序时,先删除表在创建表,程序结束时,如果调用factory.close()将自动删除表。[测试]
    create , 运行程序时,先删除表在创建表,程序结束时,表不删除。【】
    update , 如果表不存在将创建表,如果表存在将更新表。只负责添加,不负责删除。【】
    validate,程序运行开始时,检查配置文件hbm 和 表字段 是否匹配,如果匹配正常运行。如果不匹配将抛异常。[测试]
  -->
  <property name="hibernate.hbm2ddl.auto">update</property>
  <!-- 6 取消bean校验:如果使用web6.0项目,右键运行程序时将抛异常(空指针,提示:没有bean校验工厂) -->
  <property name="javax.persistence.validation.mode">none</property>
  <!-- 必须将映射文件添加到主配置文件中 -->
  <mapping resource="cn/xxx/a_hello/User.hbm.xml"/>
 </session-factory>
持久对象的配置:
<!--
  <hibernate-mapping>
   package 用于确定包
    <hibernate-mapping package="cn.xxx.e_hbm">
     <class name="Person" table="t_person">
  <class> 配置 类 和表 之间关系
   name: 类名称
    一般使用类的全限定名称
    如果根标签配置package,此处可以使用简单类名
   table: 表名称
  <property> 普通属性配置
   name : 属性名(getter)
   column :表中列名。如果没有写默认值name的值
   length:列长度。默认值:255
   type:类型
    1)hibernate类型:string/integer等
     date 日期
     time 时间
     timestamp 时间戳 (当前记录修改了,时间自动更改)
    2)java类型:java.lang.String 等
    3)mysql类型:varchar(50)
     <property name="pname" length="50">
      <column name="name" sql-type="varchar(50)"></column>
     </property>
   not-null : 是否非空
   unique : 是否唯一
   access : hibernate使用javabean的属性还是字段,默认:属性。(了解)
    取值:field、property
 
  -->
 <class name="cn.xxx.e_hbm.Person" table="t_person">
  <!-- 配置主键 -->
  <id name="pid">
   <!-- 主键生成策略 -->
   <generator class="native"></generator>
  </id>
  <!-- 普通属性 -->
  <property name="pname" column="name" length="50" type="string" not-null="true" unique="true"></property>
  <property name="gender"></property>
  <property name="birthday">
   <!-- datetime 为数据库类型,java没有对应类型 -->
   <column name="birthday" sql-type="datetime"></column>
  </property>
  <property name="photo" type="binary" length="400000"></property>
  <property name="desc" column="`desc`"></property>
 </class>

主键生成策略:
配置给hibernate 让hibernate维护PO对象的OID的值。
主键分类:代理主键、自然主键
 代理主键:由hibernate 自动生成 或 hibernate通过数据库获得,hibernate设置给PO对象的。
 自然主键:由程序(开发人员)手动维护。要求掌握:native、uuid、assigned
<!--
  <id> 用于配置主键
   name="bid" oid属性名
   column=""  列名
   length=""  长度
   type=""  类型
   access="" 访问方式:字段或属性
  <generator class=""> 用于配置主键生成策略
   1)increment 由hibernate自己通过先查询(select max(pid)...),累加1方式,进行增长。
    存在线程并发访问问题
    <generator class="increment"></generator>
   2)identity hibernate 采用数据库底层的自动增长
    mysql 自动增长列 auto_increment ,不存在线程并发访问问题
   3)sequence hibernate 采用数据库底层的序列
    oracle 使用序列
   4)hilo (high low ) 高低位算法,hibernate采用算法方式维护id(了解)
    table :表名
    column:列名
    max_lo:一次操作数
    <generator class="hilo">
                 <param name="table">hi_value</param>
                 <param name="column">next_value</param>
                 <param name="max_lo">100</param>
          </generator>
         5)native 根据底层数据库的能力选择 identity、sequence 或者 hilo 中的一个。【掌握】
         ########### 以上操作id类型必须是:整型 long, short 或者 【int】
         6)uuid 随机字符串,类型必须是String
          <generator class="uuid"></generator>
         ########### 以上 代理主键
         7)assigned 自然主键,需要手动设置id值
  -->
 <class name="cn.xxx.f_generator.Book" table="t_book">
  <id name="bid">
   <generator class="assigned"></generator>
  </id>
  <property name="title"></property>
 </class>

PO对象状态
三种状态
transient 瞬时态:session 没有缓存对象,数据库中没有对应数据。例如:new User();OID 没有值
persistent 持久态:session缓存对象,数据库最终会有。例如:save(user)  ;OID值
detached 脱管态:session没有缓存对象,数据库有。;OID值
网络其他称呼:临时态、托管态、游离态、删除态
状态转换
瞬时态
瞬时态 --> 持久态 ,save() 或 saveOrUpdate()   --> 录入 insert语句
瞬时态 --> 脱管态 ,手动设置OID
 如果手动设置OID,但数据库对应值不存在,仍认为脱管,只是欺骗hibernate,相应的操作中将抛异常。
持久态
持久态 --> 瞬时态,官方规定执行delete()
持久态 --> 脱管态,与session脱离关系即可
 session.close()  关闭
 session.clear() 清空所有
 session.evict(...) 清空指定对象
脱管态
脱管态 --> 瞬时态 , 手动删除OID
脱管态 --> 持久态 ,update() 或 saveOrUpdate() --> 更新update语句

猜你喜欢

转载自jackpot1234.iteye.com/blog/2316537
今日推荐