eclipse+maven搭建hibernate5测试环境
1环境
Eclipse: Luna Service Release 2 (4.4.2),Eclipse Java EE IDE for Web Developers.Maven:3.5.4
2搭建
2.1创建maven项目
选择Maven的Maven Project项目
2.2配置maven依赖
修改maven项目向导自动生成的pom.xml,添加依赖项
<dependencies>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>5.2.11.Final</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.32</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
</dependencies>
2.3配置hibernate持久化单元
在路径src/main/resources/META-INF下新建persistence.xml配置文件
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0"
xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd ">
<persistence-unit name="myPersistenceUnit" transaction-type="RESOURCE_LOCAL">
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5InnoDBDialect" />
<property name="hibernate.hbm2ddl.auto" value="create-drop" />
<property name="hibernate.connection.username" value="根据个人实际环境填写数据库连接的用户名" />
<property name="hibernate.connection.password" value="根据个人实际环境填写数据库连接的密码" />
<property name="hibernate.connection.url" value="jdbc:mysql://localhost:3306/jpa?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC" />
<property name="hibernate.format_sql" value="true" />
<property name="hibernate.use_sql_comments" value="true" />
<property name="hibernate.show_sql" value="true" />
</properties>
</persistence-unit>
</persistence>
2.4.编写持久化类
在src/main/java中创建持久化类
package com.tyde.ht002.model;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name="tb_message")
public class Message {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private Long id;
@Column(name="text")
private String text;
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
}
2.5.存储和查询测试Junit测试用例编写
在src/test/java中创建测试用例
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.Persistence;
import junit.framework.TestCase;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.FixMethodOrder;
import org.junit.Test;
import org.junit.runners.MethodSorters;
import com.tyde.ht002.model.Message;
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class TestHibernate {
public static EntityManagerFactory emf;
@BeforeClass
public static void start(){
System.out.println("start()");
if(emf==null)
{
emf = Persistence.createEntityManagerFactory("myPersistenceUnit");
}
}
@AfterClass
public static void stop(){
System.out.println("stop()");
if(emf!=null){
emf.close();
}
}
@Test
public void test001StoreMessage(){
System.out.println("test001StoreMessage()");
EntityManager em = emf.createEntityManager();
EntityTransaction tx = em.getTransaction();
tx.begin();
Message message =new Message();
message.setText("hello world!");
em.persist(message );
tx.commit();
em.close();
}
@Test
public void test002QueryMessage(){
System.out.println("test002QueryMessage()");
EntityManager em = emf.createEntityManager();
EntityTransaction tx = em.getTransaction();
tx.begin();
List<Message> messages = em.createQuery("select m from Message m").getResultList();
TestCase.assertEquals(messages.size(),1);
TestCase.assertEquals(messages.get(0).getText(),"hello world!");
messages.get(0).setText("haha");
tx.commit();
em.close();
}
}
3.测试用例运行情况
3.1.执行情况
两个测试用例都通过了
3.2.执行顺序
运行测试用例,查看控制台打印的方法和sql查询语句,可以看到顺序如下:
1、start()方法,实体管理器工厂的创建
Hibernate:
drop table if exists tb_message
Hibernate:
create table tb_message (
id bigint not null auto_increment,
text varchar(255),
primary key (id)
) engine=InnoDB
2、test001StoreMessage()方法
Hibernate:
/* insert com.tyde.ht002.model.Message
*/ insert
into
tb_message
(text)
values
(?)
3、test002QueryMessage()方法,查询,并修改
Hibernate:
/* select
m
from
Message m */ select
message0_.id as id1_0_,
message0_.text as text2_0_
from
tb_message message0_
Hibernate:
/* update
com.tyde.ht002.model.Message */ update
tb_message
set
text=?
where
id=?
4、stop()方法,实体管理器工厂的关闭
Hibernate:
drop table if exists tb_message
4.相关知识
4.1.Hibernate配置文件相关属性
属性 | 描述 | 相关值 |
---|---|---|
hibernate.dialect | 数据库方言 | 如:org.hibernate.dialect.MySQL5;org.hibernate.dialect.OracleDialect;org.hibernate.dialect.SQLServer2005Dialect;org.hibernate.dialect.SQLServer2008Dialect |
hibernate.connection.username | 数据库连接用户名 | |
hibernate.connection.password | 数据库连接密码 | |
hibernate.connection.url | 数据库连接url路径 | |
hibernate.format_sql | 格式化SQL | |
hibernate.use_sql_comments | SQL语句注释,可以查看SQL语句的起因。 | |
hibernate.show_sql | 打印SQL语句,方便调试。 | |
hibernate.hbm2ddl.auto | 数据库表生成方式 | create 每次加载hibernate会删除上一次的生成的表,再根据model类重新生成新表 ; create-drop 每次加载hibernate根据model类生成表,但卸载后表就自动删除; update第一次加载hibernate时会根据model类自动创建表,以后加载时自动更新; validate每次加载时,验证表结构。 |
4.2.持久化类相关注解
注解 | 描述 |
---|---|
@Entity | 实体类,默认表的名字就是类名 |
@Table | 改变某些默认的映射规则 |
@Id | 声明主键 |
@GeneratedValue | 主键的生成策略。如: GenerationType.IDENTITY使用数据库标识列来分配主键,以确保唯一性; GenerationType.TABLE 使用数据库表来分配主键,以确保唯一性; GenerationType.SEQUENCE使用数据库序列来分配主键,以确保唯一性; GenerationType.AUTO根据具体数据库来选择前面几个策略的一种。 |
@Column | 属性与数据库字段的映射关系 |
@Transitent | 不需要映射的属性 |
4.3.JUnit 4 相关注解
5.常见问题及其解决
5.1.Junit问题
现象:junit报错junit.framework.AssertionFailedError: No tests found问题
原因:使用junit4.11版本,在写测试用例类时,使用了继承extends TestCase。junit3中使用继承,但junit4不用继承;
解决方式:extends TestCase junit3中使用,但是junit4中不要采用,去掉继承。ENCE使用数据库序列来分配主键,以确保唯一性;GenerationType.AUTO根据具体数据库来选择前面几个策略的一种。
5.2.Hibernate配置解析出错
现象:报错:对实体 “characterEncoding” 的引用必须以 ‘;’ 分隔符结尾
原因:在persistence.xml的文件中"&“未转义。
解决方式:在persistence.xml的文件中,我们需要将”&“做转义”&";如:
<property name="hibernate.connection.url"
value="jdbc:mysql://localhost:3306/jpa?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC" />
5.3.Mysql查询锁死
现象:测试用例一直执行不成功,通过navicate查询message表状态,标题栏一直显示“正在载入”
原因:表解锁在navicat for mysql中新建查询SHOW PROCESSLIST,查看当前任务列表,看到有很多waiting state的命令。
解决方式:结束所有操作当前表的进程Navicat中执行:kill + 进程号其中进程号即(SHOW PROCESSLIST查询结果表显示的ID)) 。