一、新建 Java Web 项目
新建 java 项目,检查项目编码,加入 JDK1.7 及以上
二、引入 jar 包
引入 required 文件加下面所有的 jar 包
- antlr-2.7.7.jar 实现hql到sql的转换
- dom4j-1.6.1.jar xml解析
- geronimo-jta_1.1_spec-1.1.1.jar Geronimo是一个项目(整合优秀的组件和设计理念)
- hibernate-commons-annotations-5.0.1.Final.jar 注解
- hibernate-core-5.0.11.Final.jar 核心包
- hibernate-jpa-2.1-api-1.0.0.Final.jar hibenate对JPA的支持
- jandex-2.0.0.Final.jar 用来索引annoatation
- javassist-3.18.1-GA.jar 字节码操作
- jboss-logging-3.3.0.Final.jar 使用一个注解处理器来实现你的带注释的接口类
引入 jpa 文件夹下面的 jar 包
- hibernate-entitymanager-5.0.11.Final.jar hibernate对jpa的实现
引入 jpa-metamodel-generator 文件夹下面的 jar 包
- hibernate-jpamodelgen-5.0.11.Final.jar 关于模型自动生成的jar包
引入 optional / c3p0 连接池的jar包
- c3p0-0.9.2.1.jar
- mchange-commons-java-0.2.3.4.jar c3p0新版本的辅助包
- hibernate-c3p0-5.0.11.Final.jar
引入 optionl / ecache 下面的 slf4j-api.jar
SLF4J ,simple logging facade for java 简单的日志门面
它不是具体的日志解决方案,它只是提供了统一的记录日志的接口 ,其他组件就按照其提供的接口实现即可
- slf4j-api.jar
- slf4j-log4j.jar
- log4j.jar
slf4j 与 comm-logging 是竞争关系。
引入 junit / mysql / oracle
- junit-4.11.jar
- hamcrest-core-1.3.jar
- mysql-connector-java-5.0.8-bin.jar
- ojdbc14.jar
三、数据库建表,定义一个对应的实体类
数据库表:
实体类:
package com.lyu.hibernate.sysmanage.entity;
public class Student {
private Integer stId;
private String stName;
private Integer stAge;
public Integer getStId() {
return stId;
}
public void setStId(Integer stId) {
this.stId = stId;
}
public String getStName() {
return stName;
}
public void setStName(String stName) {
this.stName = stName;
}
public Integer getStAge() {
return stAge;
}
public void setStAge(Integer stAge) {
this.stAge = stAge;
}
}
四、配置 hibernate 的配置文件 hibernate.cfg.xml
在 hibernate-release-5.0.11.Final / project/ etc 目录下找到 hibernate 的配置文件模板 hibernate.cfg.xml 拷贝到项目的根目录下。
注:因为在后续配置 hibernate.cfg.xml 中的一些属性(如:数据库驱动,url,username,etc)的时候需要 hibernate.properties,所以先把 hibernate.properties 文件拷过来,后续配置完毕后删除即可。
配置数据库连接四要素
<!-- 连接数据库四要素 --> <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property> <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/hib</property> <property name="hibernate.connection.username">root</property> <property name="hibernate.connection.password">123</property>
数据库连接池配置
<!-- 用C3P0的数据源连接方式 --> <property name="hibernate.connection.provider_class">org.hibernate.c3p0.internal.C3P0ConnectionProvider</property>
数据库方言
<!-- 数据库方言 --> <property name="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</property>
session 上下文配置
<!-- session上下文(使用当前本地的线程) --> <property name="hibernate.current_session_context_class">thread</property>
thread 表示使用当前线程。(在分布式部署的时候需要别的配置)
上面五步配置完毕后的的配置文件如下:
<?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>
<session-factory>
<!-- 连接数据库四要素 -->
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/hib</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">123</property>
<!-- 用C3P0的数据源连接方式 -->
<property name="hibernate.connection.provider_class">org.hibernate.c3p0.internal.C3P0ConnectionProvider</property>
<!-- 数据库方言 -->
<property name="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</property>
<!-- session上下文(使用当前本地的线程) -->
<property name="hibernate.current_session_context_class">thread</property>
</session-factory>
</hibernate-configuration>
五、配置 数据库表与持久化对象之间的映射关系的配置文件 xxx.hbm.xml
建立实体类属性与数据库表中字段的映射关系。
<?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.lyu.hibernate.sysmanage.entity.Student" table="t_student">
<!-- 配置主键,name为实体类属性,column为数据库表字段 -->
<id name="stId" column="st_id">
<!-- 配置自增长 -->
<generator class="native"></generator>
</id>
<!-- 姓名字段 -->
<property name="stName" column="st_name"></property>
<!-- 年龄字段 -->
<property name="stAge" column="st_age"></property>
</class>
</hibernate-mapping>
六、在主配置文件中加入映射文件路径
为了让 hibernate 知道我们配置了哪些实体类与表之间的映射关系,需要把 xxx.hbm.xml 文件添加到主配置文件 hibernate.cfg.xml 中:
<?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>
<session-factory>
<!-- ...略略略... -->
<!-- 加入映射文件路径 -->
<mapping resource="com/lyu/hibernate/sysmanage/entity/student.hbm.xml" />
</session-factory>
</hibernate-configuration>
同时,为了在后续执行增删改查的时候能够看到 hibernate 执行的 sql 语句,设置 hibernate.show_sql 和 hibernate.format_sql 这两个属性为 true,最终的配置文件如下:
<?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>
<session-factory>
<!-- 显示执行过程的sql -->
<property name="hibernate.show_sql">true</property>
<!-- 格式化sql -->
<property name="hibernate.format_sql">true</property>
<!-- 连接数据库四要素 -->
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/hib</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">123</property>
<!-- 用C3P0的数据源连接方式 -->
<property name="hibernate.connection.provider_class">org.hibernate.c3p0.internal.C3P0ConnectionProvider</property>
<!-- 数据库方言 -->
<property name="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</property>
<!-- session上下文(使用当前本地的线程) -->
<property name="hibernate.current_session_context_class">thread</property>
<!-- 加入映射文件路径 -->
<mapping resource="com/lyu/hibernate/sysmanage/entity/student.hbm.xml" />
</session-factory>
</hibernate-configuration>
注:hibernate.cfg.xml 中的 property 的 name 属性值均是从 hibernate.properties 文件中拷贝过来的。
七、编写测试类进行测试
读取主配置文件
// 1.读取主配置文件 Configuration configer = new Configuration().configure(); // 如果配置的主配置文件的名字不叫 hibernate.cfg.xml 则用下面这种方式加载配置 // Configuration configer = new Configuration().configure("xxx.cfg.xml");
注:hibernate 使用的 dom4j 来加载的配置文件。
创建 SessionFactory
// 2.创建sessionFactory SessionFactory sessionFactory = configer.buildSessionFactory();
获取 Session
// 3.获取session // getCurrentSession会沿用当前session,节省数据库连接资源 Session session = sessionFactory.getCurrentSession(); // sessionFactory.openSession(); // 该方法会重新开启一个session
开启事务
// 4.开启事务 session.beginTransaction(); // 或者像下面这么写: //session.getTransaction().begin();
增删改查操作
…
事务提交
// 6.事务提交 session.getTransaction().commit();
事务回滚
try { // 开启事务.. // 执行增删改查.. // 提交事务.. } catch(Exception e) { // 发生错误,事务回滚 session.getTransaction().rollback(); }
为了复用代码,将获取 session 的部分代码提取成一个方法:
public Session getSession() {
// 1.读取主配置文件
Configuration configer = new Configuration().configure();
// Configuration configer = new Configuration().configure("xxx.cfg.xml");
// 2.创建sessionFactory
SessionFactory sessionFactory = configer.buildSessionFactory();
// 3.获取session
Session session = sessionFactory.getCurrentSession();
// sessionFactory.openSession(); // 重新开启一个session
return session;
}
1. 增加一条记录(使用 save 方法)
@Test
public void testAdd() {
Session session = getSession();
try {
// 4.开启事务
session.beginTransaction();
//session.getTransaction().begin();
// 5.增删改查操作
Student student = new Student();
student.setStName("曲健磊12");
student.setStAge(21);
session.save(student);
// 6.事务提交
session.getTransaction().commit();
} catch (Exception e) {
e.printStackTrace();
// 7.事务回滚
session.getTransaction().rollback();
}
}
2. 增加一条记录(使用 JPA 提供的 persist 接口)
@Test
public void testPersist() {
Session session = getSession();
try {
// 4.开启事务
session.beginTransaction();
//session.getTransaction().begin();
// 5.增删改查操作
Student student = new Student();
student.setStName("persisit");
student.setStAge(21);
session.persist(student); //jpa提供的接口
// 6.事务提交
session.getTransaction().commit();
} catch (Exception e) {
e.printStackTrace();
// 7.事务回滚
session.getTransaction().rollback();
}
}
3. 删除一条记录(使用 delete 方法)
@Test
public void testDel() {
Session session = getSession();
try {
// 4.开启事务
session.beginTransaction();
//session.getTransaction().begin();
// 5.增删改查操作
Student student = new Student();
student.setStId(3);
// student.setStName("曲健磊12");
// student.setStAge(21);
session.delete(student); // 删除方法是根据配置文件中的id来删的(不是数据库表中的id)
// 6.事务提交
session.getTransaction().commit();
} catch (Exception e) {
e.printStackTrace();
// 7.事务回滚
session.getTransaction().rollback();
}
}
4. 修改一条记录(使用 update 方法)
@Test
public void testUpdate() {
Session session = getSession();
try {
// 4.开启事务
session.beginTransaction();
//session.getTransaction().begin();
// 5.增删改查操作
Student student = new Student();
student.setStId(2);
student.setStName("daring");
student.setStAge(18);
session.update(student); // 修改方法也要根据对象的id来操作
// 6.事务提交
session.getTransaction().commit();
} catch (Exception e) {
e.printStackTrace();
// 7.事务回滚
session.getTransaction().rollback();
}
}
5. 增加 or 修改一条记录(通过有无主键来判断)
@Test
public void testSaveOrUpdate() {
Session session = getSession();
try {
// 4.开启事务
session.beginTransaction();
//session.getTransaction().begin();
// 5.增删改查操作
Student student = new Student();
student.setStId(5);
student.setStName("liuliuliu111");
student.setStAge(21);
session.saveOrUpdate(student); // 如果对象没有id则增加,如果有id则为修改操作
// 6.事务提交
session.getTransaction().commit();
} catch (Exception e) {
e.printStackTrace();
// 7.事务回滚
session.getTransaction().rollback();
}
}
6. 查询一条记录(使用 get 方法,不抛异常)
@Test
public void testGet() {
Session session = getSession();
try {
// 4.开启事务
session.beginTransaction();
//session.getTransaction().begin();
// 5.增删改查操作
Student student = session.get(Student.class, 111); // 还是根据id,查不到会返回null
System.out.println(student);
// 6.事务提交
session.getTransaction().commit();
} catch (Exception e) {
e.printStackTrace();
// 7.事务回滚
session.getTransaction().rollback();
}
}
7. 查询一条记录(使用 load 方法,抛异常)
@Test
public void testLoad() {
Session session = getSession();
try {
// 4.开启事务
session.beginTransaction();
//session.getTransaction().begin();
// 5.增删改查操作
Student student = session.load(Student.class, 115); // 查不到对象的时候会报错
System.out.println(student);
// 6.事务提交
session.getTransaction().commit();
} catch (Exception e) {
e.printStackTrace();
// 7.事务回滚
session.getTransaction().rollback();
}
}