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

博文参考

相关推荐
oradh30 分钟前
Oracle XTTS实现跨版本迁移和升级(Oracle 11g单库升级至19C RAC集群)
数据库·oracle·11g升级19c·xtts跨版本迁移和升级
z123456789861 小时前
2026最新两款AI编程工具深度对比实测
java·数据库·ai编程
程序猿DD2 小时前
一个 API Key,统一调用大模型、生图和联网搜索
数据库·网关
TlSfoward3 小时前
抓包代理链路下的 TLS 指纹变化分析 TLSFOWARD抓包工具
数据库·爬虫·网络协议·搜索引擎·php
数智化管理手记3 小时前
账龄分析手工统计易遗漏?自动账龄分析工具怎么搭建
大数据·网络·数据库·人工智能·数据挖掘
LabVIEW开发3 小时前
NI Package Manager安装LabVIEW时InternalServerError错误
网络·数据库·labview·labview知识·labview功能·labview程序
SelectDB3 小时前
PostgreSQL 实时同步到 Apache Doris:一站式 CDC 解决方案
数据库
Database_Cool_4 小时前
AI Agent 长期记忆怎么存?阿里云 PolarDB-X 对接 Mem0 记忆框架实践
数据库·阿里云
会编程的土豆4 小时前
数据库范式
数据库·oracle
L1624764 小时前
MySQL 全环境生产快速安装 + 完整配置手册(整合国产银河麒麟适配 + 主从补充版)
数据库·mysql