Spring Data JPA实现数据的增删改查操作

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提供用来构造查询条件的对象。该接口的关键代码如下:

public interface JpaRepository<T, ID> extends PagingAndSortingRepository<T, ID>, QueryByExampleExecutor<T> 
{
}

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

JpaRepository接口的源代码如下:

@NoRepositoryBean
public interface JpaRepository<T, ID> extends PagingAndSortingRepository<T, ID>, QueryByExampleExecutor<T> 
{
    List<T> findAll();

    List<T> findAll(Sort var1);

    List<T> findAllById(Iterable<ID> var1);

    <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);

    <S extends T> List<S> findAll(Example<S> var1);

    <S extends T> List<S> findAll(Example<S> var1, Sort var2);
}

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接口的源代码如下:

@NoRepositoryBean
public interface CrudRepository<T, ID> extends Repository<T, ID> 
{
    <S extends T> S save(S var1);

    <S extends T> Iterable<S> saveAll(Iterable<S> var1);

    Optional<T> findById(ID var1);

    boolean existsById(ID var1);

    Iterable<T> findAll();

    Iterable<T> findAllById(Iterable<ID> var1);

    long count();

    void deleteById(ID var1);

    void delete(T var1);

    void deleteAll(Iterable<? extends T> var1);

    void deleteAll();
}

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 用户信息数据表,并添加测试数据。

-- 判断数据表是否存在,存在则删除
DROP TABLE IF EXISTS tb_user;
 
-- 创建“用户信息”数据表
CREATE TABLE IF NOT EXISTS tb_user
( 
	user_id INT AUTO_INCREMENT PRIMARY KEY COMMENT '用户编号',
	user_name VARCHAR(50) NOT NULL COMMENT '用户姓名',
	blog_url VARCHAR(50) NOT NULL COMMENT '博客地址',
	remark VARCHAR(50) COMMENT '备注'
) COMMENT = '用户信息表';
 
-- 添加数据
INSERT INTO tb_user(user_name,blog_url,remark) VALUES('pan_junbiao的博客','https://blog.csdn.net/pan_junbiao','您好,欢迎访问 pan_junbiao的博客');
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配置文件中,添加如下依赖:

<!-- Spring Data JPA -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>

<!-- MySQL的JDBC数据库驱动 -->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.19</version>
</dependency>

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

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

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

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/db_admin?useSSL=false&amp
    username: root
    password: 123456
    driver-class-name: com.mysql.cj.jdbc.Driver
  jpa:
    database: MYSQL
    show-sql: true
    open-in-view: true
    properties:
      hibernate:
        enable_lazy_load_no_trans: true
        dialect: org.hibernate.dialect.MySQL5Dialect
        ddl-auto: update

3.3 实现增删改查代码

(1)实体层(Entity层)

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

package com.pjb.jpauserdemo.entity;

import javax.persistence.*;

/**
 * 用户信息实体类
 * @author pan_junbiao
 **/
@Entity
@Table(name = "tb_user")
public class UserInfo
{
    //用户ID
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "user_id")
    private int userId;

    //用户姓名
    @Column(name = "user_name")
    private String userName;

    //博客地址
    @Column(name = "blog_url")
    private String blogUrl;

    //备注
    private String remark;

    //省略getter与setter方法...
}

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

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

package com.pjb.jpauserdemo.dao;

import com.pjb.jpauserdemo.entity.UserInfo;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

/**
 * 用户信息数据库访问接口
 * @author pan_junbiao
 **/
@Repository
public interface UserDao extends JpaRepository<UserInfo,Integer>
{
}

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

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

package com.pjb.jpauserdemo.service;

import com.pjb.jpauserdemo.entity.UserInfo;
import java.util.List;

/**
 * 用户业务逻辑接口
 * @author pan_junbiao
 **/
public interface UserService
{
    /**
     * 根据用户ID,查询用户信息
     */
    public UserInfo findById(int userId);

    /**
     * 查询用户列表
     */
    public List<UserInfo> findAll();

    /**
     * 新增用户
     */
    public UserInfo save(UserInfo userInfo);

    /**
     * 修改用户
     */
    public UserInfo edit(UserInfo userInfo);

    /**
     * 删除用户
     */
    public boolean deleteById(int userId);
}

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

package com.pjb.jpauserdemo.service.impl;

import com.pjb.jpauserdemo.dao.UserDao;
import com.pjb.jpauserdemo.entity.UserInfo;
import com.pjb.jpauserdemo.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * 用户业务逻辑类
 * @author pan_junbiao
 **/
@Service
public class UserServiceImpl implements UserService
{
    @Autowired
    private UserDao userDao;

    /**
     * 根据用户ID,查询用户信息
     */
    @Override
    public UserInfo findById(int userId)
    {
        return userDao.findById(userId).get();
    }

    /**
     * 查询用户列表
     */
    @Override
    public List<UserInfo> findAll()
    {
        return userDao.findAll();
    }

    /**
     * 新增用户
     */
    @Override
    public UserInfo save(UserInfo userInfo)
    {
        return userDao.save(userInfo);
    }

    /**
     * 修改用户
     */
    @Override
    public UserInfo edit(UserInfo userInfo)
    {
        return userDao.save(userInfo);
    }

    /**
     * 删除用户
     */
    @Override
    public boolean deleteById(int userId)
    {
        boolean result = true;
        try
        {
            userDao.deleteById(userId);
        }
        catch(Exception ex)
        {
            result = false;
        }
        return result;
    }
}

3.4 执行测试

3.4.1 查询数据

@Autowired
private UserService userService;

/**
 * 测试:根据用户ID,查询用户信息
 * @author pan_junbiao
 */
@Test
public void findById()
{
    //查询用户编号为1的用户信息
    UserInfo user = userService.findById(1);

    if (user != null)
    {
        //打印结果
        System.out.println("用户编号:" + user.getUserId());
        System.out.println("用户姓名:" + user.getUserName());
        System.out.println("博客地址:" + user.getBlogUrl());
        System.out.println("备注信息:" + user.getRemark());
    }
}

执行结果:

3.4.2 查询列表

/**
 * 测试:查询用户列表
 * @author pan_junbiao
 */
@Test
public void findAll()
{
    //查询用户列表
    List<UserInfo> userList = userService.findAll();

    if (userList != null && userList.size() > 0)
    {
        for (UserInfo user : userList)
        {
            //打印结果
            System.out.println("用户编号:" + user.getUserId());
            System.out.println("用户姓名:" + user.getUserName());
            System.out.println("博客地址:" + user.getBlogUrl());
            System.out.println("备注信息:" + user.getRemark());
            System.out.println("===========================================");
        }
    }
}

执行结果:

3.4.3 新增操作

/**
 * 测试:新增用户
 * @author pan_junbiao
 */
@Test
public void save()
{
    //创建新用户
    UserInfo user = new UserInfo();
    user.setUserName("pan_junbiao的博客_03");
    user.setBlogUrl("https://blog.csdn.net/pan_junbiao");
    user.setRemark("您好,欢迎访问 pan_junbiao的博客");

    //执行新增操作
    userService.save(user);

    //如果新增成功,则可以获取自增主键
    //否则新增失败,则抛出异常
    if (user.getUserId() > 0)
    {
        System.out.println("新增用户成功,新增的用户信息:");
        System.out.println("用户编号:" + user.getUserId());
        System.out.println("用户姓名:" + user.getUserName());
        System.out.println("博客地址:" + user.getBlogUrl());
        System.out.println("备注信息:" + user.getRemark());
    }
}

执行结果:

查询数据表:

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

3.4.4 修改操作

/**
 * 测试:修改用户
 * @author pan_junbiao
 */
@Test
public void edit()
{
    //创建修改用户
    UserInfo user = new UserInfo();
    user.setUserId(3);
    user.setUserName("pan_junbiao的博客_04");
    user.setBlogUrl("https://blog.csdn.net/pan_junbiao");
    user.setRemark("您好,欢迎访问 pan_juniao的博客");

    //执行修改操作
    userService.edit(user);

    //如果没有抛出异常,则表示执行成功
    System.out.println("修改用户成功");
}

查询数据表:

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

3.4.5 删除操作

/**
 * 测试:删除用户
 * @author pan_junbiao
 */
@Test
public void deleteById()
{
    //执行新增操作
    boolean result = userService.deleteById(3);

    //打印结果
    if (result)
    {
        System.out.println("删除用户成功");
    }
    else
    {
        System.out.println("删除用户失败");
    }
}

查询数据表:

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

3.4.6 完整的测试代码

package com.pjb.jpauserdemo.service.impl;

import com.pjb.jpauserdemo.entity.UserInfo;
import com.pjb.jpauserdemo.service.UserService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import java.util.List;


/**
 * 用户信息业务逻辑测试类
 * @author pan_junbiao
 **/
@SpringBootTest
@RunWith(SpringRunner.class)
public class UserServiceImplTest
{
    @Autowired
    private UserService userService;

    /**
     * 测试:根据用户ID,查询用户信息
     * @author pan_junbiao
     */
    @Test
    public void findById()
    {
        //查询用户编号为1的用户信息
        UserInfo user = userService.findById(1);

        if (user != null)
        {
            //打印结果
            System.out.println("用户编号:" + user.getUserId());
            System.out.println("用户姓名:" + user.getUserName());
            System.out.println("博客地址:" + user.getBlogUrl());
            System.out.println("备注信息:" + user.getRemark());
            System.out.println("\n");
        }
    }

    /**
     * 测试:查询用户列表
     * @author pan_junbiao
     */
    @Test
    public void findAll()
    {
        //查询用户列表
        List<UserInfo> userList = userService.findAll();

        if (userList != null && userList.size() > 0)
        {
            for (UserInfo user : userList)
            {
                //打印结果
                System.out.println("用户编号:" + user.getUserId());
                System.out.println("用户姓名:" + user.getUserName());
                System.out.println("博客地址:" + user.getBlogUrl());
                System.out.println("备注信息:" + user.getRemark());
                System.out.println("===========================================");
            }
        }
    }

    /**
     * 测试:新增用户
     * @author pan_junbiao
     */
    @Test
    public void save()
    {
        //创建新用户
        UserInfo user = new UserInfo();
        user.setUserName("pan_junbiao的博客_03");
        user.setBlogUrl("https://blog.csdn.net/pan_junbiao");
        user.setRemark("您好,欢迎访问 pan_junbiao的博客");

        //执行新增操作
        userService.save(user);

        //如果新增成功,则可以获取自增主键
        //否则新增失败,则抛出异常
        if (user.getUserId() > 0)
        {
            System.out.println("新增用户成功,新增的用户信息:");
            System.out.println("用户编号:" + user.getUserId());
            System.out.println("用户姓名:" + user.getUserName());
            System.out.println("博客地址:" + user.getBlogUrl());
            System.out.println("备注信息:" + user.getRemark());
        }
    }

    /**
     * 测试:修改用户
     * @author pan_junbiao
     */
    @Test
    public void edit()
    {
        //创建修改用户
        UserInfo user = new UserInfo();
        user.setUserId(3);
        user.setUserName("pan_junbiao的博客_04");
        user.setBlogUrl("https://blog.csdn.net/pan_junbiao");
        user.setRemark("您好,欢迎访问 pan_juniao的博客");

        //执行修改操作
        userService.edit(user);

        //如果没有抛出异常,则表示执行成功
        System.out.println("修改用户成功");
    }

    /**
     * 测试:删除用户
     * @author pan_junbiao
     */
    @Test
    public void deleteById()
    {
        //执行新增操作
        boolean result = userService.deleteById(3);

        //打印结果
        if (result)
        {
            System.out.println("删除用户成功");
        }
        else
        {
            System.out.println("删除用户失败");
        }
    }
}
发布了377 篇原创文章 · 获赞 278 · 访问量 180万+

猜你喜欢

转载自blog.csdn.net/pan_junbiao/article/details/105245983