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>
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>
三、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(); }
删: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(); }
改: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(); }
查: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; }
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();
四、创建实体
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(); } }
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("新用户名"); }
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(); } }
八、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 }
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 }
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 }
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>
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>
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>
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>