初识JPA,Maven项目搭建
JPA是什么?
JPA 是Java Persistence API的简称,持久化API。是JDK5.0提供的注解或XML描述对象–关系型数据库的映射关系。快速完成POJO类实体到关系型数据库表的保存、修改和删除等功能。SUN公司主要是想整合ORM技术,减少程序员对CRUD的代码量,让程序员在CRUD上更得心应手。
SUN提出的JPA是JDK中的规范,只是一些规范,并没有具体的实现。具体的实现主要有Hibernate3.2+、TopLink 10.1.3+、OpenJPA等框架。这里我们以Hibernate 4.2.8 开始初识JPA是如何使用的。
Maven项目搭建
1、项目依赖
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.16</version>
<scope>provided</scope>
</dependency>
<!--JPA-->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>4.2.8.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>4.2.8.Final</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.20</version>
</dependency>
</dependencies>
2、persistence.xml
JPA 在启动时会读取persistence.xml文件,通过这个文件创建EntityManagerFactory,类似数据库连接池Pool。文件中的persistence-unit
其实就是环境信息,告诉JPA,启动时以哪个Unit作为JPA的配置信息,在创建EntityManagerFactory需要制定这个name
.
persistence.xml 需要放到哪个目录下?
- 对于普通Java项目,需要放到src下创建META-INF目录下。
- 对于Maven项目,需要放到src/main/resources 下创建META-INF目录下
总之保证项目启动后,这个文件在classes/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指定环境名词 -->
<persistence-unit name="jpaDev">
<!--指定属性的配置 -->
<properties>
<!--配置数据库方言,告诉JPA使用的数据库类型 -->
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect" />
<!--JPA的相关配置信息,hibernate配置基本和这些一样,javax.persistence换成hibernate即可 -->
<property name="javax.persistence.jdbc.url" value="jdbc:mysql:///jpa"/>
<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver" />
<property name="javax.persistence.jdbc.user" value="root" />
<property name="javax.persistence.jdbc.password" value="1234.com" />
<!--hibernate打印执行的SQL到控制台-->
<property name="hibernate.show_sql" value="true" />
<!--自动输出schema创建DDL语句 -->
<property name="hibernate.hbm2ddl.auto" value="create" />
</properties>
</persistence-unit>
</persistence>
persistence.xml 其他信息配置说明
- 指定class,让JPA扫描指定的类,默认扫描项目下有
@Entity
注解的类 - exclude-unlisted-classes 控制是否还扫描没有列出来的类
- jar-file 指定JPA扫描jar包里面的Entity类,一般用于引入外部jar包,并且有Entity需要交给JPA管理
<!--persistence-unit 可配置多个,每个都是一个环境;name指定环境名词 -->
<persistence-unit name="jpaDev">
<!--指定需要扫描的类,JPA统一管理,默认扫描@Entity 注解的类-->
<class>com.hongying.entity.User</class>
<class>com.hongying.entity.User2</class>
<!--true,表示排除没有列出来的类-->
<exclude-unlisted-classes>true</exclude-unlisted-classes>
<!--默认JPA只会扫描当前项目下的类,有时可能引入其他Jar包,也需要JPA管理里面的Entity时,这里可以指定扫描Jar文件-->
<!--<jar-file>/**/*/**.jar</jar-file>-->
<!--指定属性的配置 -->
<properties>
<!--配置数据库方言,告诉JPA使用的数据库类型 -->
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect" />
<!--JPA的相关配置信息,hibernate配置基本和这些一样,javax.persistence换成hibernate即可 -->
<property name="javax.persistence.jdbc.url" value="jdbc:mysql:///jpa"/>
<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver" />
<property name="javax.persistence.jdbc.user" value="root" />
<property name="javax.persistence.jdbc.password" value="1234.com" />
<!--hibernate打印执行的SQL到控制台-->
<property name="hibernate.show_sql" value="true" />
<!--自动输出schema创建DDL语句 -->
<property name="hibernate.hbm2ddl.auto" value="update" />
</properties>
</persistence-unit>
注意:class
可以指定多个,在开发或写Demo阶段,可以配置几个类扫描到JPA中,这样可以减少表的映射,对学习JPA有很大的帮助,不会因为表太多导致看起来眼花缭乱。同时系统启动还快。
3、hbm2ddl工具-修改表结构
在ORM的世界中,实体类和表结构其实已经是一一对应了。我们可以通过实体类的定义生成创建数据库表的DDL语句,这样在项目启动的时候就对数据库表做一些修改。注意:不能够通过数据库表的修改,映射到类。只能类–》表
- hibernate.hbm2ddl.auto=create 先删除实体对应的表,然后再创建;
- hibernate.hbm2ddl.auto=create-drop 先删除再创建,关闭系统之前会删除;
- hibernate.hbm2ddl.auto=update 实体有变化则更新数据库表结构;
- hibernate.hbm2ddl.auto=validate 检查是否有变化,有则抛出异常 ;
如何使用hbm2ddl
- 开发阶段可以用create或create-drop 快速创建表结构;
- 测试阶段使用update,否则测试数据就丢失了;
- 生产环境使用validate,启动系统前做一下检查
4、EntityManager 对象创建
JPA通过读取META-INF/persistence.xml文件中的配置persistence-unit创建EntityManagerFactory对象,然后再获取EntityManger对象。
- EntityManagerFactory对象相当一个数据库连接池,是线程安全的,一般就是一个项目下一个对象即可
- EntityManger相当一个连接对象,线程不安全,一般每次使用每次获取一个对象,使用完了需要close(),归还连接池
写一个JPAUtil类获取EntityManger
/**
* @author zyk
* @version 1.0.0
* @ClassName JpaUtil
* @Description JPA EntityManager 对象获取
* @createTime 2021年07月03日 21:15:00
*/
public abstract class JpaUtil {
private static EntityManagerFactory emf;
//EntityManagerFactory 对象是线程安全的,只需要项目启动时创建即可
static {
//根据Unit 创建Factory
emf=Persistence.createEntityManagerFactory("jpaDev");
}
public static EntityManager getEntityManager(){
return emf.createEntityManager();
}
}
5、案例创建User类
@Data
@Entity
public class User {
/**
* 主键,strategy ID 生成策略,默认AUTO,由数据库自己生成
*/
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
private String name;
}
6、单元测试,保存实体到数据库表
public class AppTest
{
/**
* 保存实体到数据库表
*/
@Test
public void save(){
User u=new User();
u.setName("jake");
EntityManager entityManager = JpaUtil.getEntityManager();
//开启事务
entityManager.getTransaction().begin();
//执行
entityManager.persist(u);
//关闭事务
entityManager.getTransaction().commit();
//归还连接
entityManager.close();
}
}
运行单元测试,查看控制台输出会创建user表 DDL ,以及插入数据到数据库表中。