hibernate

作者: 无聊新生 | 来源:发表于2017-08-21 19:14 被阅读0次

Hibernate开发步骤搭建

  • 1、导入相关jar包(Hibernate压缩包 > lib包 > required包下所有的jar,外加log4j.jar和数据库驱动包)
1.png
  • 2、编写映射文件描述类与数据库表之间的关系

    • 引入dtd约束(Hibernate压缩包 > project > etc文件下有)
    <!DOCTYPE hibernate-mapping PUBLIC
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
    
    • 映射文件推荐命名规则:类名.hbm.xml
  • 3、编写核心配置文件(位置在src下,名字叫做 hibernate.cfg.xml)

    • 引入核心配置文件dtd约束
    <!DOCTYPE hibernate-configuration PUBLIC
    "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
    
    • 配置数据库连接信息
        <!-- 配置连接数据库信息 -->
        <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="hibernate.connection.url">jdbc:mysql:///db_hibernate?useUnicode=true&characterEncoding=utf-8</property>
        <property name="hibernate.connection.username">root</property>
        <property name="hibernate.connection.password"></property>
    
    • 配置数据库方言(方言同时设置数据的存储引擎,指定引擎为InnoDB,不指定外键不能用)
        <!-- 是否开启mysql数据库方言,同时指定表的存储引擎 -->
        <property name="hibernate.dialect">org.hibernate.dialect.MySQLInnoDBDialect</property>  
    
    • 配置其他选配信息
        <!-- 显示执行的SQL语句,并对SQL语句格式进行设置 -->
        <property name="show_sql">true</property>
        <property name="format_sql">true</property>
        <!-- 自动更新表结构  -->
        <property name="hbm2ddl.auto">update</property>
    
    • 引入映射文件
        <!-- 引入映射配置文件 -->
        <mapping resource="com/wzw/bean/User.hbm.xml"/>
    

配置映射文件

配置实体类与数据表的联系

    ``` xml
    <class name="com.wzw.bean.User" table="tb_user">类与表的描述信息</class>
    ```

配置主键(hibernate要求实体类里面有一个属性作为唯一值,对应主键,主键可以有不同的生成策略)

    ``` xml
        <!-- 配置主键  -->
        <id name="id" column="tb_id">
            <!-- 配置主键生成策略 -->
            <generator class="native"></generator>
        </id>
    ```

    注意:主键生成策略(generator标签):native(根据本地数据库支持主键生成方式)、uuid(根据uuid算法生成一个32位16进制的字符串,推荐使用)

配置实体类属性与数据表字段的对应关系

    - 实体类属性与数据表字段可以使用<column>标签进行配置

    ``` xml
        <property name="username">
            <column name="tb_username"></column>
        </property>
    ```

    - 列名可以不写,默认和实体类名字段一样

    ``` xml
    <property name="username"></property>
    ```

    - type可以不写,默认和实体字段属性一致

    ``` xml
    <property name="username" column="tb_username" type="java.lang.String"></property>
    ```

    - length设置数据表中对应字段的长度,默认进行设置

    ``` xml
    <property name="username" column="tb_username" length="10"></property>
    ```

    - 普通方式配置实体类属性与数据表字段的关系

    ``` xml
    <property name="username" column="tb_username"></property>
    ```

使用Hibernate API操作

操作的主体流程

// 创建Configuration(hibernate包下)对象
        Configuration configuration = new Configuration();
        // 加载配置文件
        configuration.configure();
        // 得到SessionFactory对象
        SessionFactory sessionFactory = configuration.buildSessionFactory();
        // 得到session对象
        Session session = sessionFactory.openSession();
        // 开启事务
        Transaction transaction = session.beginTransaction();
        try {
            /*进行crud操作*/
            transaction.commit();
        } catch (Exception e) {
            if (transaction != null) {
                // 回滚事务
                transaction.rollback();
            }
            e.printStackTrace();
        } finally {
            // 释放session
            session.close();
            sessionFactory.close();
        }

实体类的三种状态

1、瞬时态:缓存中不存在,数据库中也不存在(不含有id与session无关)

2、持久态:缓存中存在,数据库中也存在(含有id,与session有关)

3、游离态(托管态):缓存中不存在,数据库中存在(含有id,与session无关)

hibernate缓存

  • hibernate缓存的作用

    1、数据存放到数据库里面,数据库本身是文件系统,使用流的方式操作文件效率不高

    2、把数据放入缓存中,不需要使用流的方式,可以直接读取数据

    3、再次使用相同语句进行查询时,先在缓存中查找,提高了查询效率

  • hibernate一级缓存

    1、存储的是数据而不是对象(通过id进行辨别)

    2、一级缓存使用范围是session(hibernate的session对象)

    3、默认进行开启

    特性:session一级缓存中有一个快照区,快照区保存原始的数据库信息,因此持久态实体类对象,改变对象的数据关闭缓存时自动进行更新(可以不调用update()方法)

增删改查API

  • get()是立即查询,查询出的对象是持久态
        // 向数据库中查询数据
        // 结论:get方法,立即查询(查询出的对象为持久态)
        User user = session.get(User.class, 7);
  • load()延迟查询
    // 向数据库中查询数据
    // 结论:load方法,延迟加载(查询出的对象为持久态),只有在使用查询出的对象时才进行查询,其它方面与get一样
    User user = session.load(User.class, 6);
  • save()添加
    // 向数据库中插入一条数据,返回值为插入数据的主键(save方法会把瞬时态对象变成持久态对象)
    Serializable serializable = session.save(user);
  • saveOrUpdate()添加或修改
    // 向数据库中插入一条数据,或对数据进行修改
    // 结论1:saveOrUpdate方法,如果添加的对象不含有主键属性,则与save方法执行相同(把瞬时态对象变为持久态对象)
    // 结论2:saveOrUpdate方法,如果添加的对象含有主键属性,会把对象保存到session一级缓存(相同主键值的对象保存在缓存中会报错,添加的对象进入持久态),
    // 清空缓存时session一级缓存会与一级快照区的数据进行比对,通过这种方式对数据进行修改(不管与数据库数据是否相同,都会进行修改)
    session.saveOrUpdate(user);
  • marge()添加或修改,该方法的返回值是一个持久化对象
    // 向数据库中插入一条数据,或对数据进行修改
    // 结论1:merge方法,如果添加的对象不含有主键属性,则与save方法执行相同(但是不会把瞬时态对象变为持久态对象)
    // 结论2:merge方法,如果添加的对象含有主键属性,先查询对象把对象数据放入快照区会,把传入的对象保存到session一级缓存(相同主键值的对象保存在缓存中会报错,对象不会进入持久状态),
    // 清空缓存时session一级缓存会与一级快照区的数据进行比对,通过这种方式对数据进行修改(两者相同不会进行修改)
    session.merge(user);
  • update()修改数据
    // 向数据库中修改数据
    // 结论:update方法,把传入的对象保存到session一级缓存(相同主键值的对象保存在缓存中会报错,对象进入持久状态),
    // 清空缓存时session一级缓存会与一级快照区的数据进行比对,通过这种方式对数据进行修改(两者相同不会进行修改)
    session.update(user);
  • delete()删除数据
    // 向数据库中删除数据
    // 结论:delete方法,删除一级缓存中的相应数据(不清除快照区的数据),并阻止这个对象的操作,
    // 清除缓冲区时通过缓冲区和快照区的对比进行删除
    session.delete(user);

hibernate绑定session

  • hibernate帮我们实现了与本地线程的绑定(底层还是ThreadLocal)

  • 在主配置文件中进行配置,通过sessionFactory.getCurrentSession();得到与线程绑定的session

    <!-- session与本地线程进行绑定 -->
    <property name="hibernate.current_session_context_class">thread</property>
        

相关文章

网友评论

      本文标题:hibernate

      本文链接:https://www.haomeiwen.com/subject/pudhdxtx.html