【从零入门系列-3】Spring Boot 之 数据库操作

【从零入门系列-3】Spring Boot 之 数据库操作

文章系列


前言

前一章简述了如何设计实现数据库实体类,本篇文章在此基础上进行开发,完成对该数据库表的常用操作,主要包括使用Spring Data JPA进行简单的增删改查和复杂查询操作。

Spring Data JPASpring提供的一套简化JPA开发的框架,按照约定好的【方法命名规则】写dao层接口,就可以在不写接口实现的情况下,实现对数据库的访问和操作,同时提供了很多除了CRUD之外的功能,如分页、排序、复杂查询等等,Spring Data JPA 可以理解为 JPA 规范的再次封装抽象,底层还是使用了 Hibernate 的 JPA 技术实现。通过引入Spring Data JPA后,我们可以基本不用写代码就能实现对数据库的增删改查操作。

此外,由于Spring Data JPA自带实现了很多内置的后台操作方法,因此在调用方法时必须根据其规范使用,深刻理解规范约定


表的基本操作实现(CRUD)

在这里,先介绍一下JpaRepository,这是类型为interface的一组接口规范,是基于JPA的Repository接口,能够极大地减少访问数据库的代码编写,是实现Spring Data JPA技术访问数据库的关键接口。

  • 编写数据操作接口

在使用时,我们只需要定义一个继承该接口类型的接口即可实现对表的基本操作方法,在此我们需要对实体类Book进行操作,因此在Dao目录上右键New->Java Class,然后设置名称为BookJpaRepository,kind类型选Interface即可,然后添加注解及继承自JpaRepository,文件BookJpaRepository.java内容如下所示:

package com.arbboter.demolibrary.Dao;

import com.arbboter.demolibrary.Domain.Book;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface BookJpaRepository extends JpaRepository<Book, Integer> {
   
}

@Repository持久层组件,用于标注数据访问组件,即DAO组件,此时配合上上一篇文章中的JPA配置,我们就可以进行增删改查啦,不用添加任何其他代码,因为JpaRepository已经帮我们实现好了。

  • 编写测试用例代码

打开框架自动生成的测试代码文件DemoLibraryApplicationTests.java编写测试用例,测试增删改查效果,测试代码如下:

@RunWith(SpringRunner.class)
@SpringBootTest
public class DemoLibraryApplicationTests {
   
    /**
     * @Autowired 注释,它可以对类成员变量、方法及构造函数进行标注,完成自动装配的工作。 
     * 通过 @Autowired的使用来消除 set ,get方法,简化程序代码
     * 此处自动装配我们实现的BookJpaRepository接口,然后可以直接使用bookJpaRepository操作数据库
     * 如果不加@Autowired,直接使用bookJpaRepository,程序运行会抛出异常
     */
    @Autowired
    private BookJpaRepository bookJpaRepository;

    @Test
    public void contextLoads() {
   
        Book book = new Book();

        // 增
        book.setName("Spring Boot 入门学习实践");
        book.setAuthor("arbboter");
        book.setImage("https://ss0.bdstatic.com/70cFuHSh_Q1YnxGkpoWK1HF6hhy/it/u=2656353677,2997395625&fm=26&gp=0.jpg");
        bookJpaRepository.save(book);
        System.out.println("保存数据成功:" + book);

        // 查
        book = bookJpaRepository.findById(book.getId()).get();
        System.out.println("新增后根据ID查询结果:" + book);

        // 修改
        book.setName("Spring Boot 入门学习实践(修改版)");
        bookJpaRepository.save(book);
        System.out.println("修改后根据ID查询结果:" + book);

        // 删除
        bookJpaRepository.deleteById(book.getId());
    }
}

注意在测试代码用需要对属性bookJpaRepository使用@Autowired自动注入实现初始化,@Autowired注解,它可以对类成员变量、方法及构造函数进行标注,完成自动装配的工作。

  • 测试结果

[外链图片转存失败(img-sGwiAwwL-1566186700190)(https://raw.githubusercontent.com/arbboter/resource/master/segmentfault/image/SpringBoot/20190514-%E6%95%B0%E6%8D%AE%E5%BA%93%E6%93%8D%E4%BD%9C/1557817269112.png)]
通过测试结果我们可以看到,程序已经能够对表数据进行增删改查,且我们通过删除SQL可以观察到,获取生成记录ID的SQL语句为:

Hibernate: select next_val as id_val from hibernate_sequence with (updlock, holdlock, rowlock)
Hibernate: update hibernate_sequence set next_val= ? where next_val=?

因此可推断出,JpaRepository对默认的自增ID均使用表hibernate_sequence作为ID生成器,所有默认的ID表公用此ID生成器。

通过上述例子,我们可以发现,虽然我们没有写任何一条SQL语句,但是程序已经可以正常操作数据库了,这对苦逼的C++程序员手写SQL来说真是不要说太幸福哈。不过上述示例也存在一些问题,数据查询均是通过ID操作的,但是实际使用中,数据查询还需要根据其他条件,比如书名作者,是不是需要手写SQL实现?答案是否定的,JpaRepository支持接口规范方法名查询,意思是如果在接口中定义的查询方法符合它的命名规则,就可以不用写实现,框架自动提供实现的方法,只需要声明无需自己实现即可使用。


JpaRepository的规范方法名查询

在我们实现的接口中,可以只定义查询方法,如果是符合规范的,可以不用写实现,就可以直接使用。

JpaRepository会对方法名进行校验,不符合规范会报错,除非添加@Query注解。

在本示例中,我们希望通过书名和作者的常用场景提供查询方案,可按下述实现:


@Repository
public interface BookJpaRepository extends JpaRepository<Book, Integer> {
   
    /**
     * 根据书名精准查询书籍列表
     * @param name 查询的书名
     * @return 名字为name的书籍列表
     */
    List<Book> findByName(String name);

    /**
     *
     * 根据书名模糊查询书籍列表
     * @param name 查询的书名
     * @return 查询结果
     */
    List<Book> findByNameLike(String name);

    /**
     * 根据书名和作者查询,注意参数列表顺序和名字顺序保持一致(约定!)
     * @param name 查询的书名
     * @param author 查询的作者名
     * @return 查询结果
     */
    List<Book> findByNameAndAuthor(String name, String author);

    /**
     * 根据书名或作者查询,注意参数列表顺序和名字顺序保持一致(约定!)
     * @param name 查询的书名
     * @param author 查询的作者名
     * @return 查询结果
     */
    List<Book> findByNameOrAuthor(String name, String author);

    /**
     * 根据作者集合查询
     * @param authors 书列表名
     * @return
     */
    List<Book> findByAuthorIn(Collection authors);
}

上述代码通,我们实现了模糊、精准、And和Or以及In的查询定义,都是根据JPA的命名规范定义方法,此时我们不用自己去实现方法,直接可以调用。

测试代码如下:

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值