一、什么是JPA
1. 理解JPA
Java Persistence API(JPA)是Java平台上的一套ORM(对象关系映射)规范,它为Java应用提供了与数据库交互的标准方式。JPA的设计目标是简化开发者对数据库的访问,提高持久化层的灵活性和可维护性。
那么什么是JPA?
JPA是Java EE中的一部分,定义了一套规范,用于实现Java对象与数据库表之间的映射关系。通过使用JPA,开发者可以库通过面向对象的方式来操作数据,而不用关心底层数据库的细节。JPA不仅提供了简单的CRUD操作,还支持复杂查询、事务管理等数据库交互功能。
2. JPA的核心概念
2.1 实体(Entity)
在JPA中,实体是指 映射到数据库表的Java对象 。通过在Java类上使用@Entity注解,开发者可以将该类声明为JPA实体。实体类的每个实例都对应数据库表中的一条记录。
@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "user_id")
private Long id;
@Column(name = "user_name")
private String username;
@Column(name = "user_email")
private String email;
// getters and setters
}
在上述例子中,User类被标记为实体,@Id注解表示该字段为主键,@GeneratedValue注解指定主键生成策略。
2.2 映射关系
JPA支持多种映射关系,包括一对一、一对多、多对一、多对多 等。通过在实体类之间使用注解,可以定义它们之间的关系。
@Entity
public class Department {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "user_id")
private Long id;
@Column(name = "user_name")
private String username;
@Column(name = "user_email")
private String email;
@OneToMany(mappedBy = "department")
private List<Employee> employees;
// 添加关联 Role对象
@ManyToOne(targetEntity = Role.class) // 表示多对一关联
@JoinColumn(name = "usr_role_id") // 注解映射关联的外键字段 , 如不指定会生成一张新表维护两个对象之间的关系
private Role role;
二、创建项目
① 选择相应的配制:
②选择相应的配置
我用到的是 MySQL数据库所以选 MySQL Drive
三、导入相关的依赖包
① 配置 pom.xml 配置文件
注意 将MySQL的驱动包的版本要一致
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.3.3</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.ty</groupId>
<artifactId>jpa</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<name>jpa</name>
<description>jpa</description>
<url/>
<licenses>
<license/>
</licenses>
<developers>
<developer/>
</developers>
<scm>
<connection/>
<developerConnection/>
<tag/>
<url/>
</scm>
<properties>
<java.version>21</java.version>
</properties>
<dependencies>
<!-- 导入jpa包 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<!-- 导入mysql包 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.19</version>
</dependency>
<!-- 导入web 包 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- 导入mysql包 -->
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<!-- 导入tomcat包 -->
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
② 配置 项目下 resource 包下的 application.properties 配置文件
# 项目名称
spring.application.name=jpa
# 配置项目资源
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
# 配置数据源驱动 crm为你的数据库名称
spring.datasource.url=jdbc:mysql://localhost:3306/crm?serverTimezone=GMT-8
# 账号
spring.datasource.username=root
# 密码
spring.datasource.password=whs
# 配置JPA(Hibernate) 相关信息
#spring.jpa.properties.hibernate.hbm2ddl.auto=update
# 配置sql方言
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL8Dialect
# 显示sql语句
spring.jpa.show-sql=true
#spring.jpa.properties.hibernate.format_sql=true
配置 application.properties 的文件又有四种方式配置
这就是配置 application.properties 配置文件的位置 及相关的配置 如果四个配置文件都没有 配置则是springboot 的 默认配置
③编写实体类
package com.ty.jpa.entity;
import jakarta.persistence.*;
import lombok.Data;
import java.io.Serializable;
import java.util.Map;
/**
* User
*
* @aurhor Administrator whs
* @since 2024/8/28
*/
@Entity // 用来标记一个数据库表对应的实体,默认和数据库中创建的表名和类名默认一致 对应数据库中的一个表,用此注解标记 pojo 是一个 JPA 实体
@Table(name = "sys_user") // 用来标记一个数据库表对应的实体,默认和数据库中创建的表名和类名默认一致 只能标注在实体的class处 表示实体对应的数据库表的信息
@Data
//@NamedQueries(@NamedQuery(name = "User.findUsersByName",query = "select u from User u where u.usrName = ?1")) // 命名QL查询
public class User implements Serializable {
@Id // 映射到数据库表的主键的属性 一个实体只能有一个属性被映射为主键
@GeneratedValue(strategy = GenerationType.IDENTITY) // 主键生成策略
@Column(name = "usr_id")
private Long usrId; // 编号
@Column(name = "usr_name") // 数据库表中该字段的详情定义
private String usrName; // 姓名
@Column(name = "usr_password")
private String usrPassword; // 密码
// 添加关联Role对象
@ManyToOne(targetEntity = Role.class) // 表示多对一关联
@JoinColumn(name = "usr_role_id") // 注解映射关联的外键字段 , 如不指定会生成一张新表维护两个对象之间的关系
private Role role;
// @Column(name = "usr_role_id")
// private Long usrRoleId; // 角色编号
@Column(name = "usr_flag")
private Long usrFlag; // 状态
public User() {
}
public User(String usrName, String usrPassword, Long usrFlag) {
this.usrName = usrName;
this.usrPassword = usrPassword;
this.usrFlag = usrFlag;
}
public Role getRole() {
return role;
}
public void setRole(Role role) {
this.role = role;
}
@Override
public String toString() {
return "User{" +
"usrId=" + usrId +
", usrName='" + usrName + '\'' +
", usrPassword='" + usrPassword + '\'' +
// ", usrRoleId=" + usrRoleId +
", role=" + role +
", usrFlag=" + usrFlag +
'}';
}
public Long getUsrId() {
return usrId;
}
public void setUsrId(Long usrId) {
this.usrId = usrId;
}
public String getUsrName() {
return usrName;
}
public void setUsrName(String usrName) {
this.usrName = usrName;
}
public String getUsrPassword() {
return usrPassword;
}
public void setUsrPassword(String usrPassword) {
this.usrPassword = usrPassword;
}
// public Long getUsrRoleId() {
// return usrRoleId;
// }
//
// public void setUsrRoleId(Long usrRoleId) {
// this.usrRoleId = usrRoleId;
// }
public Long getUsrFlag() {
return usrFlag;
}
public void setUsrFlag(Long usrFlag) {
this.usrFlag = usrFlag;
}
}
④ 编写 Repository
package com.ty.jpa.repository;
import com.ty.jpa.entity.User;
import com.ty.jpa.vo.UserInfo;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import java.util.List;
/**
* UserRepository
*
* @aurhor Administrator whs
* @since 2024/8/28
*/
public interface UsrRepository extends JpaRepository<User,Long>{
/**
* 根据用户名查询
* @param usrName
* @return
*/
public List<User> findByUsrNameLike(String usrName);
/**
* 自定义HQL查询
* HQL 是面向实体类和属性 ,语句中不能写表名和字段名
*/
@Query("select u from User u where u.usrRoleId = ?1 ") // ?后面的1 代表的是方法参数里面的顺序可以1、2、3的排序
public List<User> findByRoleId(Long roleId);
/**
* 使用原生SQL查询
* 需要在添加一个参数 nativeQuery = true
* 这时写的是SQL,面向数据库表和字段名
*/
@Query(value = "select * from sys_user where usr_role_id = ?1" , nativeQuery = true)
public List<User> findByRoleIdSQL(Long roleId);
@Transactional(timeout = 10) // 设置超时时间
@Modifying // 删除和修改都要加
@Query("update User u set u.usrName = ?1 where u.usrId = ?2")
public int modifyNameById(String name,Long id);
/**
* 此方法对应User实体中的 QL命名查询
* 如果希望根据接口方法名来实现数据库操作,则应该命名为findUsersByUsrName
*/
public List<User> findUsersByName(String usrName);
/**
* 测试按角色查询用户并分页
* @param usrRoleId 角色编号
* @param pageable 控制分页的辅助类
*/
public Page<User> findPageByUsrRoleId(Long usrRoleId, Pageable pageable);
/**
* 动态查询的复杂分页查询
* @param
* @param pageable
*/
@Query("SELECT u FROM User u WHERE u.usrName = ?1 AND u.usrRoleId = ?2")
public Page<User> findPageByUsrNameAndUsrRoleId(@Param("usrName")String usrName,@Param("roleId") Long roleId, Pageable pageable);
public Page<User> findAll(Specification<User> specification, Pageable pageable);
/**
* 根据id删除
* @param usrId
* @return
*/
@Modifying
@Transactional
@Query("DELETE FROM User u WHERE u.usrId = :usrId")
public int deleteUserById(@Param("usrId") Long usrId);
// 多表连接查询
@Query("select u.usrId as useId , u.usrName as usrName , u.usrPassword as usrPassword , u.usrRoleId as usrRoleId ,u.usrFlag as usrFlag , r.roleName as roleName from User u , Role r where u.usrRoleId = r.roleId and u.usrId = ?1")
public UserInfo getUserInfo(Long usrId);
// /**
// * Map 复杂分页查询
// * @param param
// * @param pageable
// */
// @Query("SELECT u FROM User u WHERE u.usrName = :usrName AND u.usrRoleId = :usrRoleId")
// public Page<User> findPageByMap(Map<String,Object> param, Pageable pageable);
}
注意
public interface UsrRepository extends JpaRepository<User,Long> {
}
接口要继承 JpaRepository 接口
第一个参数对应你的 实体类
JpaRepository 接口 中的方法 已经定义很多了 基本可以解决80%的sql 可以不用手动编写SQL
通过 Hibernate 他会自动生成SQL !!! 可以直接调用方法!
package org.springframework.data.jpa.repository;
import java.util.List;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.Sort;
import org.springframework.data.repository.ListCrudRepository;
import org.springframework.data.repository.ListPagingAndSortingRepository;
import org.springframework.data.repository.NoRepositoryBean;
import org.springframework.data.repository.query.QueryByExampleExecutor;
@NoRepositoryBean
public interface JpaRepository<T, ID> extends ListCrudRepository<T, ID>, ListPagingAndSortingRepository<T, ID>, QueryByExampleExecutor<T> {
void flush();
<S extends T> S saveAndFlush(S entity);
<S extends T> List<S> saveAllAndFlush(Iterable<S> entities);
/** @deprecated */
@Deprecated
default void deleteInBatch(Iterable<T> entities) {
this.deleteAllInBatch(entities);
}
void deleteAllInBatch(Iterable<T> entities);
void deleteAllByIdInBatch(Iterable<ID> ids);
void deleteAllInBatch();
/** @deprecated */
@Deprecated
T getOne(ID id);
/** @deprecated */
@Deprecated
T getById(ID id);
T getReferenceById(ID id);
<S extends T> List<S> findAll(Example<S> example);
<S extends T> List<S> findAll(Example<S> example, Sort sort);
}
④ 编写测试类
package com.ty.jpa;
import com.ty.jpa.entity.User;
import com.ty.jpa.repository.UsrRepository;
import jakarta.annotation.Resource;
import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.test.context.junit4.SpringRunner;
import java.util.HashMap;
import java.util.Map;
/**
* UserRepositoryTester
*
* @aurhor Administrator whs
* @since 2024/8/28
*/
//@RunWith(SpringRunner.class)
@SpringBootTest
public class UsrRepositoryTester {
@Resource
private UsrRepository usrRepository;
@Test
public void testGet(){ // 测试按注解查询用户,关联获得角色数据
User user = usrRepository.findById(2L).get();
System.out.println("usrName: "+user.getUsrName());
System.out.println("roleName: "+user.getRole().getRoleName());
}
@Test
public void insertUser() { // 测试新增
User user = new User("JPA","123456",1L);
usrRepository.save(user);
}
@Test
public void testGet(){ // 测试按主键查询
User user = usrRepository.findById(2L).get();
System.out.println("userName:" + user.getUsrName());
System.out.println("usrPassword:" + user.getUsrPassword());
}
@Test
public void testFindByUsrNameLike(){ // 测试按照用户名称模糊查询
List<User> list = usrRepository.findByUsrNameLike("%s%"); // 查询参数必须带%号
if (list != null){
for (User user : list ) {
System.out.println("userName: " + user.getUsrName());
}
}
}
@Test
public void testFindByRoleId(){ // 自定义QL查询
List<User> list = usrRepository.findByRoleId(1L);
if (list != null){
for (User user : list ) {
System.out.println("userName: " + user.getUsrName());
}
}
}
@Test
public void testFindByRoleIdSQL(){ // 使用原生SQL查询
List<User> list = usrRepository.findByRoleIdSQL(1L);
if (list != null){
for (User user : list ) {
System.out.println("userName: " + user.getUsrName());
}
}
}
@Test
public void testModifyNameById(){ // 测试修改功能
int upd = usrRepository.modifyNameById("阿贡",72L);
System.out.println( upd == 1 ? "修改成功!":"修改失败!");
}
@Test
public void testFindUsersByName(){ // QL命名查询
System.out.println(usrRepository.findUsersByName("阿贡"));
}
@Test
public void testFindPageByUsrRoleId(){ // 测试按角色查询用户并分页
int page = 0, size = 2; // 分页要素,页数从0开始
// 控制分页数据的排序 可以选择升序或者降序
Sort sort = Sort.by(Sort.Direction.DESC, "usrId");
// 控制分页的辅助类,主要用于设置页码、每页显示的数据条数和排序等
Pageable pageable = PageRequest.of(page, size, sort);
Page<User> userPage = usrRepository.findPageByUsrRoleId(1L,pageable);
System.out.println("总记录数:"+userPage.getTotalElements());
System.out.println("总页数:"+userPage.getTotalPages());
System.out.println("当前页数:"+userPage.getNumber()+1);
System.out.println("每页记录数:"+userPage.getSize());
System.out.println("当前页记录数:"+userPage.getNumberOfElements());
for (User user : userPage.getContent()){
System.out.println("userId :" + user.getUsrId());
System.out.println("userName: " + user.getUsrName());
}
}
@Test
public void testFindPageByUsrNameAndUsrRoleId (){ // 复杂查询用户并分页
int page = 0, size = 2; // 分页要素,页数从0开始
// 控制分页数据的排序 可以选择升序或者降序
Sort sort = Sort.by(Sort.Direction.DESC, "usrId");
// 控制分页的辅助类,主要用于设置页码、每页显示的数据条数和排序等
Pageable pageable = PageRequest.of(page, size, sort);
Map params = new HashMap();
params.put("usrId",1L);
params.put("usrName","小胖子");
Page<User> userPage = usrRepository.findPageByUsrNameAndUsrRoleId("小胖子",2L,pageable);
System.out.println("总记录数:"+userPage.getTotalElements());
System.out.println("总页数:"+userPage.getTotalPages());
System.out.println("当前页数:"+userPage.getNumber());
System.out.println("每页记录数:"+userPage.getSize());
System.out.println("当前页记录数:"+userPage.getNumberOfElements());
for (User user : userPage.getContent()){
System.out.println("userId :" + user.getUsrId());
System.out.println("userName: " + user.getUsrName());
}
}
@Test
public void testDeleteByUsrId(){ // 删除
System.out.println(usrRepository.deleteUserById(52L) == 1 ? "删除成功!":"删除失败!");
}
@Test
public void testGetUserInfo(){ // 多表连接查询
UserInfo userInfo = usrRepository.getUserInfo(2L);
System.out.println("usrName: "+userInfo.getUsrName());
System.out.println("roleName: "+userInfo.getRoleName());
System.out.println("usrFlag: "+userInfo.getUsrFlag());
}
@Test
public void testFindPageByMap (){ // 测试 Map 查询用户并分页
int page = 0, size = 2; // 分页要素,页数从0开始
// 控制分页数据的排序 可以选择升序或者降序
Sort sort = Sort.by(Sort.Direction.DESC, "usrId");
// 控制分页的辅助类,主要用于设置页码、每页显示的数据条数和排序等
Pageable pageable = PageRequest.of(page, size, sort);
Map<String,Object> param = new HashMap<>();
param.put("usrName","小胖子");
param.put("usrRoleId",1L);
System.out.println(param);
Page<User> userPage = usrRepository.findPageByMap(param,pageable);
System.out.println("总记录数:"+userPage.getTotalElements());
System.out.println("总页数:"+userPage.getTotalPages());
System.out.println("当前页数:"+userPage.getNumber());
System.out.println("每页记录数:"+userPage.getSize());
System.out.println("当前页记录数:"+userPage.getNumberOfElements());
for (User user : userPage.getContent()){
System.out.println(user+"\n");
}
}
}
⑤测试
"C:\Program Files\Java\jdk-21\bin\java.exe" -ea -Didea.test.cyclic.buffer.size=1048576 "-javaagent:E:\idea 2024.1\IntelliJ IDEA 2024.1\lib\idea_rt.jar=63797:E:\idea 2024.1\IntelliJ IDEA 2024.1\bin" -Dfile.encoding=UTF-8 -Dsun.stdout.encoding=UTF-8 -Dsun.stderr.encoding=UTF-8 -classpath "C:\Users\Administrator\.m2\repository\org\junit\platform\junit-platform-launcher\1.10.3\junit-platform-launcher-1.10.3.jar;C:\Users\Administrator\.m2\repository\org\junit\platform\junit-platform-engine\1.10.3\junit-platform-engine-1.10.3.jar;C:\Users\Administrator\.m2\repository\org\opentest4j\opentest4j\1.3.0\opentest4j-1.3.0.jar;C:\Users\Administrator\.m2\repository\org\junit\platform\junit-platform-commons\1.10.3\junit-platform-commons-1.10.3.jar;C:\Users\Administrator\.m2\repository\org\apiguardian\apiguardian-api\1.1.2\apiguardian-api-1.1.2.jar;C:\Users\Administrator\.m2\repository\org\junit\vintage\junit-vintage-engine\5.10.3\junit-vintage-engine-5.10.3.jar;E:\idea 2024.1\IntelliJ IDEA 2024.1\lib\idea_rt.jar;E:\idea 2024.1\IntelliJ IDEA 2024.1\plugins\junit\lib\junit5-rt.jar;E:\idea 2024.1\IntelliJ IDEA 2024.1\plugins\junit\lib\junit-rt.jar;D:\SpringBoot框架\Hello\jpa\target\test-classes;D:\SpringBoot框架\Hello\jpa\target\classes;D:\Source\maven\repository\org\springframework\boot\spring-boot-starter-data-jpa\3.3.3\spring-boot-starter-data-jpa-3.3.3.jar;D:\Source\maven\repository\org\springframework\boot\spring-boot-starter-aop\3.3.3\spring-boot-starter-aop-3.3.3.jar;D:\Source\maven\repository\org\springframework\spring-aop\6.1.12\spring-aop-6.1.12.jar;D:\Source\maven\repository\org\aspectj\aspectjweaver\1.9.22.1\aspectjweaver-1.9.22.1.jar;D:\Source\maven\repository\org\springframework\boot\spring-boot-starter-jdbc\3.3.3\spring-boot-starter-jdbc-3.3.3.jar;D:\Source\maven\repository\com\zaxxer\HikariCP\5.1.0\HikariCP-5.1.0.jar;D:\Source\maven\repository\org\springframework\spring-jdbc\6.1.12\spring-jdbc-6.1.12.jar;D:\Source\maven\repository\org\hibernate\orm\hibernate-core\6.5.2.Final\hibernate-core-6.5.2.Final.jar;D:\Source\maven\repository\jakarta\persistence\jakarta.persistence-api\3.1.0\jakarta.persistence-api-3.1.0.jar;D:\Source\maven\repository\jakarta\transaction\jakarta.transaction-api\2.0.1\jakarta.transaction-api-2.0.1.jar;D:\Source\maven\repository\org\jboss\logging\jboss-logging\3.5.3.Final\jboss-logging-3.5.3.Final.jar;D:\Source\maven\repository\org\hibernate\common\hibernate-commons-annotations\6.0.6.Final\hibernate-commons-annotations-6.0.6.Final.jar;D:\Source\maven\repository\io\smallrye\jandex\3.1.2\jandex-3.1.2.jar;D:\Source\maven\repository\com\fasterxml\classmate\1.7.0\classmate-1.7.0.jar;D:\Source\maven\repository\net\bytebuddy\byte-buddy\1.14.19\byte-buddy-1.14.19.jar;D:\Source\maven\repository\org\glassfish\jaxb\jaxb-runtime\4.0.5\jaxb-runtime-4.0.5.jar;D:\Source\maven\repository\org\glassfish\jaxb\jaxb-core\4.0.5\jaxb-core-4.0.5.jar;D:\Source\maven\repository\org\eclipse\angus\angus-activation\2.0.2\angus-activation-2.0.2.jar;D:\Source\maven\repository\org\glassfish\jaxb\txw2\4.0.5\txw2-4.0.5.jar;D:\Source\maven\repository\com\sun\istack\istack-commons-runtime\4.1.2\istack-commons-runtime-4.1.2.jar;D:\Source\maven\repository\jakarta\inject\jakarta.inject-api\2.0.1\jakarta.inject-api-2.0.1.jar;D:\Source\maven\repository\org\antlr\antlr4-runtime\4.13.0\antlr4-runtime-4.13.0.jar;D:\Source\maven\repository\org\springframework\data\spring-data-jpa\3.3.3\spring-data-jpa-3.3.3.jar;D:\Source\maven\repository\org\springframework\data\spring-data-commons\3.3.3\spring-data-commons-3.3.3.jar;D:\Source\maven\repository\org\springframework\spring-orm\6.1.12\spring-orm-6.1.12.jar;D:\Source\maven\repository\org\springframework\spring-context\6.1.12\spring-context-6.1.12.jar;D:\Source\maven\repository\org\springframework\spring-tx\6.1.12\spring-tx-6.1.12.jar;D:\Source\maven\repository\org\springframework\spring-beans\6.1.12\spring-beans-6.1.12.jar;D:\Source\maven\repository\org\slf4j\slf4j-api\2.0.16\slf4j-api-2.0.16.jar;D:\Source\maven\repository\org\springframework\spring-aspects\6.1.12\spring-aspects-6.1.12.jar;D:\Source\maven\repository\mysql\mysql-connector-java\8.0.19\mysql-connector-java-8.0.19.jar;D:\Source\maven\repository\com\google\protobuf\protobuf-java\3.6.1\protobuf-java-3.6.1.jar;D:\Source\maven\repository\org\springframework\boot\spring-boot-starter-web\3.3.3\spring-boot-starter-web-3.3.3.jar;D:\Source\maven\repository\org\springframework\boot\spring-boot-starter\3.3.3\spring-boot-starter-3.3.3.jar;D:\Source\maven\repository\org\springframework\boot\spring-boot\3.3.3\spring-boot-3.3.3.jar;D:\Source\maven\repository\org\springframework\boot\spring-boot-autoconfigure\3.3.3\spring-boot-autoconfigure-3.3.3.jar;D:\Source\maven\repository\org\springframework\boot\spring-boot-starter-logging\3.3.3\spring-boot-starter-logging-3.3.3.jar;D:\Source\maven\repository\ch\qos\logback\logback-classic\1.5.7\logback-classic-1.5.7.jar;D:\Source\maven\repository\ch\qos\logback\logback-core\1.5.7\logback-core-1.5.7.jar;D:\Source\maven\repository\org\apache\logging\log4j\log4j-to-slf4j\2.23.1\log4j-to-slf4j-2.23.1.jar;D:\Source\maven\repository\org\apache\logging\log4j\log4j-api\2.23.1\log4j-api-2.23.1.jar;D:\Source\maven\repository\org\slf4j\jul-to-slf4j\2.0.16\jul-to-slf4j-2.0.16.jar;D:\Source\maven\repository\org\yaml\snakeyaml\2.2\snakeyaml-2.2.jar;D:\Source\maven\repository\org\springframework\boot\spring-boot-starter-json\3.3.3\spring-boot-starter-json-3.3.3.jar;D:\Source\maven\repository\com\fasterxml\jackson\core\jackson-databind\2.17.2\jackson-databind-2.17.2.jar;D:\Source\maven\repository\com\fasterxml\jackson\core\jackson-annotations\2.17.2\jackson-annotations-2.17.2.jar;D:\Source\maven\repository\com\fasterxml\jackson\core\jackson-core\2.17.2\jackson-core-2.17.2.jar;D:\Source\maven\repository\com\fasterxml\jackson\datatype\jackson-datatype-jdk8\2.17.2\jackson-datatype-jdk8-2.17.2.jar;D:\Source\maven\repository\com\fasterxml\jackson\datatype\jackson-datatype-jsr310\2.17.2\jackson-datatype-jsr310-2.17.2.jar;D:\Source\maven\repository\com\fasterxml\jackson\module\jackson-module-parameter-names\2.17.2\jackson-module-parameter-names-2.17.2.jar;D:\Source\maven\repository\org\springframework\spring-web\6.1.12\spring-web-6.1.12.jar;D:\Source\maven\repository\io\micrometer\micrometer-observation\1.13.3\micrometer-observation-1.13.3.jar;D:\Source\maven\repository\io\micrometer\micrometer-commons\1.13.3\micrometer-commons-1.13.3.jar;D:\Source\maven\repository\org\springframework\spring-webmvc\6.1.12\spring-webmvc-6.1.12.jar;D:\Source\maven\repository\org\springframework\spring-expression\6.1.12\spring-expression-6.1.12.jar;D:\Source\maven\repository\com\mysql\mysql-connector-j\8.3.0\mysql-connector-j-8.3.0.jar;D:\Source\maven\repository\org\springframework\boot\spring-boot-starter-tomcat\3.3.3\spring-boot-starter-tomcat-3.3.3.jar;D:\Source\maven\repository\jakarta\annotation\jakarta.annotation-api\2.1.1\jakarta.annotation-api-2.1.1.jar;D:\Source\maven\repository\org\apache\tomcat\embed\tomcat-embed-core\10.1.28\tomcat-embed-core-10.1.28.jar;D:\Source\maven\repository\org\apache\tomcat\embed\tomcat-embed-el\10.1.28\tomcat-embed-el-10.1.28.jar;D:\Source\maven\repository\org\apache\tomcat\embed\tomcat-embed-websocket\10.1.28\tomcat-embed-websocket-10.1.28.jar;D:\Source\maven\repository\org\springframework\boot\spring-boot-starter-test\3.3.3\spring-boot-starter-test-3.3.3.jar;D:\Source\maven\repository\org\springframework\boot\spring-boot-test\3.3.3\spring-boot-test-3.3.3.jar;D:\Source\maven\repository\org\springframework\boot\spring-boot-test-autoconfigure\3.3.3\spring-boot-test-autoconfigure-3.3.3.jar;D:\Source\maven\repository\com\jayway\jsonpath\json-path\2.9.0\json-path-2.9.0.jar;D:\Source\maven\repository\jakarta\xml\bind\jakarta.xml.bind-api\4.0.2\jakarta.xml.bind-api-4.0.2.jar;D:\Source\maven\repository\jakarta\activation\jakarta.activation-api\2.1.3\jakarta.activation-api-2.1.3.jar;D:\Source\maven\repository\net\minidev\json-smart\2.5.1\json-smart-2.5.1.jar;D:\Source\maven\repository\net\minidev\accessors-smart\2.5.1\accessors-smart-2.5.1.jar;D:\Source\maven\repository\org\ow2\asm\asm\9.6\asm-9.6.jar;D:\Source\maven\repository\org\assertj\assertj-core\3.25.3\assertj-core-3.25.3.jar;D:\Source\maven\repository\org\awaitility\awaitility\4.2.2\awaitility-4.2.2.jar;D:\Source\maven\repository\org\hamcrest\hamcrest\2.2\hamcrest-2.2.jar;D:\Source\maven\repository\org\junit\jupiter\junit-jupiter\5.10.3\junit-jupiter-5.10.3.jar;D:\Source\maven\repository\org\junit\jupiter\junit-jupiter-api\5.10.3\junit-jupiter-api-5.10.3.jar;D:\Source\maven\repository\org\opentest4j\opentest4j\1.3.0\opentest4j-1.3.0.jar;D:\Source\maven\repository\org\junit\platform\junit-platform-commons\1.10.3\junit-platform-commons-1.10.3.jar;D:\Source\maven\repository\org\apiguardian\apiguardian-api\1.1.2\apiguardian-api-1.1.2.jar;D:\Source\maven\repository\org\junit\jupiter\junit-jupiter-params\5.10.3\junit-jupiter-params-5.10.3.jar;D:\Source\maven\repository\org\junit\jupiter\junit-jupiter-engine\5.10.3\junit-jupiter-engine-5.10.3.jar;D:\Source\maven\repository\org\junit\platform\junit-platform-engine\1.10.3\junit-platform-engine-1.10.3.jar;D:\Source\maven\repository\org\mockito\mockito-core\5.11.0\mockito-core-5.11.0.jar;D:\Source\maven\repository\net\bytebuddy\byte-buddy-agent\1.14.19\byte-buddy-agent-1.14.19.jar;D:\Source\maven\repository\org\objenesis\objenesis\3.3\objenesis-3.3.jar;D:\Source\maven\repository\org\mockito\mockito-junit-jupiter\5.11.0\mockito-junit-jupiter-5.11.0.jar;D:\Source\maven\repository\org\skyscreamer\jsonassert\1.5.3\jsonassert-1.5.3.jar;D:\Source\maven\repository\com\vaadin\external\google\android-json\0.0.20131108.vaadin1\android-json-0.0.20131108.vaadin1.jar;D:\Source\maven\repository\org\springframework\spring-core\6.1.12\spring-core-6.1.12.jar;D:\Source\maven\repository\org\springframework\spring-jcl\6.1.12\spring-jcl-6.1.12.jar;D:\Source\maven\repository\org\springframework\spring-test\6.1.12\spring-test-6.1.12.jar;D:\Source\maven\repository\org\xmlunit\xmlunit-core\2.9.1\xmlunit-core-2.9.1.jar;D:\Source\maven\repository\junit\junit\4.13.2\junit-4.13.2.jar;D:\Source\maven\repository\org\hamcrest\hamcrest-core\2.2\hamcrest-core-2.2.jar;D:\Source\maven\repository\org\projectlombok\lombok\1.18.34\lombok-1.18.34.jar" com.intellij.rt.junit.JUnitStarter -ideVersion5 -junit5 com.ty.jpa.UsrRepositoryTester,testGet
15:56:40.211 [main] INFO org.springframework.test.context.support.AnnotationConfigContextLoaderUtils -- Could not detect default configuration classes for test class [com.ty.jpa.UsrRepositoryTester]: UsrRepositoryTester does not declare any static, non-private, non-final, nested classes annotated with @Configuration.
15:56:40.311 [main] INFO org.springframework.boot.test.context.SpringBootTestContextBootstrapper -- Found @SpringBootConfiguration com.ty.jpa.JpaApplication for test class com.ty.jpa.UsrRepositoryTester
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v3.3.3)
2024-08-31T15:56:40.911+08:00 INFO 30632 --- [jpa] [ main] com.ty.jpa.UsrRepositoryTester : Starting UsrRepositoryTester using Java 21.0.1 with PID 30632 (started by Administrator in D:\SpringBoot框架\Hello\jpa)
2024-08-31T15:56:40.913+08:00 INFO 30632 --- [jpa] [ main] com.ty.jpa.UsrRepositoryTester : No active profile set, falling back to 1 default profile: "default"
2024-08-31T15:56:41.561+08:00 INFO 30632 --- [jpa] [ main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
2024-08-31T15:56:41.642+08:00 INFO 30632 --- [jpa] [ main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 69 ms. Found 1 JPA repository interface.
2024-08-31T15:56:42.119+08:00 INFO 30632 --- [jpa] [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting...
2024-08-31T15:56:42.685+08:00 INFO 30632 --- [jpa] [ main] com.zaxxer.hikari.pool.HikariPool : HikariPool-1 - Added connection com.mysql.cj.jdbc.ConnectionImpl@1e12a5a6
2024-08-31T15:56:42.685+08:00 INFO 30632 --- [jpa] [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Start completed.
2024-08-31T15:56:42.738+08:00 INFO 30632 --- [jpa] [ main] o.hibernate.jpa.internal.util.LogHelper : HHH000204: Processing PersistenceUnitInfo [name: default]
2024-08-31T15:56:42.801+08:00 INFO 30632 --- [jpa] [ main] org.hibernate.Version : HHH000412: Hibernate ORM core version 6.5.2.Final
2024-08-31T15:56:42.841+08:00 INFO 30632 --- [jpa] [ main] o.h.c.internal.RegionFactoryInitiator : HHH000026: Second-level cache disabled
2024-08-31T15:56:43.187+08:00 INFO 30632 --- [jpa] [ main] o.s.o.j.p.SpringPersistenceUnitInfo : No LoadTimeWeaver setup: ignoring JPA class transformer
2024-08-31T15:56:43.279+08:00 WARN 30632 --- [jpa] [ main] org.hibernate.orm.deprecation : HHH90000025: MySQL8Dialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default)
2024-08-31T15:56:43.279+08:00 WARN 30632 --- [jpa] [ main] org.hibernate.orm.deprecation : HHH90000026: MySQL8Dialect has been deprecated; use org.hibernate.dialect.MySQLDialect instead
2024-08-31T15:56:44.051+08:00 INFO 30632 --- [jpa] [ main] o.h.e.t.j.p.i.JtaPlatformInitiator : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration)
2024-08-31T15:56:44.055+08:00 INFO 30632 --- [jpa] [ main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
2024-08-31T15:56:44.222+08:00 WARN 30632 --- [jpa] [ main] JpaBaseConfiguration$JpaWebConfiguration : spring.jpa.open-in-view is enabled by default. Therefore, database queries may be performed during view rendering. Explicitly configure spring.jpa.open-in-view to disable this warning
2024-08-31T15:56:44.792+08:00 INFO 30632 --- [jpa] [ main] com.ty.jpa.UsrRepositoryTester : Started UsrRepositoryTester in 4.263 seconds (process running for 5.663)
WARNING: A Java agent has been loaded dynamically (D:\Source\maven\repository\net\bytebuddy\byte-buddy-agent\1.14.19\byte-buddy-agent-1.14.19.jar)
WARNING: If a serviceability tool is in use, please run with -XX:+EnableDynamicAgentLoading to hide this warning
WARNING: If a serviceability tool is not in use, please run with -Djdk.instrument.traceUsage for more information
WARNING: Dynamic loading of agents will be disallowed by default in a future release
Java HotSpot(TM) 64-Bit Server VM warning: Sharing is only supported for boot loader classes because bootstrap classpath has been appended
Hibernate: select u1_0.usr_id,r1_0.role_id,r1_0.role_desc,r1_0.role_flag,r1_0.role_name,u1_0.usr_flag,u1_0.usr_name,u1_0.usr_password from sys_user u1_0 left join sys_role r1_0 on r1_0.role_id=u1_0.usr_role_id where u1_0.usr_id=?
usrName: test
roleName: 客户经理
2024-08-31T15:56:45.353+08:00 INFO 30632 --- [jpa] [ionShutdownHook] j.LocalContainerEntityManagerFactoryBean : Closing JPA EntityManagerFactory for persistence unit 'default'
2024-08-31T15:56:45.357+08:00 INFO 30632 --- [jpa] [ionShutdownHook] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown initiated...
2024-08-31T15:56:45.365+08:00 INFO 30632 --- [jpa] [ionShutdownHook] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown completed.
进程已结束,退出代码为 0
至此 , SpringBoot 集成 Spring Data JPA 已经搭建完成 ~~