框架

Hibernate

2017-10-23  本文已影响0人  AntiGravity

理解

一、Hibernate是对JDBC进一步封装
原来没有使用Hibernate做持久层开发时,存在很多冗余,如:各种JDBC语句,connection的管理,所以出现了Hibernate把JDBC封装了一下,我们不用操作数据,直接操作它就行了。

二、我们再从分层的角度来看
我们知道非常典型的三层架构:表示层,业务层,还有持久层。Hiberante也是持久层的框架,而且持久层的框架还有很多,比如:IBatis,Nhibernate,JDO,OJB,EJB等等。

三、Hibernate是开源的一个ORM(对象关系映射)框架。
ORM,即Object-Relational Mapping,它的作用就是在关系型数据库和对象之间做了一个映射。从对象(Object)映射到关系(Relation),再从关系映射到对象。这样,我们在操作数据库的时候,不需要再去和复杂SQL打交道,只要像操作对象一样操作它就可以了(把关系数据库的字段在内存中映射成对象的属性)。

总结:省略了mybatis中需要写的mapper文件,但同时由于每次操作需要生成一句sql语句,所以不适合大量数据的使用。

使用

1. maven依赖

org.hibernate – hibernate-core
org.hibernate.javax.persistence – hibernate-jpa-2.1-api
org.hibernate.common – hibernate-commons-annotation
com.fasterxml - classmate
org.apache.geronimo.specs – geronimo-annotations_1.0_spec
org.jboss – jandex
org.jboss.logging – jboss-logging
jboss - javassist

2. 配置文件(hibernate.cfg.xml)

<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
    <session-factory>
        <!-- 四大参数 -->
        <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver(驱动)</property>
        <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/hibernate(数据库)</property>
        <property name="hibernate.connection.username">用户名</property>
        <property name="hibernate.connection.password">密码</property>
        <!-- SQL 方言 ,注意使用MySQLInnoDBDialect,才可以使用Innodb引擎-->
        <property name="dialect">org.hibernate.dialect.MySQL5InnoDBDialect</property>
        <!-- 打印出sql -->
        <property name="show_sql">true</property>       
        <!-- 格式化sql -->
        <property name="format_sql">true</property>
        <!-- 有表更新表,没有表自动创建表 -->
        <property name="hbm2ddl.auto">update</property>     
        <!-- 加载映射文件 -->
        <mapping resource="xml文件路径"/>或
        <mapping class="类路径"/>
    </session-factory>
</hibernate-configuration>

3. 实体类写法

  1. xml配置文件
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">  
<hibernate-mapping>
    <class name="com.hibernate.entity.User" table="user">
        <id name="uid" column="uid">
            <!-- 使用数据库默认的生成主键的方案 -->
            <generator class="native"/>
        </id>
        <property name="username" column="username"/>
        <property name="password" column="password"/>
    </class>
</hibernate-mapping>
  1. JPA

什么是JPA?
Java Persistence API,Java在持久层的一套接口,与JDBC接口类似,提供一套规范,有其他数据库厂商去实现。Hibernate实现了JPA接口。


注解在实体类的使用:
@Entity //表示该类为持久化类
@Table(name="user") //对应数据库的表名,默认为类名小写
public class User {
    @Id //主键
    @GeneratedValue(strategy=GenerationType.IDENTITY)//主键生成策略 IDENTITY与native类似,默认为auto
    private Integer uid;
    @Column(name="user_name") //设置属性名与字段名的映射关系,默认同属性名
    private String username;
    private String password; //如果属性名与字段名一致,可以不写注解
    @OneToMany(cascade=CascadeType.ALL) //一对多,casacde为级联
    @JoinColumn(name="外键名") //外键
    private Set<Customer> custSet = new HashSet<>();
    @ManyToMany(cascade=CascadeType.ALL,fetch=FetchType.LAZY)//多对多,懒加载
    @JoinTable(//生成第三张表
            name="user_role",//表名如双向则两个类中设置为一样
            joinColumns={@JoinColumn(name="uid")},//本表中的主键
            inverseJoinColumns={@JoinColumn(name="rid")}//另一张表的主键
    )
    private Set<Role> roleSet = new HashSet<>();
}

4. SESSION查用API

save、delete、update、get、load
延迟查询:如果使用了对象中非id的属性时才会发送sql语句
saveOrUpdate
瞬时态执行save(),游离态执行update()
merge
两个相同id的对象合并

5. 实体类的三种状态

状态转换原理图

6. 测试

    Configuration configure = new Configuration().configure("hibernate.cfg.xml");//如果配置文件名如此写法,可以省略
    SessionFactory factory = configure.buildSessionFactory();
    Session session = factory.openSession();// 获取连接
    // 除查询外,更新、删除、添加均需开启事务
    Transaction tx = session.beginTransaction();
    User user = new User("Steve", "666");
    session.save(user);
    tx.commit();// 提交事务
    session.close();// 关闭连接

增强

1. hql查询

// ---------------占位符条件查询------------------
    // 占位符条件查询 ?
    public void test3() {
        String hql = "from User u where u.username=? and u.password=?";
        Query<User> query = session.createQuery(hql);
        query.setParameter(0, "lisi");
        query.setParameter(1, "123");
        User u = query.uniqueResult();
        System.out.println(u);
    }
    // 命名占位符条件查询1 parameter
    public void test4() {
        String hql = "from User where username=:username and password=:password";
        Query<User> query = session.createQuery(hql);
        query.setParameter("username", "lisi");
        query.setParameter("password", "123");
        User u = query.uniqueResult();
        System.out.println(u);
    }
    // 命名占位符条件查询2 javabean或map
    public void test5() {
        String hql = "from User where username=:username and password=:password";
        Query<User> query = session.createQuery(hql);
        User user = new User("lisi", "123");
        query.setProperties(user);
        User u = query.uniqueResult();
    }
    // 迫切内连接,直接封装成对象 查询custid=1的用户
    public void test12() {
        String hql = "from User u inner join fetch u.custSet c where c.custid=1";
        Query<User> query = session.createQuery(hql);
        List<User> list = query.getResultList();
    }
其他查询

SQLQuery
Criteria

2. 二级缓存

Hibernate中的二级缓存是属于SessionFactory级别的缓存机制。第一级别的缓存是Session级别的缓存,是属于事务范围的缓存,由Hibernate管理,一般无需进行干预。第二级别的缓存是SessionFactory级别的缓存,是属于进程范围的缓存。
二级缓存也分为了两种:

  1. 内置缓存:Hibernate自带的,不可卸载,通常在Hibernate的初始化阶段,Hibernate会把映射元数据和预定义的SQL语句放置到SessionFactory的缓存中。该内置缓存是只读的。
  2. 外置缓存:通常说的二级缓存也就是外置缓存,在默认情况下SessionFactory不会启用这个缓存插件,外置缓存中的数据是数据库数据的复制,外置缓存的物理介质可以是内存或者硬盘。
Hibernate二级缓存结构
依赖

org.hibernate – hibernate-ehcache
net.sf.ehcache – ehcache-core

配置文件
<ehcache>  
      <!--
      指定二级缓存存放在磁盘上的位置,可以使用磁盘目录
        也可以使用Java System Property目录
        user.home是用户目录
        user.dir是用户当前工作目录
        java.io.tmpdir是默认临时文件路径

        name:Cache的唯一标识。
        maxElementsInMemory:内存中最大缓存对象数。
        eternal:Element是否永久有效,一旦设置true,timeout将不起作用。
        timeToIdleSeconds:设置Element在失效前的允许闲置时间。仅当element不是永久有效时使用,可选属性,默认值是0,也就是可闲置时间无穷大。
        timeToLiveSeconds:设置Element在失效前允许存活时间。最大时间介于创建时间和失效时间之间。仅当element不是永久有效时使用,默认是0.,也就是element存活时间无穷大。
        overflowToDisk:配置此属性,当内存中Element数量达到maxElementsInMemory时,Ehcache将会Element写到磁盘中。
        maxElementsOnDisk:磁盘中最大缓存对象数,若是0表示无穷大。
        memoryStoreEvictionPolicy:当达到maxElementsInMemory限制时,Ehcache将会根据指定的策略
        去清理缓存中的内容。默认策略是LRU(最近最少使用),你也可以设置为FIFO(先进先出)或是LFU(较少使用)
      -->
    <diskStore path="java.io.tmpdir/cache"/>
    <defaultCache
            maxElementsInMemory="10000"
            eternal="false"
            timeToIdleSeconds="120"
            timeToLiveSeconds="120"
            overflowToDisk="true"
    />
    <!--可以给每个实体类指定一个配置文件,通过name属性指定,要使用类的全名-->
    <!--<cache name="com.teemo.entity.User"-->
    <!--maxElementsInMemory="10000"-->
    <!--eternal="false"-->
    <!--timeToIdleSeconds="300"-->
    <!--timeToLiveSeconds="600"-->
    <!--overflowToDisk="true"-->
    <!--/>-->
    <cache name="simple"
           maxElementsInMemory="1000"
           eternal="true"
           timeToIdleSeconds="0"
           timeToLiveSeconds="0"
           overflowToDisk="false"
    />
</ehcache>
在spring-hibernate.xml中的配置
<!-- 开启二级缓存:根据id来查询 -->
<prop key="hibernate.cache.use_second_level_cache">true</prop>
<!-- 开启查询缓存:根据非id来查询,需要在query中设置setCacheable(true) -->
<prop key="hibernate.cache.use_query_cache">true</prop>
<!-- 高速缓存提供程序 -->
<prop key="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory</prop>
在需要使用二级缓存的类上添加注解

@org.hibernate.annotations.Cache(region ="simple",usage = CacheConcurrencyStrategy.READ_ONLY)

补充:http://www.cnblogs.com/whgk/p/6103038.html

上一篇下一篇

猜你喜欢

热点阅读