SpringBoot数据访问3.2:SpringBoot整合JPA

SpringBoot数据访问3系列

3.1 SpringBoot整合MyBatis
3.2 SpringBoot整合JPA
3.3 SpringBoot整合Redis


SpringBoot整合JPA

  • SpringBoot数据访问3系列
  • 概括
  • 一、步骤截图
    • 1. 创建项目,添加mysql和jpa依赖,配置数据库连接
    • 2. 编写ORM实体类
      • 2.1 报错解决:idea中@Column的name属性值报错:Cannot resolve column 'a_id'
    • 3. 编写Repository接口
    • 4. 编写单元测试
      • 4.1 解决报错:java.lang.IllegalStateException: Failed to load ApplicationContext
  • 二、测试结果
  • 三、整体代码
    • 目录结构
    • 1. 全局配置文件(数据库连接)
    • 2. 实体类(@Entity标注的)
    • 3. DAO层接口(使用JPA框架对ORM关系的数据进行操作)
    • 5. 测试类(简单使用了Pageable分页查询)


概括

JPA(Java持久化API),是Sun公司官方提出的Java持久化规范,它为Java开发人员提供了一种对象/关系映射工具 管理Java中的关系型数据库,其主要目的是简化现有的持久化开发工作和整合ORM(对象关系映射),spring boot在JPA规范的基础上,利用其优点,提出了Spring Data JPA模块对其具有ORM关系的数据进行持久化操作
Spring Data JPA是Spring在ORM框架、JPA规范的基础上封装的一套JPA应用框架,提供增删改查等常用功能,使开发者能用较少的代码实现数据操作,同时还易于扩展。

本文主要介绍SpringBoot中如何使用JPA框架对ORM关系的数据

  1. JPA以及Spring Data JPA的介绍
  2. springboot项目中如何使用JPA对关系型数据库中的数据(ORM对象关系映射)进行操作
    ① 添加spring-boot-starter-data-jpa依赖
    ② 实体类(POJO类=>普通java类)=>@Entity注解标识
    ③ DAO层(自定义Repositroy接口)
    ④ 测试类(简单使用了Pageable分页查询)

一、步骤截图

1. 创建项目,添加mysql和jpa依赖,配置数据库连接

创建项目,添加两个依赖
SpringBoot数据访问3.2:SpringBoot整合JPA_第1张图片
在全局配置文件中,对数据库进行连接

# MySQl数据库springbootdata连接配置
# 数据库连接地址
spring.datasource.url=jdbc:mysql://localhost:3306/springbootdata?serverTimezone=UTC
# 数据库用户名&密码:
spring.datasource.username=root
spring.datasource.password=123456

如果在3.1 SpringBoot整合MyBatis的基础上修改,则需要在pom.xml中添加spring-boot-starter-data-jpa依赖

<dependency>
   <groupId>org.springframework.bootgroupId>
   <artifactId>spring-boot-starter-data-jpaartifactId>
dependency>

2. 编写ORM实体类

  1. @Entity:标注要与数据库做映射的实体类,默认情况下,数据表的名称是首字母小写的类名,可以用name属性指定映射的表名
    (设置ORM实体类,并指定映射的表名)
    @Entity(name = "t_comment")
  2. @Id:标注在类属性或getter()方法上,标识该类属性对应表中的主键(表明映射对应的主键)
  3. @GeneratedValue:与@Id注解标注在同一位置,用于表示属性对应主键的生成策略
    (设置主键自增长策略)
    @GeneratedValue(strategy = GenerationType.IDENTITY)
  4. @Column:标注在属性上,当类属性和表字段名不同时,用name属性表示该类属性对应的表字段名
    (指定映射的表字段名)
    @Column(name = "a_id")

创建com.wpz.domain包,创建Comment实体类
SpringBoot数据访问3.2:SpringBoot整合JPA_第2张图片

2.1 报错解决:idea中@Column的name属性值报错:Cannot resolve column ‘a_id’

SpringBoot数据访问3.2:SpringBoot整合JPA_第3张图片
按照图片步骤解决:
SpringBoot数据访问3.2:SpringBoot整合JPA_第4张图片
SpringBoot数据访问3.2:SpringBoot整合JPA_第5张图片
SpringBoot数据访问3.2:SpringBoot整合JPA_第6张图片
SpringBoot数据访问3.2:SpringBoot整合JPA_第7张图片
然后就ok啦
SpringBoot数据访问3.2:SpringBoot整合JPA_第8张图片

3. 编写Repository接口

  1. 使用Spring Boot JPA自定义Repository接口,必须继承XXRepository接口,T:要操作的实体类,D:实体类中主键数据类型
    ① JpaRepository接口继承关系
    SpringBoot数据访问3.2:SpringBoot整合JPA_第9张图片
  2. 在自定义接口中对数据进行操作 的主要方式:
    ① 自定义接口继承了JpaRepository接口,则默认包含了一些常用的CRUD
    ② 可以直接使用方法名关键字进行查询操作(注意是查询!)=>findBy+表字段名(列名)+[关键字:NotNull等]
    ③ 可以使用 @Query注解配合SQL语句进行数据查,改,删操作
    针对变更操作(改、删),无论是否使用了@Query,都必须在方法上添加@Transaction注解进行事务管理,否则会报InvalidDataAccessApiUsageException(无效数据访问api使用异常)。如果调用Repository接口方法的业务层Service类上添加了@Transaction注解,那Repository接口中就不用标了
    ⑤ 使用@Query执行变更操作(改、删)时,除了使用@Query还必须使用@Modifying注解表示数据变更

创建com.wpz.repository包,创建一个用于对数据库表t_comment进行操作Repository接口CommentRepository
SpringBoot数据访问3.2:SpringBoot整合JPA_第10张图片

4. 编写单元测试

在Chapter03jpaApplicationTests测试类当前位置创建一个JpaTests测试类,用于编写Jpa相关的单元测试
这里是步骤截图,整体代码在后面整体罗列
SpringBoot数据访问3.2:SpringBoot整合JPA_第11张图片
SpringBoot数据访问3.2:SpringBoot整合JPA_第12张图片
SpringBoot数据访问3.2:SpringBoot整合JPA_第13张图片

4.1 解决报错:java.lang.IllegalStateException: Failed to load ApplicationContext

报错解释内容是这样
SpringBoot数据访问3.2:SpringBoot整合JPA_第14张图片
SpringBoot数据访问3.2:SpringBoot整合JPA_第15张图片
我这里的原因是全局配置文件中没有连接mysql数据库

# MySQl数据库springbootdata连接配置
# 数据库连接地址
spring.datasource.url=jdbc:mysql://localhost:3306/springbootdata?serverTimezone=UTC
# 数据库用户名&密码:
spring.datasource.username=root
spring.datasource.password=123456

二、测试结果

运行JpaTests测试类
SpringBoot数据访问3.2:SpringBoot整合JPA_第16张图片


三、整体代码

目录结构

SpringBoot数据访问3.2:SpringBoot整合JPA_第17张图片

1. 全局配置文件(数据库连接)

# MySQl数据库springbootdata连接配置
# 数据库连接地址
spring.datasource.url=jdbc:mysql://localhost:3306/springbootdata?serverTimezone=UTC
# 数据库用户名&密码:
spring.datasource.username=root
spring.datasource.password=123456

2. 实体类(@Entity标注的)

package com.wpz.domain;

import javax.persistence.*;

/**
 * @author 王胖子
 * @version 1.0
 * ORM实体类
 */
//设置ORM实体类,并指定映射的表名
//@Entity:标注要与数据库做映射的实体类,默认情况下,数据表的名称是首字母小写的类名,可以用name属性指定映射的表名
@Entity(name = "t_comment")
public class Comment {
    //表明映射对应的主键
    //@Id:标注在类属性或getter()方法上,标识某一个属性对应表中的主键
    @Id
    //设置主键自增长策略
    //@GeneratedValue:与@Id注解标注在同一位置,用于表示属性对应主键的生成策略
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;//主键id
    private String content;//评论的内容
    private String author;//发表评论的人
    //指定映射的表字段名
    //@Column:标注在属性上,当类属性和表字段名不同时,用name属性表示该类属性对应的表字段名
    @Column(name = "a_id")
    private Integer aId;//关联t_article的主键(作为t_comment的外键)

    //下面是get、set、toString方法

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }

    public String getAuthor() {
        return author;
    }

    public void setAuthor(String author) {
        this.author = author;
    }

    public Integer getaId() {
        return aId;
    }

    public void setaId(Integer aId) {
        this.aId = aId;
    }

    @Override
    public String toString() {
        return "Comment{" +
                "id=" + id +
                ", content='" + content + '\'' +
                ", author='" + author + '\'' +
                ", aId=" + aId +
                '}';
    }
}

3. DAO层接口(使用JPA框架对ORM关系的数据进行操作)

package com.wpz.repository;

import com.wpz.domain.Comment;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * @author 王胖子
 * @version 1.0
 * Repository接口文件,用于对数据库表进行操作
 */
public interface CommentRepository extends JpaRepository<Comment, Integer> {
    //1. 查询author非空的Comment集合=>不需要标注解,因为这是JPA支持的方法名关键子查询方式
    List<Comment> findByAuthorNotNull();

    //2. 根据文章id(实体类中设置的表字段名对应的类属性名aid),分页查询Comment评论集合
    @Query("SELECT c FROM t_comment c WHERE c.aId=?1")
    List<Comment> getCommentPaged(Integer aid, Pageable pageable);

    //3. 使用原生SQL语句(使用表字段名a_id),根据文章id分页查询Comment评论集合
    @Query(value = "SELECT * FROM t_comment  WHERE a_Id=?1", nativeQuery = true)
    List<Comment> getCommentPaged2(Integer aid, Pageable pageable);

    //4. 根据评论id修改评论作者author
    @Transactional
    @Modifying
    @Query("UPDATE t_comment c SET c.author=?2 where c.id=?1")
    int updateComment(Integer id, String author);

    //5. 根据评论id删除评论
    @Transactional
    @Modifying
    @Query("DELETE FROM t_comment c where c.id=?1")
    int deleteComment(Integer id);
}

5. 测试类(简单使用了Pageable分页查询)

package com.wpz;

import com.wpz.domain.Comment;
import com.wpz.repository.CommentRepository;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;

import java.util.List;
import java.util.Optional;

/**
 * @author 王胖子
 * @version 1.0
 * JpaTests:用于编写Jpa相关的单元测试
 */
@SpringBootTest
public class JpaTests {
    @Autowired
    private CommentRepository repository;

    //1. 使用JpaRepository内部方法进行操作
    // findById(1)=>接口文件自己提供的查询方法,可以直接使用
    @Test
    public void selectComment() {
        Optional<Comment> optional = repository.findById(1);
        if (optional.isPresent()) {//查回来内容不为空
            System.out.println("内部方法findById(1)查询\n" + optional.get());//输出查出的内容
        }
        System.out.println();
    }

    //2. 使用方法名关键字findByAuthorNotNull()进行数据操作
    @Test
    public void selectCommentByKeys() {
        List<Comment> list = repository.findByAuthorNotNull();
        System.out.println("方法名关键字查询:作者非空时的评论\n" + list);
    }

    //3. 使用@Query注解进行操作=>根据文章id查询评论,并根据指定分页来显示查询结果
    @Test
    public void selectCommentPaged() {
        /*
            pageable封装了分页的参数,当前页page(开始页是0),和每页最多显示的条数3
            - aid=1时,查询的结果有4条,每页最多显示3条,所以共有2页(0页[3条]和1页[1条])
            - 这里我设置了当前页为1,表示我想要得到第1页的内容
            - 结果会出现第1页的一条内容
         */
        Pageable pageable = PageRequest.of(1, 3);
        List<Comment> currentPagedComment = repository.getCommentPaged(1, pageable);
        System.out.println("@Query注解查询:aid=1时第一页的评论\n" + currentPagedComment);
    }
}

你可能感兴趣的:(springboot实例练习,spring,boot,java,spring)