Hibernate学习

Hibernate是一个操作数据库的框架,实现了对JDBC的封装

一、Hibernate 与 C3P0+dbutils 对比

1)创建

● hibernate:

创建hibernate.cfg.xml

配置驱动,数据库url、用户名、密码

数据库的方言

● c3p0+dbutils:

c3p0连接数据库:配置驱动、数据库url、用户名、密码

dbutils操作数据库

2)添加实体

● hibernate:

需要实体与表的映射文件xxx.hbm.xml:配置属性与字段的对应,添加主键生成策略

● c3p0+dbutils:

需要实体

3)操作数据库

● hibernate:

通过session操作数据库(开启事务)

session.save操作数据库中的表

● c3p0+dbutils:

通过QueryRunner操作数据库

写sql语句操作数据库中的表

二、配置文件

1)hibernate.cfg.xml配置

● 数据库驱动、url、用户名、密码
● 方言-org.hibernate.dialect.MySQLDialect;MySQLDialect:自动生成表需要添加表的类型MySQL5InnoDBDialect
● 显示并生成SQL语句
● 配置自动生成表
● orm文件位置
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
    "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
    <!-- 负责初始化Hibernate -->
    <session-factory>
        <!-- 连接数据库驱动 -->
        <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
        <!-- 数据库地址 -->
        <property name="hibernate.connection.url"><![CDATA[jdbc:mysql://localhost:3306/hibernatelearn?useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2B8&useSSL=true]]></property>
        <!-- 数据库用户名 -->
        <property name="hibernate.connection.username">root</property>
        <!-- 数据库密码 -->
        <property name="hibernate.connection.password">123456</property>

        <!-- 配置数据库方言 -->
        <!-- <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property> -->
        <property name="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</property>
        
        <!-- 将Hibernate生成的SQL语句打印到控制台 -->
        <property name="hibernate.show_sql">true</property>
        <!-- 格式化hibernate生成的SQL语句 -->
        <property name="hibernate.format_sql">true</property>
                
        <!-- 配置hibernate自动创建表
            create:            自动创建表,每次框架运行都会创建一张新的表,原来的数据将丢失(开发)
            create-drop:    自动建表,每次框架运行结束都会将所有表删除(开发环境中测试使用)
            update(推荐):    自动生成表,如果表已经存在 则更新数据,如果表不存在 就会创建一张新的表
         -->
        <property name="hibernate.hbm2ddl.auto">update</property>
        
        <!-- 配置事务的隔离级别:
            1(0001)    读未提交:最低的隔离级别,最没用(最快)
            2(0010)    读已提交:可避免脏读,不能避免不可重复度
            4(0100)    可重复读:可以避免不可重复度,可以避免脏读(MySQL默认)
            8(1000)    串行化:最强大,三种都可以解决(最慢) 
         -->
        <property name="hibernate.connection.isolation">4</property>
        
        <!-- 配置事务(session与当前线程绑定) -->
        <property name="hibernate.current_session_context_class">thread</property>
        
        <!-- orm映射关系 -(O对象,R关系,M映射)-->
        <mapping resource="com/sikiedu/domain/User.bhm.xml"/>
        
    </session-factory>
</hibernate-configuration>
View Code

2)配置实体与表的映射文件xxx.hbm.xml

● id标签:
  name:实体中的属性
  column(可选):数据库的列名
  type(可选):填写列(属性)的类型,hibernate会自动检测实体属性的类型(每个类型有三种写法:[ java类型 | hibernate类型 | 数据库类型 ])
  length(可选):配置数据库中列的长度(默认值:使用数据库类型的最大长度)
  ◆ generator标签主键生成策略
    identity:主键自增
    sequence:Oracle中主键生成的策略
    native:identity+sequence(hibernate会根据连接的数据库自动选择(identity或sequence))
    uuid:产生随机字符串作为主键,主键必须为String
    assigned:手动指定
● property标签除了id之外的普通属性   name:实体中的属性   column(可选):数据库的列名   type(可选):填写列(属性)的类型,hibernate会自动检测实体属性的类型(每个类型有三种写法:[ java类型 | hibernate类型 | 数据库类型 ])   length(可选):配置数据库中列的长度,默认值:使用数据库类型的最大长度   not-null(可选):配置该属性(列)是否不能为空,默认值:false
<?xml version="1.0" encoding="UTF-8"?>
<!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.sikiedu.domain.User" table="user">
        <id name="id" column="id">
            <!-- 主键生成策略 -->
            <generator class="uuid"></generator>
        </id>
        <property name="username" column="username"></property>
        <property name="password" column="password"></property>
        <property name="name" column="name"></property>
        <property name="email" column="email"></property>
        <property name="telephone" column="telephone"></property>
    </class>
</hibernate-mapping>
View Code

三、API讲解

1)Configuration

// 读取hibernate.cfg.xml
Configuration config = new Configuration().configure();

2)SessionFactory:工厂类,用于创建session对象;

① 负责保存和使用所有配置信息,消耗内存资源大

② 线程安全

③ 保证一个web项目中,只创建一个

一般创建工具类使用

//得到SessionFactory
SessionFactory factory = config.buildSessionFactory();
//创建Session对象
Session openSession = factory.openSession();

3)Session(重点):核心对象,实现数据库的增删改查

增:save

 - 本质:对象状态的转换,瞬时 - - - > 持久化

 - 目的:生成ID

public void addUser(User user) {
    // 读取hibernate.cfg.xml
    Configuration config = new Configuration().configure();
    // 获取SessionFactory工厂
    SessionFactory SessionFactory = config.buildSessionFactory();
    // 获取Session
    Session session = SessionFactory.openSession();
    // 打开事物
    Transaction transaction = session.beginTransaction();
    // 将user对象添加到数据库
    session.save(user);
    // 提交事务
    transaction.commit();
    // 关闭Session
    session.close();
}
View Code

删:delete

public void deleteUser(String id) {
    // 读取hibernate.cfg.xml
    Configuration config = new Configuration().configure();
    // 获取SessionFactory工厂
    SessionFactory SessionFactory = config.buildSessionFactory();
    // 获取Session
    Session session = SessionFactory.openSession();
    // 开启事物
    Transaction transaction = session.beginTransaction();
    // 得到指定ID的对象
    User user = session.get(User.class, id);
    // 将该对象在数据库中删除
    session.delete(user);
    // 提交事务
    transaction.commit();
    // 关闭Session
    session.close();
}
View Code

改:update

public void ChangeUser() {
    // 读取hibernate.cfg.xml
    Configuration config = new Configuration().configure();
    // 获取SessionFactory工厂
    SessionFactory SessionFactory = config.buildSessionFactory();
    // 获取Session
    Session session = SessionFactory.openSession();
    // 开启事物
    Transaction transaction = session.beginTransaction();
    // 得到指定ID的对象,并修改该对象的信息
    User user = session.get(User.class, "402880e56e2624ad016e2624b30d0000");//有ID,与Session有关联  持久化状态
    user.setUsername("newUsername");
    // 更新数据库,将修改后的对象更新到数据库中
    session.update(user);
    // 提交事务
    transaction.commit();
    // 关闭Session
    session.close();
}
View Code

查:get

public User findUser(String id) {
    // 读取hibernate.cfg.xml
    Configuration config = new Configuration().configure();
    // 获取SessionFactory工厂
    SessionFactory SessionFactory = config.buildSessionFactory();
    // 获取Session
    Session session = SessionFactory.openSession();
    // 开启事物
    Transaction transaction = session.beginTransaction();
    // 根据ID获取对象
    User user = session.get(User.class, id);
    // 提交事务
    transaction.commit();
    // 关闭Session
    session.close();
    // 返回获取到的对象
    return user;
}
View Code

4)Transaction:事物处理对象

// 读取hibernate.cfg.xml
Configuration config = new Configuration().configure();
// 获取SessionFactory工厂
SessionFactory SessionFactory = config.buildSessionFactory();
// 获取Session
Session session = SessionFactory.openSession();
// 开启事物
Transaction transaction = session.beginTransaction();

//进行数据库操作...

// 提交事务
transaction.commit();
// 关闭Session
session.close();
View Code

四、创建实体

1)提供无参的构造器

2)提供属性 - 成员变量的私有化,提供get、set方法

3)类型 - 尽量使用包装类型

4)主键

5)不要加final(hibernate中使用代理机制)

五、对象的三种状态

1)瞬时状态:实体-没有ID,没有与Session关联

2)持久化状态:实体-有ID,与Session关联

特点:持久化状态对象的任何改变都会同步到数据库中

3)游离态:实体-有ID,没有与Session关联

Configuration config = new Configuration().configure();
SessionFactory SessionFactory = config.buildSessionFactory();
Session session = SessionFactory.openSession();
Transaction transaction = session.beginTransaction();
   
User user = new User();//=>没有ID,没有与session关联   瞬时状态
user.setName("newName");//=>没有ID,没有与session关联  瞬时状态
session.save(user);//=>有ID,与session关联  持久化状态;
// save本质:对象状态的转换,瞬时->持久化;save目的:生成ID

transaction.commit();
session.close();//=>没有与session关联,有ID  游离态

对象三种状态的改变

六、一级缓存

提高效率

Configuration config = new Configuration().configure();
SessionFactory SessionFactory = config.buildSessionFactory();
Session session = SessionFactory.openSession();
Transaction transaction = session.beginTransaction();

// 获取ID为UserId的对象
// 有ID,与Session有关联    持久化状态
User user1 = session.get(User.class, UserId);
User user2 = session.get(User.class, UserId);
User user3 = session.get(User.class, UserId);
User user4 = session.get(User.class, UserId);
User user5 = session.get(User.class, UserId);
// 缓存的存在
System.out.println(user1==user5);// true

transaction.commit();
session.close();//=>没有与session关联,有ID  游离态

七、事务

1)事务的性质

原子性:原子,不可再分,一个操作不能分为更小的操作,要么全都执行,要么全不执行
一致性:事务在完成时,必须使得所有的数据保持一致的状态(与开始事务前保持一样的状态)
隔离性:事务查看数据时数据所处的状态,要么是另一个并发事务修改它之前的状态,要么使另一并发事务修改它之后的状态,事务不会查看中间状态的数据
持久性:事务完成之后。它对于系统的影响是永久性的。(执行了就执行了,没有撤回(悔棋)的说法)

2)事务的隔离级别

脏读:读取了未提交事务中的数据
不可重复读取:对于数据库中的某个数据,一个事务范围内多次读取同一个数据,却有不同的值
幻读:

3)配置事务的隔离级别hibernate.cfg.xml配置

1(0001) - 读未提交:最低的隔离级别,最没用(最快)
2(0010) - 读已提交:可避免脏读,不能避免不可重复度
3(0100) - 可重复读:可以避免不可重复度,可以避免脏读(MySQL默认)
8(1000) - 串行化:最强大,三种都可以解决(最慢) 
<!-- hibernate.cfg.xml配置事务隔离级别 -->
<property name="hibernate.connection.isolation">4</property>

5)事务小案例根据 id 查找 user,如果找到就改变 user 的名字,否则不做任何变化

- 需要配置事务

<!-- 配置事务(session与当前线程绑定) -->
<property name="hibernate.current_session_context_class">thread</property>
public class HibernateUtils {
    private static SessionFactory sessionFactory = null;

    static {
        // 读取hibernate.cfg.xml
        Configuration configure = new Configuration().configure();
        // 获取SessionFactory工厂
        sessionFactory = configure.buildSessionFactory();
    }

    // 获取全新的Session
    public static Session getSession() {
        // 获取session
        return sessionFactory.openSession();
    }

    // 获取当前线程的Session
    public static Session getCurrentSession() {
        return sessionFactory.getCurrentSession();
    }
}
HibernateUtils
public User findUserById(String id) {
    // 获取当前线程的session
    Session session = HibernateUtils.getCurrentSession();
    return session.get(User.class, id);
}

public void ChangeUserByUserId(String id) {
    // 获取当前线程的session
    Session session = HibernateUtils.getCurrentSession();
    // 先拿到持久化User
    User user = session.get(User.class, id);
    // 改变User(持久化->beginTransaction.commit()提交事务才会同步到数据库)
    user.setUsername("新用户名");

}
UserDao
public void addUser(User user) {

    // 获取当前线程的session,开启事物
    Session session = HibernateUtils.getCurrentSession();
    Transaction transaction = session.beginTransaction();
    try {
        // 根据ID查找对象
        User tuser = userDao.findUserById("94a80ab8-d049-4c73-bcc1-47206f56aafb");
        if (tuser != null) {
            // 如果找到了,根据ID修改名字
            userDao.ChangeUserByUserId(tuser.getId());
        } else {
            // 没找到,不做任何操作
        }
    } catch (Exception e) {
        e.printStackTrace();
        // 出错 - 回滚事务
        transaction.rollback();
    } finally {
        // 提交事务
        transaction.commit();
    }
}
UserService

八、HQL 与 Criteria 与 sql

1)HQL:不能出现表中的任何内容

(1)基本查询

String hql = "from com.sikiedu.domain.User";
Query<User> query = session.createQuery(hql);
List<User> list = query.list();// 查询多条数据

(2)条件查询 - 基本条件查询

String hql = "from com.sikiedu.domain.User where id = 1";
Query<User> query = session.createQuery(hql);
User user = query.uniqueResult();// 查询唯一数据

(3)条件查询 - ?占位符查询

String hql = "from com.sikiedu.domain.User where id = ?0";
Query query = session.createQuery(hql);
query.setParameter(0, id);// 设置参数
User user = (User) query.uniqueResult();// 查询唯一数据

(4)条件查询 - 命名占位符查询(推荐)

String hql = "from com.sikiedu.domain.User where id = :id";
Query query = session.createQuery(hql);
query.setParameter("id", id);// 设置参数
User user = (User) query.uniqueResult();// 查询唯一数据

(5)limit - 分页查询 

String hql = "from com.sikiedu.domain.User";
Query query = session.createQuery(hql);
query.setFirstResult(0);// 查询起始位置
query.setMaxResults(8);// 查询个数
List<User> list = query.list();

2)Criteria - CriteriaBuilder对象

(1)方法

gt 等于 > ge 等于 >=
lt 等于 < le 等于 <=
equal 等于 == nog 等于 !
between 等于 between and
like 等于 like 
isNotNull 等于 is not null / isNull 等于 is
null or 等于 or / and 等于 and
count 等于 总数 / avg 等于 平均值

(2)基本查询

CriteriaBuilder criteriaBuilder = session.getCriteriaBuilder();
// createQuery ---> 查询条件(首先要知道查询什么类型数据)(实体Object User)
CriteriaQuery<User> createQuery = criteriaBuilder.createQuery(User.class);
Root<User> form = createQuery.from(User.class);
createQuery.select(form);
// 执行查询
List<User> list = session.createQuery(createQuery).getResultList();

(3)条件查询

CriteriaBuilder builder = session.getCriteriaBuilder();
// createQuery ---> 查询条件(首先要知道查询什么类型数据)(实体Object User)
CriteriaQuery<User> query = builder.createQuery(User.class);
Root<User> from = query.from(User.class);
query.select(from).where(from.get("id").in("402880e56e2624ad016e262536ff0001"));
// 执行查询,并获取查询结果
List<User> list = session.createQuery(query).getResultList();

(4)分页查询

// createQuery ---> 查询条件(首先要知道查询什么类型数据)(数Integer Long)
CriteriaQuery<User> createQuery = session.getCriteriaBuilder().createQuery(User.class);
Root<User> from = createQuery.from(User.class);
createQuery.select(from);
// 执行查询
Query<User> query = session.createQuery(createQuery);
query.setFirstResult(0);
query.setMaxResults(3);
List<User> list = query.list();

(5)查询总记录数

CriteriaBuilder builder = session.getCriteriaBuilder();
// createQuery ---> 查询条件(首先要知道查询什么类型数据)(数Integer Long)
CriteriaQuery<Long> query = builder.createQuery(Long.class);
Root<User> from = query.from(User.class);
query.select(builder.count(from));
// 查询名字带有i的人的总数 - query.select(builder.count(from)).where(builder.like(from.get("username"), "%泡%")); 
// 执行查询
Long count = session.createQuery(query).uniqueResult();

3)sql

(1)基本查询

String sql = "select * from user";
// 创建sql查询对象
NativeQuery<User> sqlQuery = session.createSQLQuery(sql);
// 封装数据
sqlQuery.addEntity(User.class);
// 接收list结果
List<User> list = sqlQuery.list();

(2)条件查询

String sql = "select * from user where username = ?";
// 创建sql查询对象
NativeQuery<User> sqlQuery = session.createSQLQuery(sql);
// 给?赋值
sqlQuery.setParameter(1, "泡泡");
// 封装数据
sqlQuery.addEntity("com.sikiedu.domain.User");
// 接收唯一结果
User user = sqlQuery.uniqueResult();

(3)分页查询

String sql = "select * from user limit ?,?";
// 创建sql查询对象
NativeQuery<User> sqlQuery = session.createSQLQuery(sql);
// 给?复制
sqlQuery.setParameter(1, 1);
sqlQuery.setParameter(2, 2);
// 封装数据
sqlQuery.addEntity(User.class);
// 获取查询结果
List<User> list = sqlQuery.list();

九、外键关联 - 一对多与多对多关系

传送门① 传送门②

1)多对一 / 一对多(重点)

一对多关系是关系型数据库中两个表之间的一种关系。通常在数据库层级中,两表之间是有主外键关系的。在ORM中,如何通过对象描述表之间的关系,是ORM核心。

2)多对多(重点)

多对多关系是关系数据库中两个表之间的一种数据关系,为了维护这种关系,通常会存在一张中间关系表。两张表都只和关系表间建立主外键关系。

- 其实就是在中间表中的两次一对多的关系。

3)例子

模拟用户和用户帖子和回复帖的映射关系,一个用户有多个帖子,一个帖子可以被多个用户回复。
一个用户发表的多个帖子,对应用户和帖子的一对多映射。
多个用户回复一个帖子,对应用户和帖子的多对一映射。

实体类:

 1 package com.sikiedu.domain;
 2 
 3 import java.util.HashSet;
 4 import java.util.Set;
 5 
 6 public class User {
 7 
 8     private String id;
 9 
10     private String username;
11     private String password;
12     private String name;
13     private String email;
14     private String telephone;
15     // 一对多 - 被paste表所引用
16     private Set<Paste> pasteSet = new HashSet<Paste>();
17     private Set<Paste> answerPasteSet = new HashSet<Paste>();
18 
19     public User() {
20         super();
21     }
22 
23     public String getId() {
24         return id;
25     }
26 
27     public void setId(String id) {
28         this.id = id;
29     }
30 
31     public String getUsername() {
32         return username;
33     }
34 
35     public void setUsername(String username) {
36         this.username = username;
37     }
38 
39     public String getPassword() {
40         return password;
41     }
42 
43     public void setPassword(String password) {
44         this.password = password;
45     }
46 
47     public String getName() {
48         return name;
49     }
50 
51     public void setName(String name) {
52         this.name = name;
53     }
54 
55     public String getEmail() {
56         return email;
57     }
58 
59     public void setEmail(String email) {
60         this.email = email;
61     }
62 
63     public String getTelephone() {
64         return telephone;
65     }
66 
67     public void setTelephone(String telephone) {
68         this.telephone = telephone;
69     }
70 
71     public Set<Paste> getPasteSet() {
72         return pasteSet;
73     }
74 
75     public void setPasteSet(Set<Paste> pasteSet) {
76         this.pasteSet = pasteSet;
77     }
78 
79     public Set<Paste> getAnswerPasteSet() {
80         return answerPasteSet;
81     }
82 
83     public void setAnswerPasteSet(Set<Paste> answerPasteSet) {
84         this.answerPasteSet = answerPasteSet;
85     }
86 
87 }
实体类 - User Code
 1 package com.sikiedu.domain;
 2 
 3 import java.util.HashSet;
 4 import java.util.Set;
 5 
 6 public class Paste {
 7 
 8     private String id;
 9     private String title;
10     private String content;
11     private Integer offer;
12     private Integer ansnum;
13     private Integer glanceover;
14     private String createtime;
15     // 多对一 - 引用user表为外键属性
16     private User user;
17     // 一对多 - 被answer表所引用
18     private Set<User> userAnswerSet = new HashSet<User>();
19 
20     public Paste() {
21         super();
22     }
23 
24     public String getId() {
25         return id;
26     }
27 
28     public void setId(String id) {
29         this.id = id;
30     }
31 
32     public String getTitle() {
33         return title;
34     }
35 
36     public void setTitle(String title) {
37         this.title = title;
38     }
39 
40     public String getContent() {
41         return content;
42     }
43 
44     public void setContent(String content) {
45         this.content = content;
46     }
47 
48     public Integer getOffer() {
49         return offer;
50     }
51 
52     public void setOffer(Integer offer) {
53         this.offer = offer;
54     }
55 
56     public Integer getAnsnum() {
57         return ansnum;
58     }
59 
60     public void setAnsnum(Integer ansnum) {
61         this.ansnum = ansnum;
62     }
63 
64     public Integer getGlanceover() {
65         return glanceover;
66     }
67 
68     public void setGlanceover(Integer glanceover) {
69         this.glanceover = glanceover;
70     }
71 
72     public String getCreatetime() {
73         return createtime;
74     }
75 
76     public void setCreatetime(String createtime) {
77         this.createtime = createtime;
78     }
79 
80     public User getUser() {
81         return user;
82     }
83 
84     public void setUser(User user) {
85         this.user = user;
86     }
87 
88     public Set<User> getUserAnswerSet() {
89         return userAnswerSet;
90     }
91 
92     public void setUserAnswerSet(Set<User> userAnswerSet) {
93         this.userAnswerSet = userAnswerSet;
94     }
95 
96 }
实体类 - Paste Code
 1 package com.sikiedu.domain;
 2 
 3 public class Answer {
 4 
 5     private String id;
 6     private String content;
 7     // 多对一 - 引用user表、paste表为外键属性
 8     private User user;
 9     private Paste paste;
10 
11     public Answer() {
12         super();
13     }
14 
15     public String getId() {
16         return id;
17     }
18 
19     public void setId(String id) {
20         this.id = id;
21     }
22 
23     public User getUser() {
24         return user;
25     }
26 
27     public void setUser(User user) {
28         this.user = user;
29     }
30 
31     public Paste getPaste() {
32         return paste;
33     }
34 
35     public void setPaste(Paste paste) {
36         this.paste = paste;
37     }
38 
39     public String getContent() {
40         return content;
41     }
42 
43     public void setContent(String content) {
44         this.content = content;
45     }
46 
47 }
实体类 - Answer Code

hbm.xml映射文件:

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <!DOCTYPE hibernate-mapping PUBLIC 
 3     "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
 4     "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
 5 
 6 <hibernate-mapping package="com.sikiedu.domain">
 7     <class name="User" table="user">
 8         <id name="id">
 9             <generator class="uuid"></generator>
10         </id>
11         <property name="username" column="username"></property>
12         <property name="password" column="password"></property>
13         <property name="name" column="name"></property>
14         <property name="email" column="email"></property>
15         <property name="telephone" column="telephone"></property>
16 
17         <!-- 一对多 - one-to-many - 被paste表所引用
18             name:集合属性名称
19             cascade:级联操作
20                     ① save-update:级联保存,级联更新  (当一对多的'一'更新了'多'也会跟着更新)
21                     ② delete:级联删除(当一对多的'一'删除了'多'也会跟着删除)
22                     ③ all
23             inverse:配置关系是否不维护
24                     ① true:不维护
25                     ② false:维护关系
26                 column:外键列名
27                 class:与他相关的对象的完整类名-->
28         <set name="pasteSet">
29             <key column="userid"></key>
30             <one-to-many class="Paste" />
31         </set>
32         
33         <!-- 多对多关系 - 转换为两个一对多 -->
34         <set name="answerPasteSet">
35             <!-- 指定关联的外键的列名 -->
36             <key column="pasteid"></key>
37             <!-- 指定关联的外键的实体类名 -->
38             <one-to-many class="Answer"/>
39         </set>
40         
41     </class>
42 </hibernate-mapping>
XML - User Code
 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <!DOCTYPE hibernate-mapping PUBLIC 
 3     "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
 4     "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
 5 <hibernate-mapping package="com.sikiedu.domain">
 6     <class name="Paste" table="paste">
 7         <id name="id">
 8             <generator class="uuid"></generator>
 9         </id>
10         <property name="title" column="title"></property>
11         <property name="content" column="content"></property>
12         <property name="offer" column="offer"></property>
13         <property name="ansnum" column="ansnum"></property>
14         <property name="glanceover" column="glanceover"></property>
15         <property name="createtime" column="createtime"></property>
16         
17         <!-- 多对一  many-to-one - 外键关联指定user表为userid属性的约束 
18             name:引用属性名
19             class:与他关联的对象的完整类名
20             column:外键列名 -->
21         <!-- inverse:配置关系是否不维护
22                     ① true:不维护
23                     ② false:维护关系
24              insert属性:
25                性能优化:
26                无论怎么放弃维护,总有一方需要维护(按默认值来就行)
27                一般的开发中,一的方放弃维护,多的一方不放弃维护
28          -->
29         <many-to-one name="user" class="User" column="userid" insert="true"></many-to-one>
30         
31         <!-- 多对多关系   - 转换为两个一对多 -->
32         <set name="userAnswerSet">
33             <!-- 指定关联的外键的列名 -->
34             <key column="userid"></key>
35             <!-- 指定关联的外键的实体类名 -->
36             <one-to-many class="Answer"/>
37         </set>
38         
39     </class>
40 </hibernate-mapping>
XML - Paste Code
 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <!DOCTYPE hibernate-mapping PUBLIC 
 3     "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
 4     "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
 5 <hibernate-mapping package="com.sikiedu.domain">
 6     <class name="Answer" table="answer">
 7         <id name="id">
 8             <generator class="uuid"></generator>
 9         </id>
10         <property name="content" column="content"></property>
11         <!-- 多对一  many-to-one - 外键关联指定user/paste表为userid/pasteid属性的约束 -->
12         <many-to-one name="user" column="userid" class="User"></many-to-one>
13         <many-to-one name="paste" column="pasteid" class="Paste"></many-to-one>
14     </class>
15 </hibernate-mapping>
XML - Answer Code

hibernate.cfg.xml配置文件:

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <!DOCTYPE hibernate-configuration PUBLIC
 3     "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
 4     "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
 5 
 6 <hibernate-configuration>
 7     <session-factory>
 8         <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
 9         <property name="hibernate.connection.url"><![CDATA[jdbc:mysql://localhost:3306/hforum?useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2B8&useSSL=true]]></property>
10         <property name="hibernate.connection.username">root</property>
11         <property name="hibernate.connection.password">123456</property>
12 
13         <!-- 配置数据库方言 -->
14         <property name="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</property>
15 
16         <!-- 将hibernate生成的sql语句打印到控制台 -->
17         <property name="hibernate.show_sql"></property>
18 
19         <!-- 格式化hibernate生成的sql语句 -->
20         <property name="hibernate.format_sql"></property>
21 
22         <!-- 配置hibernate自动创建表 -->
23         <property name="hibernate.hbm2ddl.auto">update</property>
24 
25         <!-- 配置数据库的隔离级别 -->
26         <property name="hibernate.connection.isolation">4</property>
27 
28         <!-- 配置事务 (session与当前线程绑定) -->
29         <property name="current_session_context_class">thread</property>
30 
31         <!-- orm映射关系 -(O对象,R关系,M映射)-->
32         <mapping resource="com/sikiedu/domain/User.hbm.xml" />
33         <mapping resource="com/sikiedu/domain/Paste.hbm.xml" />
34         <mapping resource="com/sikiedu/domain/Answer.hbm.xml" />
35 
36     </session-factory>
37 </hibernate-configuration>
hibernate Code
原文地址:https://www.cnblogs.com/Dm920/p/11780224.html