JPA——JPA 开发步骤实战

摘要

本文主要介绍了JPA开发步骤实战,包括添加JPA依赖、领域Domain模型设计、创建Java实体类、配置数据库连接、创建Repository接口、service类、Application类、Controller类,提供RPC调用接口,进行JPA接口测试以及启动Springboot应用服务等内容,旨在帮助开发者掌握JPA开发流程。

1. 添加JPA依赖

pom.xml 文件中添加 JPA 和 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>
    <groupId>com.zhuangxiaoyan</groupId>
    <artifactId>springboot_jpa</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>springboot_jpa</name>
    <description>springboot_jpa</description>
    <properties>
        <java.version>1.8</java.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <spring-boot.version>2.6.13</spring-boot.version>
        <mysql-connector-verison>5.1.49</mysql-connector-verison>
        <lombok-version>1.18.30</lombok-version>
    </properties>

    <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-jdbc</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!--MySQL JDBC依赖,用来连接数据库-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>${mysql-connector-verison}</version>
        </dependency>

        <!-- Lombok注解 -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>${lombok-version}</version>
            <scope>provided</scope>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>${spring-boot.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>${spring-boot.version}</version>
                <configuration>
                    <mainClass>com.zhuangxiaoyan.springboot.jpa.SpringbootJpaApplication</mainClass>
                    <skip>true</skip>
                </configuration>
                <executions>
                    <execution>
                        <id>repackage</id>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

</project>

2. 领域Domain模型设计

-- springboot_jpa.`user` definition

CREATE TABLE `user` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键',
  `email` varchar(100) NOT NULL,
  `name` varchar(100) NOT NULL,
  `gmt_create` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `gmt_modify` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
  PRIMARY KEY (`id`),
  UNIQUE KEY `email` (`email`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COMMENT='user表';

3. 创建Java实体类

package com.zhuangxiaoyan.springboot.jpa.domian.model;

import lombok.Data;
import lombok.EqualsAndHashCode;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.PrePersist;
import javax.persistence.PreUpdate;
import javax.persistence.Table;
import java.io.Serializable;
import java.time.LocalDateTime;

/**
 * User
 *
 * @author xjl
 * @version 2025/01/13 23:07
 **/
@Entity
@Table(name = "user")
@Data
@EqualsAndHashCode
public class User implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "id")
    private int id;

    @Column(nullable = false, unique = true)
    private String email;

    @Column(nullable = false)
    private String name;

    @Column(nullable = false)
    private LocalDateTime gmtCreate;

    @Column(nullable = false)
    private LocalDateTime gmtModify;

    // 在实体第一次持久化到数据库时(即插入时),设置 gmtCreate 和 gmtModify
    @PrePersist
    public void prePersist() {
        LocalDateTime now = LocalDateTime.now();
        if (gmtCreate == null) {
            gmtCreate = now;
        }
        if (gmtModify == null) {
            gmtModify = now;
        }
    }

    // 在实体每次更新时,更新 gmtModify
    @PreUpdate
    public void preUpdate() {
        gmtModify = LocalDateTime.now();
    }
}

4. 配置数据库连接配置

application.propertiesapplication.yml 中配置数据源。

server:
  port: 8080                 # 设置应用程序运行端口
  servlet:
    context-path: /api       # 设置应用程序的上下文路径

spring:
  application:
    name: springboot-mybatis-app  # 设置 Spring Boot 应用程序的名称
  datasource:
    driver-class-name: com.mysql.jdbc.Driver   # MySQL数据库驱动
    url: jdbc:mysql://192.168.3.13:3306/springboot_jpa?useSSL=false&serverTimezone=UTC&characterEncoding=utf8&connectTimeout=10000&socketTimeout=10000  # 数据库连接URL
    username: root   # 数据库用户名
    password: root   # 数据库密码
    hikari:                   # 配置 Hikari 数据源连接池(Spring Boot 2 默认使用 HikariCP)
      minimum-idle: 5         # 最小空闲连接数
      maximum-pool-size: 10   # 最大连接池大小
      idle-timeout: 30000     # 空闲连接的最大生命周期(毫秒)
      connection-timeout: 30000  # 连接超时时间(毫秒)
      pool-name: HikariCP      # 连接池名称
  jackson:
    serialization:
      fail-on-empty-beans: false  # 禁用 Jackson 序列化空 JavaBean 错误
  thymeleaf:
    cache: false               # 开启/关闭 Thymeleaf 模板缓存
  messages:
    basename: messages         # 配置国际化消息文件路径(messages.properties)

logging:
  level:
    root: INFO                 # 设置根日志级别
    org.apache.ibatis: DEBUG   # 设置根mybatis的日志级别
    org.springframework.web: DEBUG  # 设置 Spring Web 的日志级别
    com.zhuangxiaoyan.springboot: DEBUG  # 设置自定义包的日志级别
  pattern:
    console: "%d{yyyy-MM-dd HH:mm:ss} - %msg%n"  # 设置日志输出格式

5. 创建Repository接口

UserRepository需要继承的JPARepository接口或者CrudRepository接口

package com.zhuangxiaoyan.springboot.jpa.domian.repository;

import com.zhuangxiaoyan.springboot.jpa.domian.model.User;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;

import java.util.Optional;

/**
 * UserRepository
 *
 * @author xjl
 * @version 2025/01/13 23:14
 **/
public interface UserRepository extends CrudRepository<User, Integer> {
    /**
     * 根据邮箱查询用户
     *
     * @param email
     * @return
     */
    Optional<User> findByEmail(String email);
}

6. 创建service类

package com.zhuangxiaoyan.springboot.jpa.domian.service;

import com.zhuangxiaoyan.springboot.jpa.domian.model.User;
import com.zhuangxiaoyan.springboot.jpa.domian.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Optional;

/**
 * UserDomainService
 *
 * @author xjl
 * @version 2025/01/13 23:12
 **/
@Service
public class UserService {

    @Autowired
    private UserRepository userRepository;

    /**
     * 判断邮箱是否唯一
     *
     * @param email
     * @return
     */
    public boolean isEmailUnique(String email) {
        return userRepository.findByEmail(email).isPresent();
    }

    /**
     * 创建用户
     *
     * @param user
     * @return
     */
    public User createUser(User user) {
        if (userRepository.findByEmail(user.getEmail()).isPresent()) {
            throw new IllegalArgumentException("Email already exists");
        }
        return userRepository.save(user);
    }

    /**
     * 查询所有用户
     *
     * @return
     */
    public List<User> getAllUsers() {
        return (List<User>) userRepository.findAll();
    }

    /**
     * 根据 ID 查询用户
     *
     * @param id
     * @return
     */
    public Optional<User> getUserById(int id) {
        return userRepository.findById(id);
    }

    /**
     * 更新用户
     *
     * @param id
     * @param updatedUser
     * @return
     */
    public User updateUser(int id, User updatedUser) {
        return userRepository.findById(id).map(user -> {
            user.setName(updatedUser.getName());
            user.setEmail(updatedUser.getEmail());
            return userRepository.save(user);
        }).orElseThrow(() -> new IllegalArgumentException("User not found"));
    }

    /**
     * 删除用户
     *
     * @param id
     */
    public void deleteUser(int id) {
        if (!userRepository.existsById(id)) {
            throw new IllegalArgumentException("User not found");
        }
        userRepository.deleteById(id);
    }
}

7. 创建Application类

package com.zhuangxiaoyan.springboot.jpa.application;

import com.zhuangxiaoyan.springboot.jpa.domian.model.User;
import com.zhuangxiaoyan.springboot.jpa.domian.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * UserApplication
 *
 * @author xjl
 * @version 2025/01/13 23:44
 **/
@Service
public class UserManagerApplication {

    @Autowired
    private UserService userService;

    /**
     * 这一层主要是业务层,相关处理逻辑
     */
    public User userCreateBusiness(User user) {
        return userService.createUser(user);
    }

    /**
     * 这一层主要是业务层,相关处理逻辑
     */
    public List<User> getUserAll() {
        return userService.getAllUsers();
    }
}

8. 创建Controller类

package com.zhuangxiaoyan.springboot.jpa.interfaces.controller;

import com.zhuangxiaoyan.springboot.jpa.domian.model.User;
import com.zhuangxiaoyan.springboot.jpa.domian.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

/**
 * UserController
 *
 * @author xjl
 * @version 2025/01/13 23:27
 **/
@RestController
@RequestMapping("/users")
public class UserManagerController {

    @Autowired
    private UserService userService;

    // 创建用户
    @PostMapping
    public ResponseEntity<User> createUser(@RequestBody User user) {
        User createdUser = userService.createUser(user);
        return ResponseEntity.ok(createdUser);
    }

    // 获取所有用户
    @GetMapping
    public ResponseEntity<List<User>> getAllUsers() {
        List<User> users = userService.getAllUsers();
        return ResponseEntity.ok(users);
    }

    // 根据 ID 获取用户
    @GetMapping("/{id}")
    public ResponseEntity<User> getUserById(@PathVariable int id) {
        return userService.getUserById(id)
                .map(ResponseEntity::ok)
                .orElse(ResponseEntity.notFound().build());
    }

    // 更新用户
    @PutMapping("/{id}")
    public ResponseEntity<User> updateUser(@PathVariable int id, @RequestBody User user) {
        User updatedUser = userService.updateUser(id, user);
        return ResponseEntity.ok(updatedUser);
    }

    // 删除用户
    @DeleteMapping("/{id}")
    public ResponseEntity<Void> deleteUser(@PathVariable int id) {
        userService.deleteUser(id);
        return ResponseEntity.noContent().build();
    }
}

9. 提供RPC调用接口

package com.zhuangxiaoyan.springboot.jpa.interfaces.facade;

/**
 * UserManagerFacade 提供远程调用GRPC 服务
 *
 * @author xjl
 * @version 2025/01/13 23:01
 **/
public interface UserManagerFacade {

}

10. JPA接口测试

package com.zhuangxiaoyan.springboot.jpa.application;

import com.zhuangxiaoyan.springboot.jpa.SpringbootJpaApplication;
import com.zhuangxiaoyan.springboot.jpa.domian.model.User;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

/**
 * UserMangerApplicationTest 测试类
 *
 * @author xjl
 * @version 2025/01/14 08:54
 **/

@SpringBootTest(classes = SpringbootJpaApplication.class)
public class UserMangerApplicationTest {

    @Autowired
    private UserManagerApplication userMangerApplication;

    @Test
    public void testCreateUser() {
        User user = new User();
        user.setName("xjl-test");
        user.setEmail("xjl-test@163.com");
        userMangerApplication.userCreateBusiness(user);
    }

    @Test
    public void testGetUserAll() {
        userMangerApplication.getUserAll().forEach(System.out::println);
    }
}

11. Springboot启动服务

package com.zhuangxiaoyan.springboot.jpa;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class SpringbootJpaApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringbootJpaApplication.class, args);
    }

}

12. 参考代码

Hera-Mybatis: 主要介绍的Mybatis的相关的原理和实践方案。 - Gitee.com

博文参考

相关推荐
T.O.P1119 分钟前
SQL语法基础知识总结
数据库·sql·mysql
BillKu21 分钟前
数据库存储上下标符号,sqlserver 2008r2,dm8
数据库·sqlserver·达梦数据库·dm8
Amir_zy22 分钟前
Python脚本:不同Oracle库的表进行读写
数据库·python·oracle
m0_7482398323 分钟前
MySQL Workbench菜单汉化为中文
android·数据库·mysql
JUN12JUN1224 分钟前
简单的sql注入 buuctf
服务器·数据库·oracle
CSBLOG26 分钟前
Day30上 - ChromaDB 向量数据库
数据库·人工智能·深度学习·oracle
GottdesKrieges27 分钟前
GaussDB日常维护操作
数据库·sql·gaussdb
爱上语文3 小时前
MyBatis实现数据库的CRUD
java·开发语言·数据库·mybatis
明月看潮生3 小时前
青少年编程与数学 02-007 PostgreSQL数据库应用 06课题、数据库操作
数据库·青少年编程·postgresql·编程与数学