(一)JPA的快速入門
- 2022 年 9 月 21 日
- 筆記
- spring, SpringData
JPA簡介
JPA是什麼
JPA 是Java Persistence API的縮寫,是一套由Java官方制定的ORM標準。當制定這套標準以後,市場上就出現很多JPA框架。如:OpenJPA(apache),EclipseTop(linktop)(eclipse),Hibernate。
1、如何使用
引入依賴
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<lombok.version>1.18.24</lombok.version> <!--lombok版本-->
<slf4j.version>1.7.25</slf4j.version> <!--slf4j版本-->
<spring.version>5.3.21</spring.version>
<junit.version>5.8.2</junit.version>
<mysql.version>8.0.30</mysql.version>
<HikariCP.version>5.0.1</HikariCP.version> <!--HikariCP連接池版本-->
<jpa.version>3.1.0</jpa.version> <!--jpa連接池版本-->
<hibernateORM.version>6.1.0.Final</hibernateORM.version> <!--HibernateORM 連接池版本-->
<hibernate.version>5.6.9.Final</hibernate.version> <!--Hibernate版本-->
</properties>
<dependencies>
<!--日誌列印-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>${slf4j.version}</version>
</dependency>
<!--日誌列印-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>${junit.version}</version>
</dependency>
<!-- HikariCP連接池 -->
<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
<version>5.0.1</version>
</dependency>
<!--雅加達JPA規範-->
<dependency>
<groupId>jakarta.persistence</groupId>
<artifactId>jakarta.persistence-api</artifactId>
<version>${jpa.version}</version>
</dependency>
<!--JPA核心依賴-->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>${hibernateORM.version}</version>
</dependency>
<!--hibernate使用Hikaricp連接池-->
<dependency>
<groupId>org.hibernate.orm</groupId>
<artifactId>hibernate-hikaricp</artifactId>
<version>${hibernateORM.version}</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core-jakarta</artifactId>
<version>${hibernate.version}</version>
</dependency>
</dependencies>
資料庫腳本
use yootk;
create table course
(
cid bigint auto_increment comment '課程id',
cname varchar(50) comment '課程名稱',
start date comment '課程開始時間',
end date comment '課程結束時間',
credit int comment '課程學分',
num int comment '課程人數',
constraint pk_cid primary key (cid)
)engine= innodb;
在JPA的開發過程之中是需要提供有一個持久化類的,而這個 持久化類 需要使用到一些特定的註解進行標記(JPA提供了所有可用的註解),同時這個類的結構要與數據表的結構完全對應。
創建實體類
package look.word.po;
import jakarta.persistence.*;
import lombok.*;
import org.hibernate.Hibernate;
import java.util.Date;
import java.util.Objects;
@Entity // 一個基於JPA規範的實體類
@Table(name = "course") //指定當前實體類關聯的表
@Getter
@Setter
@ToString
@RequiredArgsConstructor
public class Course {
@Id // 標識為主鍵
@GeneratedValue(strategy = GenerationType.IDENTITY) //指定主鍵生成策略
private Long cid;
// @Column註解,設置屬性關聯的資料庫表欄位
// 注意:如果屬性名和表欄位名相同,可以不設置
private String cname;
@Temporal(TemporalType.DATE) // 定義時間類型
private Date start;
@Temporal(TemporalType.DATE)
private Date end;
private Integer credit;
private Integer num;
// equels() hashCode()
}
常用註解
創建JAP配置文件
resources/META-INF/persistence.xml
注意: 配置很多,但不用記 記得修改資料庫,我這裡是基於Hikari連接池的,不需要可以直接使用簡化版
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1"
xmlns="//xmlns.jcp.org/xml/ns/persistence"
xmlns:xsi="//www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="//xmlns.jcp.org/xml/ns/persistence
//xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
<persistence-unit name="YootkJPA"> <!-- 持久化單元 -->
<class>look.word.po.Course</class> <!-- 實體類 -->
<properties> <!-- 使用Hikari連接池實現資料庫連接管理 -->
<property name="hibernate.connection.provider_class"
value="org.hibernate.hikaricp.internal.HikariCPConnectionProvider"/>
<property name="hibernate.dialect"
value="org.hibernate.dialect.MySQLDialect"/> <!-- 資料庫方言 -->
<property name="hibernate.hikari.dataSourceClassName"
value="com.zaxxer.hikari.HikariDataSource"/> <!-- Hikari數據源 -->
<property name="hibernate.hikari.minimumIdle"
value="5"/> <!-- 空閑時連接池數量 -->
<property name="hibernate.hikari.maximumPoolSize"
value="10"/> <!-- 連接池最大數量 -->
<property name="hibernate.hikari.idleTimeout"
value="3000"/> <!-- 連接最小維持時長 -->
<property name="hibernate.hikari.dataSource.driverClassName"
value="com.mysql.cj.jdbc.Driver"/> <!-- 驅動程式 -->
<property name="hibernate.hikari.dataSource.jdbcUrl"
value="jdbc:mysql://localhost:3306/yootk"/> <!-- 連接地址 -->
<property name="hibernate.hikari.dataSource.username"
value="root"/> <!-- 用戶名 -->
<property name="hibernate.hikari.dataSource.password"
value="317311"/> <!-- 密碼 -->
<property name="hibernate.show_sql"
value="true"/> <!-- 顯示執行SQL -->
<property name="hibernate.format_sql"
value="false"/> <!-- 格式化SQL -->
</properties>
</persistence-unit>
</persistence>
簡化版:
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="//xmlns.jcp.org/xml/ns/persistence" version="2.1">
<!-- 持久單元,配置一個資料庫連接 -->
<persistence-unit name="mysql-jpa">
<!-- DB連接四要素 -->
<properties>
<!-- 這裡使用Hibernate-JPA -->
<property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver"/>
<property name="hibernate.connection.url" value="jdbc:mysql://localhost:3306/yootk"/>
<property name="hibernate.connection.username" value="root"/>
<property name="hibernate.connection.password" value="317311"/>
<!-- 格式化輸出SQL語句 -->
<property name="hibernate.format_sql" value="true"/>
</properties>
</persistence-unit>
</persistence>
Hibernate可移植性配置核心: hibernate.dialect, 配置不同的方言就可以實現不同的資料庫移植處理
創建日期工具類:
知道用就好,不需要知道其原理。字元串轉日期對象
package look.word.util;
import java.time.Instant;
import java.time.LocalDate;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.Date;
/**
* @author : look-word
* 2022-09-19 22:38
**/
public class DateUtil {
/**
* 轉換格式
*/
private static final String DATA_PATTERN = "yyyy-MM-dd";
/**
* 日期格式化
*/
private static final DateTimeFormatter DATE_FORMATTER =
DateTimeFormatter.ofPattern(DATA_PATTERN);
private static final ZoneId ZONE_ID = ZoneId.systemDefault();
public static Date stringToDate(String date) {
LocalDate localDate = LocalDate.parse(date, DATE_FORMATTER);
Instant instant = localDate.atStartOfDay().atZone(ZONE_ID).toInstant();
return Date.from(instant);
}
}
測試:
測試文件夾下,創建測試文件,因為我們引入了 Junit 依賴,可以直接使用。
import jakarta.persistence.EntityManager;
import jakarta.persistence.EntityManagerFactory;
import jakarta.persistence.Persistence;
import look.word.po.Course;
import look.word.util.DateUtil;
import org.junit.jupiter.api.Test;
/**
* @author : look-word
* 2022-09-19 22:44
**/
public class TestCoursePersistence {
@Test
public void testAdd() {
// 創建JPA Entity工廠
EntityManagerFactory factory =
Persistence.createEntityManagerFactory("YootkJPA");
// JPA操作對象
EntityManager entityManager = factory.createEntityManager();
// 開啟事務
entityManager.getTransaction().begin();
Course course = new Course(); // 創建實體對象
course.setCname("Spring編程實戰");
course.setStart(DateUtil.stringToDate("2022-09-19"));
course.setEnd(DateUtil.stringToDate("2022-12-30"));
course.setCredit(2);
course.setNum(88);
entityManager.persist(course); // 類似於插入
entityManager.getTransaction().commit(); // 提交事務
factory.close();// 關閉連接
}
}
// 執行結果 需要往下翻 才能看到
// Hibernate: insert into course (cname, credit, end, num, start) values (?, ?, ?, ?, ?) 執行的sql
// 在JPA配置文件中有配置
一定要及得提交事務。
- 執行錯誤的話,一定要是上面哪一步出現錯誤了,請仔細查看
- 執行 沒有日誌輸出,提示log4j日誌配置的話,是由於我們沒有配置日誌資訊
**配置日誌: **log4j.properties
#將等級為DEBUG的日誌資訊輸出到console和file這兩個目的地,console和file的定義在下面的程式碼
log4j.rootLogger=DEBUG,console,file
#控制台輸出的相關設置
log4j.appender.console=org.apache.log4j.ConsoleAppender
log4j.appender.console.Threshold=DEBUG
log4j.appender.console.ImmediateFlush=true
log4j.appender.console.Target=System.err
log4j.appender.console.layout=org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=[%-5p] %d(%r) --> [%t] %l: %m %x %n
#文件輸出的相關設置
log4j.appender.file = org.apache.log4j.RollingFileAppender
log4j.appender.file.File=./log/logFile.log
log4j.appender.file.MaxFileSize=10mb
log4j.appender.file.Threshold=DEBUG
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=[%p][%d{yy-MM-dd}][%c]%m%n
#日誌輸出級別
log4j.logger.org.mybatis=DEBUG
log4j.logger.java.sql=DEBUG
log4j.logger.java.sql.Statement=DEBUG
log4j.logger.java.sql.ResultSet=DEBUG
log4j.logger.java.sql.PreparedStatement=DEBUG