• Spring Data JPA实现数据的增删改查操作 ,save()操作,如果id不存在就insert新增,如果id存在就是update


    Spring Data JPA实现数据的增删改查操作
    https://blog.csdn.net/pan_junbiao/article/details/105245983

    1、JPA(Java持久层API)

    1.1 认识Spring Data

    Spring Data 是Spring的一个子项目,旨在统一和简化各类型数据的持久化存储方式,而不拘泥于是关系型数据库还是NoSQL数据库。无论是哪种持久化存储方式,数据访问对象(Data Access Objects,DAO)都会提供对对象的增加、删除、修改和查询的方法,以及排序和分页方法等。
    Spring Data 提供了基于这些层面的统一接口(如:CrudRepository、 PagingAndSortingRepository),以实现持久化的存储。

    1.2 认识JPA

    JPA(Java Persistence API)是Java的持久化API,用于对象的持久化。它是一个非常强大的ORM持久化的解决方案,免去了使用JDBCTemplate开发的编写脚本工作。JPA通过简单约定好接口方法的规则自动生成相应的JPQL语句,然后映射成POJO对象。

    JPA是一个规范化接口,封装了Hibernate的操作作为默认实现,让用户不通过任何配置即可完成数据库的操作。

    2、认识JPA的接口

    JPA提供了操作数据库的接口。在开发过程中继承和使用这些接口,可简化现有的持久化开发工作。可以使Spring找到自定义接口,并生成代理类,后续可以把自定义接口注入Spring容器中进行管理。在自定义接口过程中,可以不写相关的SQL操作,由代理类自动生成。

    2.1 JPA接口JpaRepository

    JpaRepository接口继承自PagingAndSortingRepository接口。该接口提供了JPA的相关实用功能,以及通过Example进行查询的功能。Example对象是JPA提供用来构造查询条件的对象。该接口的关键代码如下:

    1. public interface JpaRepository<T, ID> extends PagingAndSortingRepository<T, ID>, QueryByExampleExecutor<T>
    2. {
    3. }

    在上述代码中,T 表示实体对象,ID 表示主键。ID必须实现序列号。

    JpaRepository接口的源代码如下:

    1. @NoRepositoryBean
    2. public interface JpaRepository<T, ID> extends PagingAndSortingRepository<T, ID>, QueryByExampleExecutor<T>
    3. {
    4. List<T> findAll();
    5. List<T> findAll(Sort var1);
    6. List<T> findAllById(Iterable<ID> var1);
    7. <S extends T> List<S> saveAll(Iterable<S> var1);
    8. void flush();
    9. <S extends T> S saveAndFlush(S var1);
    10. void deleteInBatch(Iterable<T> var1);
    11. void deleteAllInBatch();
    12. T getOne(ID var1);
    13. <S extends T> List<S> findAll(Example<S> var1);
    14. <S extends T> List<S> findAll(Example<S> var1, Sort var2);
    15. }

    JpaRepository接口提供的方法与说明:

    方法描述
    List<T> findAll();查找所有实体。
    List<T> findAll(Sort var1);排序、查找所有实体。
    List<T> findAllById(Iterable<ID> var1);返回制定一组ID的实体。
    <S extends T> List<S> saveAll(Iterable<S> var1);保存集合。
    void flush();执行缓存与数据库同步。
    <S extends T> S saveAndFlush(S var1);强制执行持久化。
    void deleteInBatch(Iterable<T> var1);删除一个实体集合。
    void deleteAllInBatch();删除所有实体。
    T getOne(ID var1);返回ID对应的实体。如果不存在,则返回空值。
    <S extends T> List<S> findAll(Example<S> var1);查询满足Example的所有对象。
    <S extends T> List<S> findAll(Example<S> var1, Sort var2);

    查询满足Example的所有对象,并且进行排序返回。

    2.2 数据操作接口CrudRepository

    CrudRepository接口继承自Repository接口,并新增了增加、删除、修改和查询方法。

    CrudRepository接口的源代码如下:

    1. @NoRepositoryBean
    2. public interface CrudRepository<T, ID> extends Repository<T, ID>
    3. {
    4. <S extends T> S save(S var1);
    5. <S extends T> Iterable<S> saveAll(Iterable<S> var1);
    6. Optional<T> findById(ID var1);
    7. boolean existsById(ID var1);
    8. Iterable<T> findAll();
    9. Iterable<T> findAllById(Iterable<ID> var1);
    10. long count();
    11. void deleteById(ID var1);
    12. void delete(T var1);
    13. void deleteAll(Iterable<? extends T> var1);
    14. void deleteAll();
    15. }

    CrudRepository接口提供的方法与说明:

    方法说明
    <S extends T> S save(S var1);保存实体。当实体中包含主键时,JPA会进行更新操作。
    <S extends T> Iterable<S> saveAll(Iterable<S> var1);保存所有实体。实体必须不为空。
    Optional<T> findById(ID var1);根据主键ID检索实体。
    boolean existsById(ID var1);根据主键ID检索实体,返回是否存在。值为布尔类型。
    Iterable<T> findAll();返回所有实体。
    Iterable<T> findAllById(Iterable<ID> var1);根据给定的一组ID值返回一组实体。
    long count();返回实体的数量
    void deleteById(ID var1);根据ID删除数据。
    void delete(T var1);删除给定的实体。
    void deleteAll(Iterable<? extends T> var1);删除实体。
    void deleteAll();删除所有实体。

    3、使用JPA实现数据的增删改查操作

    【实例】创建SpringBoot项目,使用JPA实现数据的增删改查操作。

    3.1 创建数据库表

    使用MySQL数据库,创建 tb_user 用户信息数据表,并添加测试数据。

    1. -- 判断数据表是否存在,存在则删除
    2. DROP TABLE IF EXISTS tb_user;
    3. -- 创建“用户信息”数据表
    4. CREATE TABLE IF NOT EXISTS tb_user
    5. (
    6. user_id INT AUTO_INCREMENT PRIMARY KEY COMMENT '用户编号',
    7. user_name VARCHAR(50) NOT NULL COMMENT '用户姓名',
    8. blog_url VARCHAR(50) NOT NULL COMMENT '博客地址',
    9. remark VARCHAR(50) COMMENT '备注'
    10. ) COMMENT = '用户信息表';
    11. -- 添加数据
    12. INSERT INTO tb_user(user_name,blog_url,remark) VALUES('pan_junbiao的博客','https://blog.csdn.net/pan_junbiao','您好,欢迎访问 pan_junbiao的博客');
    13. INSERT INTO tb_user(user_name,blog_url,remark) VALUES('pan_junbiao的博客_02','https://blog.csdn.net/pan_junbiao','您好,欢迎访问 pan_junbiao的博客');

    执行结果:

    3.2 创建项目并配置JPA环境

    (1)创建SpringBoot项目

    创建SpringBoot项目,并创建项目结构:dao(数据访问层)、service(服务层)、entity(实体层),如下图:

    (2)添加JPA和MySQL数据库的依赖

    在pom.xml配置文件中,添加如下依赖:

    1. <!-- Spring Data JPA -->
    2. <dependency>
    3. <groupId>org.springframework.boot</groupId>
    4. <artifactId>spring-boot-starter-data-jpa</artifactId>
    5. </dependency>
    6. <!-- MySQL的JDBC数据库驱动 -->
    7. <dependency>
    8. <groupId>mysql</groupId>
    9. <artifactId>mysql-connector-java</artifactId>
    10. <version>8.0.19</version>
    11. </dependency>

    (3)配置数据库连接信息

    SpringBoot项目使用MySQL等关系型数据库,需要配置连接信息。

    将默认的application.properties文件的后缀修改为“.yml”,即配置文件名称为:application.yml,并配置以下MySQL数据库的连接信息:

    1. spring:
    2. datasource:
    3. url: jdbc:mysql://localhost:3306/db_admin?useSSL=false&amp
    4. username: root
    5. password: 123456
    6. driver-class-name: com.mysql.cj.jdbc.Driver
    7. jpa:
    8. database: MYSQL
    9. show-sql: true
    10. open-in-view: true
    11. properties:
    12. hibernate:
    13. enable_lazy_load_no_trans: true
    14. dialect: org.hibernate.dialect.MySQL5Dialect
    15. ddl-auto: update

    3.3 实现增删改查代码

    (1)实体层(Entity层)

    在实体层(Entity层)中,创建UserInfo.java(用户信息实体类)。

    1. package com.pjb.jpauserdemo.entity;
    2. import javax.persistence.*;
    3. /**
    4. * 用户信息实体类
    5. * @author pan_junbiao
    6. **/
    7. @Entity
    8. @Table(name = "tb_user")
    9. public class UserInfo
    10. {
    11. //用户ID
    12. @Id
    13. @GeneratedValue(strategy = GenerationType.IDENTITY)
    14. @Column(name = "user_id")
    15. private int userId;
    16. //用户姓名
    17. @Column(name = "user_name")
    18. private String userName;
    19. //博客地址
    20. @Column(name = "blog_url")
    21. private String blogUrl;
    22. //备注
    23. private String remark;
    24. //省略getter与setter方法...
    25. }

    (2)数据库访问层(Dao层)

    在数据库访问层(Dao层)中,创建UserDao.java(用户信息数据库访问接口),并继承JpaRepository接口。

    1. package com.pjb.jpauserdemo.dao;
    2. import com.pjb.jpauserdemo.entity.UserInfo;
    3. import org.springframework.data.jpa.repository.JpaRepository;
    4. import org.springframework.stereotype.Repository;
    5. /**
    6. * 用户信息数据库访问接口
    7. * @author pan_junbiao
    8. **/
    9. @Repository
    10. public interface UserDao extends JpaRepository<UserInfo,Integer>
    11. {
    12. }

    (3)业务逻辑层(Service层)

    在业务逻辑层(Service层)中,创建UserService.java(用户业务逻辑接口)。

    1. package com.pjb.jpauserdemo.service;
    2. import com.pjb.jpauserdemo.entity.UserInfo;
    3. import java.util.List;
    4. /**
    5. * 用户业务逻辑接口
    6. * @author pan_junbiao
    7. **/
    8. public interface UserService
    9. {
    10. /**
    11. * 根据用户ID,查询用户信息
    12. */
    13. public UserInfo findById(int userId);
    14. /**
    15. * 查询用户列表
    16. */
    17. public List<UserInfo> findAll();
    18. /**
    19. * 新增用户
    20. */
    21. public UserInfo save(UserInfo userInfo);
    22. /**
    23. * 修改用户
    24. */
    25. public UserInfo edit(UserInfo userInfo);
    26. /**
    27. * 删除用户
    28. */
    29. public boolean deleteById(int userId);
    30. }

    在业务逻辑层(Service层)下,创建 impl 目录,在该目录下创建UserServiceImpl.java(用户业务逻辑类)。

    1. package com.pjb.jpauserdemo.service.impl;
    2. import com.pjb.jpauserdemo.dao.UserDao;
    3. import com.pjb.jpauserdemo.entity.UserInfo;
    4. import com.pjb.jpauserdemo.service.UserService;
    5. import org.springframework.beans.factory.annotation.Autowired;
    6. import org.springframework.stereotype.Service;
    7. import java.util.List;
    8. /**
    9. * 用户业务逻辑类
    10. * @author pan_junbiao
    11. **/
    12. @Service
    13. public class UserServiceImpl implements UserService
    14. {
    15. @Autowired
    16. private UserDao userDao;
    17. /**
    18. * 根据用户ID,查询用户信息
    19. */
    20. @Override
    21. public UserInfo findById(int userId)
    22. {
    23. return userDao.findById(userId).get();
    24. }
    25. /**
    26. * 查询用户列表
    27. */
    28. @Override
    29. public List<UserInfo> findAll()
    30. {
    31. return userDao.findAll();
    32. }
    33. /**
    34. * 新增用户
    35. */
    36. @Override
    37. public UserInfo save(UserInfo userInfo)
    38. {
    39. return userDao.save(userInfo);
    40. }
    41. /**
    42. * 修改用户
    43. */
    44. @Override
    45. public UserInfo edit(UserInfo userInfo)
    46. {
    47. return userDao.save(userInfo);
    48. }
    49. /**
    50. * 删除用户
    51. */
    52. @Override
    53. public boolean deleteById(int userId)
    54. {
    55. boolean result = true;
    56. try
    57. {
    58. userDao.deleteById(userId);
    59. }
    60. catch(Exception ex)
    61. {
    62. result = false;
    63. }
    64. return result;
    65. }
    66. }

    3.4 执行测试

    3.4.1 查询数据

    1. @Autowired
    2. private UserService userService;
    3. /**
    4. * 测试:根据用户ID,查询用户信息
    5. * @author pan_junbiao
    6. */
    7. @Test
    8. public void findById()
    9. {
    10. //查询用户编号为1的用户信息
    11. UserInfo user = userService.findById(1);
    12. if (user != null)
    13. {
    14. //打印结果
    15. System.out.println("用户编号:" + user.getUserId());
    16. System.out.println("用户姓名:" + user.getUserName());
    17. System.out.println("博客地址:" + user.getBlogUrl());
    18. System.out.println("备注信息:" + user.getRemark());
    19. }
    20. }

    执行结果:

    3.4.2 查询列表

    1. /**
    2. * 测试:查询用户列表
    3. * @author pan_junbiao
    4. */
    5. @Test
    6. public void findAll()
    7. {
    8. //查询用户列表
    9. List<UserInfo> userList = userService.findAll();
    10. if (userList != null && userList.size() > 0)
    11. {
    12. for (UserInfo user : userList)
    13. {
    14. //打印结果
    15. System.out.println("用户编号:" + user.getUserId());
    16. System.out.println("用户姓名:" + user.getUserName());
    17. System.out.println("博客地址:" + user.getBlogUrl());
    18. System.out.println("备注信息:" + user.getRemark());
    19. System.out.println("===========================================");
    20. }
    21. }
    22. }

    执行结果:

    3.4.3 新增操作

    1. /**
    2. * 测试:新增用户
    3. * @author pan_junbiao
    4. */
    5. @Test
    6. public void save()
    7. {
    8. //创建新用户
    9. UserInfo user = new UserInfo();
    10. user.setUserName("pan_junbiao的博客_03");
    11. user.setBlogUrl("https://blog.csdn.net/pan_junbiao");
    12. user.setRemark("您好,欢迎访问 pan_junbiao的博客");
    13. //执行新增操作
    14. userService.save(user);
    15. //如果新增成功,则可以获取自增主键
    16. //否则新增失败,则抛出异常
    17. if (user.getUserId() > 0)
    18. {
    19. System.out.println("新增用户成功,新增的用户信息:");
    20. System.out.println("用户编号:" + user.getUserId());
    21. System.out.println("用户姓名:" + user.getUserName());
    22. System.out.println("博客地址:" + user.getBlogUrl());
    23. System.out.println("备注信息:" + user.getRemark());
    24. }
    25. }

    执行结果:

    查询数据表:

    从查询的数据表结果中可以看到,成功新增了ID为3的用户信息。

    3.4.4 修改操作

    1. /**
    2. * 测试:修改用户
    3. * @author pan_junbiao
    4. */
    5. @Test
    6. public void edit()
    7. {
    8. //创建修改用户
    9. UserInfo user = new UserInfo();
    10. user.setUserId(3);
    11. user.setUserName("pan_junbiao的博客_04");
    12. user.setBlogUrl("https://blog.csdn.net/pan_junbiao");
    13. user.setRemark("您好,欢迎访问 pan_junbiao的博客");
    14. //执行修改操作
    15. userService.edit(user);
    16. //如果没有抛出异常,则表示执行成功
    17. System.out.println("修改用户成功");
    18. }

    查询数据表:

    从查询的数据表结果中可以看到,ID为3的用户信息已被修改。

    3.4.5 删除操作

    1. /**
    2. * 测试:删除用户
    3. * @author pan_junbiao
    4. */
    5. @Test
    6. public void deleteById()
    7. {
    8. //执行新增操作
    9. boolean result = userService.deleteById(3);
    10. //打印结果
    11. if (result)
    12. {
    13. System.out.println("删除用户成功");
    14. }
    15. else
    16. {
    17. System.out.println("删除用户失败");
    18. }
    19. }

    查询数据表:

    从查询的数据表结果中可以看到,ID为3的用户信息已被删除。

    3.4.6 完整的测试代码

    1. package com.pjb.jpauserdemo.service.impl;
    2. import com.pjb.jpauserdemo.entity.UserInfo;
    3. import com.pjb.jpauserdemo.service.UserService;
    4. import org.junit.Test;
    5. import org.junit.runner.RunWith;
    6. import org.springframework.beans.factory.annotation.Autowired;
    7. import org.springframework.boot.test.context.SpringBootTest;
    8. import org.springframework.test.context.junit4.SpringRunner;
    9. import java.util.List;
    10. /**
    11. * 用户信息业务逻辑测试类
    12. * @author pan_junbiao
    13. **/
    14. @SpringBootTest
    15. @RunWith(SpringRunner.class)
    16. public class UserServiceImplTest
    17. {
    18. @Autowired
    19. private UserService userService;
    20. /**
    21. * 测试:根据用户ID,查询用户信息
    22. * @author pan_junbiao
    23. */
    24. @Test
    25. public void findById()
    26. {
    27. //查询用户编号为1的用户信息
    28. UserInfo user = userService.findById(1);
    29. if (user != null)
    30. {
    31. //打印结果
    32. System.out.println("用户编号:" + user.getUserId());
    33. System.out.println("用户姓名:" + user.getUserName());
    34. System.out.println("博客地址:" + user.getBlogUrl());
    35. System.out.println("备注信息:" + user.getRemark());
    36. System.out.println("\n");
    37. }
    38. }
    39. /**
    40. * 测试:查询用户列表
    41. * @author pan_junbiao
    42. */
    43. @Test
    44. public void findAll()
    45. {
    46. //查询用户列表
    47. List<UserInfo> userList = userService.findAll();
    48. if (userList != null && userList.size() > 0)
    49. {
    50. for (UserInfo user : userList)
    51. {
    52. //打印结果
    53. System.out.println("用户编号:" + user.getUserId());
    54. System.out.println("用户姓名:" + user.getUserName());
    55. System.out.println("博客地址:" + user.getBlogUrl());
    56. System.out.println("备注信息:" + user.getRemark());
    57. System.out.println("===========================================");
    58. }
    59. }
    60. }
    61. /**
    62. * 测试:新增用户
    63. * @author pan_junbiao
    64. */
    65. @Test
    66. public void save()
    67. {
    68. //创建新用户
    69. UserInfo user = new UserInfo();
    70. user.setUserName("pan_junbiao的博客_03");
    71. user.setBlogUrl("https://blog.csdn.net/pan_junbiao");
    72. user.setRemark("您好,欢迎访问 pan_junbiao的博客");
    73. //执行新增操作
    74. userService.save(user);
    75. //如果新增成功,则可以获取自增主键
    76. //否则新增失败,则抛出异常
    77. if (user.getUserId() > 0)
    78. {
    79. System.out.println("新增用户成功,新增的用户信息:");
    80. System.out.println("用户编号:" + user.getUserId());
    81. System.out.println("用户姓名:" + user.getUserName());
    82. System.out.println("博客地址:" + user.getBlogUrl());
    83. System.out.println("备注信息:" + user.getRemark());
    84. }
    85. }
    86. /**
    87. * 测试:修改用户
    88. * @author pan_junbiao
    89. */
    90. @Test
    91. public void edit()
    92. {
    93. //创建修改用户
    94. UserInfo user = new UserInfo();
    95. user.setUserId(3);
    96. user.setUserName("pan_junbiao的博客_04");
    97. user.setBlogUrl("https://blog.csdn.net/pan_junbiao");
    98. user.setRemark("您好,欢迎访问 pan_junbiao的博客");
    99. //执行修改操作
    100. userService.edit(user);
    101. //如果没有抛出异常,则表示执行成功
    102. System.out.println("修改用户成功");
    103. }
    104. /**
    105. * 测试:删除用户
    106. * @author pan_junbiao
    107. */
    108. @Test
    109. public void deleteById()
    110. {
    111. //执行新增操作
    112. boolean result = userService.deleteById(3);
    113. //打印结果
    114. if (result)
    115. {
    116. System.out.println("删除用户成功");
    117. }
    118. else
    119. {
    120. System.out.println("删除用户失败");
    121. }
    122. }
    123. }
  • 相关阅读:
    linux PCI 接口
    Linux 内核链表头数据结构
    Linux内核链表
    spawn-fcgi原理及源代码分析
    TRIZ系列-创新原理-17-转变到新维度原理
    《转》ceilometer的数据採集机制入门
    git配置文件读取顺序
    Android Studio 使用感受 错误解决
    scikit-learn:在实际项目中用到过的知识点(总结)
    //%f表示以十进制格式化输出浮点数 %.2f
  • 原文地址:https://www.cnblogs.com/sunny3158/p/16353791.html
Copyright © 2020-2023  润新知