给同事做的Hibernate4.2 注解映射以及缓存培训教程及例子

前几天给team同事准备了spring mvc 的基础讲解, 这几天继续给他们做 Hibernate 4.2 用注解编程的方式,因为用XML配置的方式都有些基础,而且在现在的项目开发中用XML 配置方式越来越少,用注解越来越多,所以就常见的一些mapping 关系做了讲解, 并用例子详细介绍了二级缓存的使用. 主要内容如下:

Hibernate 关系映射主要内容
1. hibernate 一对一单向外键关联
2. hibernate 一对一双向外键关联
3. 一对多单向关联
4. 多对一单向关联
5. 一对多或者多对一双向关联
6. 多对多单向关联
7. 多多多双向关联.
对于 Hibernate 来说,常见的映射关系就是上面的7中关系,但对于数据库来说,其实就只有一种关系--外键关联. 另外 Hibernate 一对一还有主键关联方式,但几乎没被用过,所以略去不讲。

例子所需要的jar 包
对于所有的工程均提供源码下载, 至于jar 包,可以到官方下载,其中有用到mysql 所以还得需要mysql-connector 这个jar 包。

如何使用 Hibernate mapping 关系的这些例子
1. 首先配置 hibernate.cfg.xml 文件,特别是基于注解的方式要用 <mapping class="com.training.hibernate...."/> 方式。这里是实体类配置.一个配置例子如下:
程序代码 程序代码

<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

<hibernate-configuration>
    <session-factory>        
        <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="connection.url">jdbc:mysql://localhost/hibernate</property>
        <property name="connection.username">root</property>
        <property name="connection.password"></property>
        <property name="dialect">org.hibernate.dialect.MySQLDialect</property>      
        <!-- Enable Hibernate's automatic session context management -->
        <property name="current_session_context_class">thread</property>
        <!-- Disable the second-level cache  -->
        <property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>
        <!-- Echo all executed SQL to stdout -->
        <property name="show_sql">true</property>
        <property name="format_sql">true</property>
        <mapping class="com.training.hibernate.Husband"/>
        <mapping class="com.training.hibernate.Wife"/>        
    </session-factory>
</hibernate-configuration>

注意修改里面的数据库连接。

2. 所有的例子均用junit test 做测试。测试的代码都在test 源码目录下, 首先应运行:generateSchema 方法,这个方法自动根据mapping 的实体类生成数据库表. 先有对象再有表,OOD 的设计思想,虽然不一定适合所有情况,但演示这么做确实很好。

3. 运行 generateData() 方法,这是用来生成测试数据用的方法,生成数据之后,就可以运行其他junit test 方法了。

Hibernate 关系映射关系总结
1.  注意所有的单向关联,基本都用到@JoinColumn 注解,指明外键关联的字段(数据库中的字段,不是属性), 如果不用@JoinColumn, 会有关联表出现,但如果不是多对多关联这个表示冗余的,所以一般用@JoinColumn。比如:
程序代码 程序代码

@ManyToOne(cascade={CascadeType.ALL})    
    @JoinColumn(name = "departmentId")
    public Department getDepartment() {
        return department;
    }

那么在这个实体类对应的表中,会有一个departmentId的字段作为外键关联.

2. 如果是双向关联,可以确定的说,都会用到 mappedBy="xxx", 这里的 "xxx" 表示由另一个对象的属性所隐射了。比如:
程序代码 程序代码

在一个实体类中这样定义:
private Department department;
....
@ManyToOne(cascade={CascadeType.ALL})    
    @JoinColumn(name = "departmentId")
    public Department getDepartment() {
        return department;
    }
那么在另外一个实体类中,就只需要这样了:
private Set<User> users = new HashSet<User>();
.....
@OneToMany(mappedBy = "department",cascade={CascadeType.ALL})    
    public Set<User> getUsers() {
        return users;
    }


3. 如果是多对多关系,必须用到第三张表来作为关联关系的映射表. 这是会用@JoinTable来注解:
比如 :
程序代码 程序代码

private Set<Student> students = new HashSet<Student>();
.....
@ManyToMany
    @JoinTable(name="teacher_student",
        joinColumns={@JoinColumn(name="teacherId")},
        inverseJoinColumns={@JoinColumn(name="studentId")}
        )
    public Set<Student> getStudents() {
        return students;
    }
另一个关联对象,如果需要双向关联的话就用如下配置:
private Set<Teacher> teachers = new HashSet<Teacher>();
    ....
    @ManyToMany(mappedBy="students")
    public Set<Teacher> getTeachers() {
        return teachers;
    }
    

这个时候会用第三张表 teacher_student 来记录 两个表的关联关系, 这个第三张表中的字段分别由joinColumns,inverseJoinColumns 来做对应。

4. 使用二级缓存. 首先得开启二级缓存,并配置好hibernate 配置文件.
程序代码 程序代码

<!-- Disable the second-level cache  
        <property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>
        -->
        
        <property name="hibernate.cache.use_second_level_cache">true</property>
        <property name="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</property>
        <property name="hibernate.cache.use_query_cache">true</property>
        <property name="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory</property>

这里用到 EHCache , 还得有ehcache 的配置
程序代码 程序代码

<ehcache>
<diskStore path="java.io.tmpdir"/>
<defaultCache
        maxElementsInMemory="10000"
        eternal="false"
        timeToIdleSeconds="120"
        timeToLiveSeconds="1200"
        overflowToDisk="true"
        />
[/ehcache>


最重要的,还得在实体类上面加上类似如下的注解:
程序代码 程序代码

@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)

这样,就会对这个实体类的内容缓存下来. Hibernate 二级缓存,应该也是对应于一个类似于hashmap一样的东西,每个缓存的对象都有一个ID, 只有这个ID 存在才能在二级缓存中获取到,对于查询也一样,一定要查询条件完全相同才能生效,有例子在代码中.

所有例子下载:
下载文件 one to on 单向外键关联
下载文件 one to one 双向外键关联
下载文件 many to one 单向关联
下载文件 one to many 单向关联
下载文件 one to many and many to one 双向关联
下载文件 many to many 单向关联
下载文件 many to many 双向关联
下载文件 Hibernate level2 cache


除非申明,文章均为一号门原创,转载请注明本文地址,谢谢!
[本日志由 轻舞肥羊 于 2014-04-08 09:21 PM 编辑]
文章来自: 本站原创
引用通告: 查看所有引用 | 我要引用此文章
Tags: hibernate annotation
相关日志:
评论: 0 | 引用: 0 | 查看次数: -
发表评论
昵 称:
密 码: 游客发言不需要密码.
内 容:
验证码: 验证码
选 项:
虽然发表评论不用注册,但是为了保护您的发言权,建议您注册帐号.