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

博文参考

相关推荐
心思这就是1 分钟前
sql注入
数据库·sql
福赖6 分钟前
《微服务即使通讯中redis的作用》
数据库·redis·缓存
自己的九又四分之三站台14 分钟前
向量数据库PGVector实操
数据库
sa1002715 分钟前
walmart沃尔玛关键词商品搜索实现逻辑
数据库·python
handsome123428 分钟前
Navicat 查数据 乱码 解决 的经历
数据库·mysql·oracle
AllData公司负责人32 分钟前
【亲测好用】数仓建模平台能力演示
大数据·数据库·算法
上海合宙LuatOS1 小时前
LuatOS框架的使用(2)
java·服务器·开发语言·前端·数据库·嵌入式硬件·php
一起养小猫1 小时前
Flutter for OpenHarmony 实战 文件存储与数据库操作完全指南
开发语言·jvm·数据库·spring·flutter·harmonyos
2301_765703141 小时前
深入理解Python的if __name__ == ‘__main__‘
jvm·数据库·python
浒畔居1 小时前
使用Docker容器化你的Python应用
jvm·数据库·python