SpringBoot 使用 JPA

JPA: Java Persistence API Java 持久层 API,也就是咱们用来操作数据库的框架

首先,咱们先来捋一下 SpringBoot 如何集成 JPA 框架

1. 首先要加入 JPA 的依赖包 ?:

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

2. 为了方便,我们再引入一个插件 Lombok ,有关 Lombok 的其他用法可以去百度一下 ?:

Lombok是一个Java库,能自动插入编辑器并构建工具,简化Java开发
说白了,通过这个库,在实体类上加入它设定的注解,这样咱们就可以不用写属性的 set、get 方法

<dependency>
	<groupId>org.projectlombok</groupId>
	<artifactId>lombok</artifactId>
	<optional>true</optional>
</dependency>

开启 Lombok ,这个要在 idea 上安装 Lombok 插件 ?,然后应用就好了


3. 现在咱们在数据库中创建一张数据表,我的数据库名为 jpa_test, 数据表名称 t_user ?,建表语句在下面 ?

CREATE TABLE `t_user` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
  `username` varchar(30) NOT NULL DEFAULT '' COMMENT '用户名',
  `password` varchar(50) NOT NULL DEFAULT '' COMMENT '密码',
  `real_name` varchar(10) NOT NULL DEFAULT '' COMMENT '真实姓名',
  `department_name` varchar(20) NOT NULL DEFAULT '' COMMENT '所在部门名称',
	`create_time` datetime NOT NULL COMMENT '创建时间',
	`update_time` datetime NOT NULL COMMENT '修改时间',
  PRIMARY KEY (`id`)
) DEFAULT CHARSET=utf8 COMMENT='用户表';

4. 现在进行数据源的配置 ?,打开 application.properties ,填入下面 ? 的内容,根据自己的数据库信息的不同,请自行修改,不要照搬全复制!

# datasource 配置
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://127.0.0.1/jpa_test?serverTimezone=GMT%2b8&useUnicode=yes&characterEncoding=UTF-8&useSSL=false
spring.datasource.username=root
spring.datasource.password=123

5. 现在咱们配置一下 jpa,打开 application.properties ,填入下面 ? 的内容

# jpa 配置
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
spring.jpa.properties.hibernate.hbm2ddl.auto=validate
spring.jpa.show-sql=true

具体的配置详情信息,自行百度,我这里只是列举了一般开发所需要进行的配置

然后咱们再来一下,具体的代码编写

1. 老样子,首先要弄个实体类,创建一个 entity 包,新建一个 UserEntity 实体类 ?

package mr.s.jpa.entity;

import lombok.Data;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;

import javax.persistence.*;
import java.sql.Timestamp;

@Data
@Entity
@Table(name = "t_user")
@EntityListeners(AuditingEntityListener.class)
public class UserEntity {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String username;
    private String password;
    private String realName;
    private String departmentName;

    @CreatedDate
    private Timestamp createTime;

    @LastModifiedDate
    private Timestamp updateTime;
}

画重点!!!!!!

上面的实体类中有,@CreateDate@LastModifiedDate 这两个注解,这两个注解有啥用呢?为了是让我们进行插入和修改记录时,时间自动更新,这个特别方便,但是方便是方便了,我们也需要做一些其他的配置,在实体类上加入@EntityListeners(AuditingEntityListener.class) 注解,在启动类,加上 @EnableJpaAuditing 注解 


2. 现在需要创建 repository 包,创建 UserRepository 接口类 ?

package mr.s.jpa.repository;

import mr.s.jpa.entity.UserEntity;
import org.springframework.data.jpa.repository.JpaRepository;

public interface UserRepository extends JpaRepository<UserEntity, Long> {
}

 画重点!!!!!!

UserRepository 接口要继承 JpaRepository接口,而且要注意,JpaRepository<T, ID> T 表示实体类,ID 表示这个实体类的主键

额外知识点!!!!!!

平常我们可能会遇到主键是两个以上的字段构成的,这时候我们怎么处理呢?看下面 ?

这是两个字段组成的主键实体类 ?

@Data
@Entity
@Table(name = "t_user_role")
@EntityListeners(AuditingEntityListener.class)
@IdClass(UserRoleEntity.UserRolePrimaryKey.class)
public class UserRoleEntity {

    @Id
    private Integer userId;

    @Id
    private Integer roleId;

    private String operator;

    @CreatedDate
    private Timestamp createTime;

    @LastModifiedDate
    private Timestamp updateTime;

    @Data
    public static class UserRolePrimaryKey implements Serializable {

        private static final long serialVersionUID = -6861842133302907913L;

        private Integer userId;

        private Integer roleId;
    }
}

这是两个字段组成主键的实体类操作接口 ?

public interface UserRoleRepository extends JpaRepository<UserRoleEntity, UserRoleEntity.UserRolePrimaryKey> {
  
}

准备工作都已经做完了,现在咱们开始写一些基本的增删查改吧

1. 查询(查询有很多种,下面依次讲解!)

根据主键进行查询

@Autowired
private UserRepository userRepository;

@Test
public void testGet() {
	Optional<UserEntity> userEntityOptional = userRepository.findById(1L);
	// 判断查询结果是否为空
	if (userEntityOptional.isPresent()) {
		// 获得查询结果
		UserEntity userEntity = userEntityOptional.get();
		System.out.println(userEntity);
	}
}

根据条件进行查询,比如说根据用户名这样的查询,这种条件查询有两种解决方案
通过 Example 进行条件查询

@Autowired
private UserRepository userRepository;

@Test
public void testGet(){
	UserEntity userEntity = new UserEntity();
	// 设置查询条件
	userEntity.setUsername("zhangsan");
	Example<UserEntity> userEntityExample = Example.of(userEntity);
	// 获取查询结果集合
	List<UserEntity> userEntityList = userRepository.findAll(userEntityExample);
	System.out.println(userEntityList.size());
	// 获取单个查询结果
	Optional<UserEntity> userEntityOptional = userRepository.findOne(userEntityExample);
	if (userEntityOptional.isPresent()){
		UserEntity saveEntity = userEntityOptional.get();
		System.out.println(saveEntity);
	}
}

在 UserRepository 接口写代码的方式

public interface UserRepository extends JpaRepository<UserEntity, Long> {
    UserEntity findByUsername(String username);
}
@Autowired
private UserRepository userRepository;

@Test
public void testGet() {
	UserEntity userEntity = userRepository.findByUsername("zhangsan");
	System.out.println(userEntity);
}

在 UserRepository 接口上写原生 SQL 的方式(注意:@Param("userId") 和 SQL 语句中的 :userId 对应)

public interface UserRepository extends JpaRepository<UserEntity, Long> {
    
    @Query(value = "select t_user.* from t_user where t_user.id = :userId", nativeQuery = true)
    UserEntity findByUserId(@Param("userId") Long userId);
}
@Autowired
private UserRepository userRepository;

@Test
public void testGet() {
	UserEntity userEntity = userRepository.findByUserId(1L);
	System.out.println(userEntity);
}

查询排序

@Autowired
private UserRepository userRepository;

@Test
public void testGet() {
	Sort sort = new Sort(Sort.Direction.ASC, "id");
	List<UserEntity> userEntityList = userRepository.findAll(sort);
	System.out.println(userEntityList.size());
}

分页查询

@Autowired
private UserRepository userRepository;

@Test
public void testGet() {
	int page = 1;
	int limit = 10;
	// 注意,页号是从 0 开始的
	Pageable pageable =  PageRequest.of(page - 1, limit);
	Page<UserEntity> userEntityPage = userRepository.findAll(pageable);
	List<UserEntity> userEntityList = userEntityPage.getContent();
	System.out.println(userEntityList.size());
}

2. 添加(注意要加上,@Transactional 事务注解)

@Autowired
private UserRepository userRepository;

@Transactional(rollbackFor = Exception.class)
@Test
public void testAdd() {
	UserEntity userEntity = new UserEntity();
	userEntity.setUsername("zhangsan");
	userEntity.setPassword("123");
	userEntity.setRealName("张三");
	userEntity.setDepartmentName("研发部");
	userRepository.saveAndFlush(userEntity);
}

3. 修改(修改和添加的区别是:修改要求实体类有主键,且主键在数据库中已经存在)

只更新不为空的字段!!!

@Autowired
private UserRepository userRepository;

@Transactional(rollbackFor = Exception.class)
@Test
public void testEdit() {
	UserEntity userEntity = new UserEntity();
	userEntity.setId(1L);
	userEntity.setUsername("zhangsan");
	userRepository.saveAndFlush(userEntity);
}

4. 删除(删除也有很多种,可以根据主键删除,可以根据条件删除,条件删除可以使用 Example 也可以在 UserRepository 接口中写对应的方法,这里只给出根据主键删除,其余的自己研究尝试一下就ok了)

@Autowired
private UserRepository userRepository;

@Transactional(rollbackFor = Exception.class)
@Test
public void testDel() {
	userRepository.deleteById(1L);
}

最后来个总结,JPA 很强大,可以做很多的事情,可以自己多多尝试,上面只是列举了一些简单常用的方法,对了,使用 Example 和 通过 Repository 中自己写的方法,两种都可以,看你是怎么选择了,我比较倾向通过 Repository 中自己写的方法(如果是条件单一),条件要是很多就会使用 Example 了 (*^_^*)

如果觉得有帮助的话,点个赞再走!!! 嘻嘻 o(* ̄▽ ̄*)ブ

发布了92 篇原创文章 · 获赞 23 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/assiduous_me/article/details/100700937