本篇博客会一步一步地演示如何集成hibernate,以及如何进行简单的增删改查。本篇博客的主要目的是快速地构建一个可运行的hibernate项目,概览hibernate,体会hibernate,对技术的细节不过多的解释。
新建一个maven项目,并加入以下依赖,包含hibernate相关的,mysql驱动,以及运行测试代码需要的包。还包括一个plugin。
<dependencies>
<dependency>
<groupId>junitgroupId>
<artifactId>junitartifactId>
<version>3.8.1version>
<scope>testscope>
dependency>
<dependency>
<groupId>org.testnggroupId>
<artifactId>testngartifactId>
<version>[6.9.10,)version>
<scope>testscope>
dependency>
<dependency>
<groupId>org.hibernategroupId>
<artifactId>hibernate-coreartifactId>
<version>5.2.10.Finalversion>
dependency>
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
<version>5.1.6version>
dependency>
<dependency>
<groupId>org.hibernategroupId>
<artifactId>hibernate-c3p0artifactId>
<version>[5.0.0,5.9.9)version>
dependency>
<dependency>
<groupId>com.mchangegroupId>
<artifactId>c3p0artifactId>
<version>0.9.5.2version>
dependency>
dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.pluginsgroupId>
<artifactId>maven-compiler-pluginartifactId>
<version>2.3.2version>
<configuration>
<source>1.8source>
<target>1.8target>
<showDeprecation>trueshowDeprecation>
<showWarnings>trueshowWarnings>
configuration>
plugin>
plugins>
build>
在项目中新建一个source folder,名字叫src/test/resources
,并在该source folder下新增一个名叫hibernate.cfg.xml
的xml文件,内容如下
<hibernate-configuration>
<session-factory>
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialectproperty>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driverproperty>
<property name="hibernate.connection.url">jdbc:mysql://localhost/sakilaproperty>
<property name="hibernate.connection.username">rootproperty>
<property name="hibernate.connection.password">rootproperty>
<property name="c3p0.timeout">10property>
<mapping class="chapter03.simple.Person" />
session-factory>
hibernate-configuration>
注意,上面的hibernate.connection.url
、hibernate.connection.username
和hibernate.connection.password
需要修改成你的环境的值。
节点的话,等会也需要替换成接下来你创建的实体类的真实全名。
本篇的例子中,我会使用一个名叫Person
的表,下面是创建这个表的sql脚本
create table Person
(
id int auto_increment primary key,
name varchar(100) not null
) default charset = utf8
为了方便演示,这个表结构尽量简单
在src/main/java
下新建一个java类(POJO),来对应数据库中的Person
表。
package chapter03.simple;
import javax.persistence.*;
@Entity
public class Person {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column
String name;
public Person() {
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
这里面包含了几个注解类:
1. @Entity
表示这个类是一个实体类,对应数据库中的一个表,不加参数的话,hibernate会认为类名和表名是一样的。如果不一样的话,可以加入一个name
参数来指定表的名字,如@Entity(name = "persons")
,意思是Person类对应到数据表的名字是persons
2. @Id
表示映射表中的这一列是主键。
3. @GeneratedValue(strategy = GenerationType.IDENTITY)
表示这一列是自增长的,无需为它赋值
4. @Column
表示该字段对应到映射表中的一列。如果数据表的列名不一样的话,也可以使用name
参数来指定真正的列名。
以上几步已经把hibernate集成到了我们的项目中,下面是时候编写一些代码来使用hibernate做点事情了。
在src/test/java
下新建一个类,本例中的完整类名是chapter03.simple.PersonTest
。注意,这个类要添加到hibernate.cfg.xml
中的
节点。下面我会针对某个小主题只列出相关的代码片段,完整的PersonTest
类的代码我会在最后贴出来。如果这个过程中有疑惑的话,可以直接去最下面看完整的代码。
SessionFactory
对象SessionFactory factory;
String testName = "J. C. Smell";
long generateId = 0;
@BeforeClass
public void setup() {
StandardServiceRegistry registry = new StandardServiceRegistryBuilder().configure().build();
factory = new MetadataSources(registry).buildMetadata().buildSessionFactory();
}
setup()
方法初始化了一个SessionFactory
对象,这个对象是全局的,下面的增删改查都会用到。上面还有两个变量也是全局的,为了在下面几个方法中共享。
@Test
public void testSavePerson() {
try (Session session = factory.openSession()) {
Transaction tx = session.beginTransaction();
Person person = new Person();
person.setName(testName);
session.save(person);
tx.commit();
generateId = person.getId();
System.out.println("the person's id is " + generateId);
Assert.assertEquals(generateId > 0, true);
}
}
@Test(dependsOnMethods = "testSavePerson")
public void testQueryPerson() {
try (Session session = factory.openSession()) {
Query query = session.createQuery("from Person where name = :name", Person.class);
query.setParameter("name", testName);
Person person = query.uniqueResult();
Assert.assertEquals(person.name, testName);
}
}
@Test(dependsOnMethods = "testQueryPerson")
public void testUpdatePerson() {
try (Session session = factory.openSession()) {
Transaction tx = session.beginTransaction();
Query query = session.createQuery("from Person where name = :name", Person.class);
query.setParameter("name", testName);
Person person = query.uniqueResult();
person.setName(testName + "updated");
tx.commit();
}
}
@Test(dependsOnMethods = "testUpdatePerson")
public void testDeletePerson() {
try(Session session = factory.openSession()){
Transaction tx = session.beginTransaction();
Query query = session.createQuery("from Person where id = :id", Person.class);
query.setParameter("id", generateId);
Person person = query.uniqueResult();
session.delete(person);
tx.commit();
}
}
打开控制台或终端,cd到项目的根目录,输入mvn clean test
命令开始运行测试代码,顺利的话结果应该是
Tests run: 4, Failures: 0, Errors: 0, Skipped: 0
由于@Test
的dependsOnMethods
参数的约束,上面的增删改查操作会按照顺序运行,并且如果一个方法运行失败了,下面的方法也会被跳过。
PersonTest
类的代码package chapter03.simple;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.boot.MetadataSources;
import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.testng.Assert;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
public class PersonTest {
SessionFactory factory;
String testName = "J. C. Smell";
long generateId = 0;
@BeforeClass
public void setup() {
StandardServiceRegistry registry = new StandardServiceRegistryBuilder().configure().build();
factory = new MetadataSources(registry).buildMetadata().buildSessionFactory();
}
@Test
public void testSavePerson() {
try (Session session = factory.openSession()) {
Transaction tx = session.beginTransaction();
Person person = new Person();
person.setName(testName);
session.save(person);
tx.commit();
generateId = person.getId();
System.out.println("the person's id is " + generateId);
Assert.assertEquals(generateId > 0, true);
}
}
@Test(dependsOnMethods = "testSavePerson")
public void testQueryPerson() {
try (Session session = factory.openSession()) {
Query query = session.createQuery("from Person where name = :name", Person.class);
query.setParameter("name", testName);
Person person = query.uniqueResult();
Assert.assertEquals(person.name, testName);
}
}
@Test(dependsOnMethods = "testQueryPerson")
public void testUpdatePerson() {
try (Session session = factory.openSession()) {
Transaction tx = session.beginTransaction();
Query query = session.createQuery("from Person where name = :name", Person.class);
query.setParameter("name", testName);
Person person = query.uniqueResult();
person.setName(testName + "updated");
tx.commit();
}
}
@Test(dependsOnMethods = "testUpdatePerson")
public void testDeletePerson() {
try(Session session = factory.openSession()){
Transaction tx = session.beginTransaction();
Query query = session.createQuery("from Person where id = :id", Person.class);
query.setParameter("id", generateId);
Person person = query.uniqueResult();
session.delete(person);
tx.commit();
}
}
}