Spring Boot JPA 使用教程


JPA 是 Spring Boot 官方推薦的數據庫訪問組件,其充分體現了面向對象編程思想,有點像 asp.net 的 EFCore。JPA 也是眾多 ORM 的抽象。

從本系列開始,都需要用到 mysql 數據庫 和其他一些參考的數據庫。請准備相關環節。本章需要以下環境支撐:

  • mysql 5.6+
  • jdk1.8+
  • spring boot 2.1.6
  • idea 2018.1

本項目源碼下載

1 數據准備

數據庫教程系列都是使用相同的數據,如在 Spring Boot JDBC 使用教程使用的一樣

字段 類型 主鍵 說明
id int 自動編號
user_name varchar(100) 用戶名
password varchar(255) 密碼
last_login_time date 最近登錄時間
sex tinyint 性別 0男 1女 2其他

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for t_user
-- ----------------------------
DROP TABLE IF EXISTS `t_user`;
CREATE TABLE `t_user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `user_name` varchar(255) DEFAULT NULL,
  `password` varchar(255) DEFAULT NULL,
  `last_login_time` datetime DEFAULT NULL,
  `sex` tinyint(4) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=armscii8;

-- ----------------------------
-- Records of t_user
-- ----------------------------
BEGIN;
INSERT INTO `t_user` VALUES (1, 'json', '123', '2019-07-27 16:01:21', 1);
INSERT INTO `t_user` VALUES (2, 'jack jo', '123', '2019-07-24 16:01:37', 1);
INSERT INTO `t_user` VALUES (3, 'manistal', '123', '2019-07-24 16:01:37', 1);
INSERT INTO `t_user` VALUES (4, 'landengdeng', '123', '2019-07-24 16:01:37', 1);
INSERT INTO `t_user` VALUES (5, 'max', '123', '2019-07-24 16:01:37', 1);
COMMIT;

SET FOREIGN_KEY_CHECKS = 1;

2 新建 Spring Boot 工程項

  1. File > New > Project,如下圖選擇 Spring Initializr 然后點擊 【Next】下一步
  2. 填寫 GroupId(包名)、Artifact(項目名) 即可。點擊 下一步
    groupId=com.fishpro
    artifactId=jpa
  3. 選擇依賴 Spring Web Starter 前面打鈎,勾選SQL選項的 Spring Data JPA , MySQL
  4. 項目名設置為 spring-boot-study-jpa.

3 依賴引入 Pom.xml 配置

如果您已經勾選了 勾選SQL選項的 Spring Data JPA , MySQL,那么無須手動增加依賴。

<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-data-jpa</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-webflux</artifactId>
		</dependency>

		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<scope>runtime</scope>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
		<dependency>
			<groupId>io.projectreactor</groupId>
			<artifactId>reactor-test</artifactId>
			<scope>test</scope>
		</dependency>
	</dependencies>

4 JPA 的工程配置 application.yml

server:
  port: 8086
spring:
  #通用的數據源配置
  datasource:
    driverClassName: com.mysql.jdbc.Driver
    url: jdbc:mysql://localhost:3306/demo_test?useSSL=false&useUnicode=true&characterEncoding=utf8
    username: root
    password: 123
  jpa:
    #這個參數是在建表的時候,將默認的存儲引擎切換為 InnoDB 用的
    database-platform: org.hibernate.dialect.MySQL5InnoDBDialect
    #配置在日志中打印出執行的 SQL 語句信息。
    show-sql: true
    hibernate:
      #配置指明在程序啟動的時候要刪除並且創建實體類對應的表
      ddl-auto: create
  • spring.jpa.database-platform 設置為 org.hibernate.dialect.MySQL5InnoDBDialect 這個參數是在建表的時候,將默認的存儲引擎切換為 InnoDB 用的
  • spring.jpa.show-sql 設置為true 配置在日志中打印出執行的 SQL 語句信息。
  • spring.jpa.hibernate.ddl-auto 設置為 create 配置指明在程序啟動的時候要刪除並且創建實體類對應的表

5 編寫示例代碼

本示例代碼結構跟 Spring Boot Mybatis 使用教程 是一樣的。

代碼方便不同的是,在命名方便,JPA 把 Dao 改成了 Repository,繼承了 CrudRepository。

本示例包括新增的頁面

  1. src/main/java/com/fishpro/jpa/controller/UserController.java 控制層 rest api
  2. src/main/java/com/fishpro/jpa/domain/UserDO.java 實體對象
  3. src/main/java/com/fishpro/jpa/dao/UserRepository.java Repository 數據庫訪問層
  4. src/test/java/fishpro/com/UserRepositoryTest.java 測試類

5.1 新建實體對象 UserDao.java

建立基於 POJO 的實體對象,需要注意的是 JPA 與 Mybatis 是有區別的

  1. 實體類需要使用 @Entity 注解標注
  2. 需要對實體類的屬性進行標注,使用 @Id 標注主鍵
  3. 使用 @Column 標注非主鍵

/**
 * 用戶實體類
 * */
@Entity
@Table(name="t_user")
public class UserDO {
    @Id
    private Integer id;
    @Column(name="user_name",length = 200)
    private String userName;
    @Column(name="password",length = 200)
    private String password;
    @Column(name="sex")
    private Integer sex;
    @Column(name="last_login_time")
    private Date lastLoginTime;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public Integer getSex() {
        return sex;
    }

    public void setSex(Integer sex) {
        this.sex = sex;
    }

    public Date getLastLoginTime() {
        return lastLoginTime;
    }

    public void setLastLoginTime(Date lastLoginTime) {
        this.lastLoginTime = lastLoginTime;
    }
}

5.2 新建倉庫接口類 UserRepository

倉庫接口類 UserRepository 就是我們常用的 Dao 接口,需要注意的是 JPA 的倉儲接口需要

  1. 使用 @Repository 注解
  2. 繼承 JPARepository
  3. UserRepository 不需要編寫任何代碼,就可實現增刪改查
@Repository
public interface UserRepository extends JPARepository<UserDO,Integer> {

}

6 編寫 UserRepository 的測試用例

關於測試可參看 Spring Boot RestApi 測試教程 Mock 的使用

src/test/java/com/fishpro/jpa/ 下新增 UserRepositoryTest.java 使用 @RunWith(SpringRunner.class)@SpringBootTest 注解標注類。

@RunWith(SpringRunner.class)
@SpringBootTest
public class UserRepositoryTest{

}

6.1 新增用戶數據

初始化一個對象 UserDO 測試Insert過程

/**
     * 初始化一個對象 UserDO 測試Insert過程
     * */
    @Before
    public void before(){
        UserDO userDO=new UserDO();
        userDO.setId(1);
        userDO.setUserName("fishpro");
        userDO.setSex(1);
        userDO.setLastLoginTime(new Date());
        userDO.setPassword("passWord");
        userRepository.save(userDO);
    }

6.2 查詢單個數據

@Test
    public void testFind(){
        Optional<UserDO> optionalUserDO=userRepository.findById(1);
        if(optionalUserDO.isPresent()){
            UserDO userDO=optionalUserDO.get();
            System.out.println("testFind user"+userDO.getUserName());
        }

    }

6.3 查詢多個數據

@Test
    public void testFindAll(){
        List<UserDO> list=userRepository.findAll();
        for (UserDO user:list
             ) {
            System.out.println("user_name:"+user.getUserName());
        }
    }

6.4 更新數據

@Test
    public void testUpdate(){
        Optional<UserDO> optionalUserDO=userRepository.findById(1);
        if(optionalUserDO.isPresent()){
            UserDO userDO=optionalUserDO.get();
            userDO.setUserName("fishpro001");
            userRepository.save(userDO);
            System.out.println("testFind user"+userDO.getUserName());
        }

    }

6.5 刪除數據

@After
    public void after(){
        userRepository.deleteById(1);
        userRepository.deleteById(2);
        userRepository.deleteById(3);
    }

7 問題思考

7.1 聯合主鍵設置

假設我們定義了用戶角色表包括了 userId,roleId 兩個都是主鍵。

  1. 定義一個主鍵類
public class UserRoleKey implements Serializable {
    private Integer userId;
    private Integer roleId;
}
  1. 定義實體類
    注意實體類上 是用來 @IdClass 注解來實現復合主鍵定義
@Entity
@Table(name="t_user_role")
@IdClass(UserRoleKey.class) //注意這里是引入了 定義的符合主鍵類
public class UserRoleDO {
    @Id
    private Integer userId;
    @Id
    private Integer roleId;

    public Integer getUserId() {
        return userId;
    }

    public void setUserId(Integer userId) {
        this.userId = userId;
    }

    public Integer getRoleId() {
        return roleId;
    }

    public void setRoleId(Integer roleId) {
        this.roleId = roleId;
    }
}

7.2 自定義查詢


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM