SpringBoot - 使用Spring Data JPA操作数据库1(安装配置,基本用法)

作者: hangge 发布时间: 2020-01-31 浏览: 2858 次 编辑

一、基本介绍

1,什么是 JPA

  • JPAJava Persistence API 的简称,中文名 Java 持久层 API
  • 我们都知道 Hibernate 框架是一个 ORM 框架,而 JPA 则是一种 ORM 规范。JPAHibernate 的关系就像是 JDBCJDBC 驱动的关系,即 JPA 制定了 ORM 规范,而 Hibernate 是这些规范的实现。因此从功能来说,JPA 相当于 Hibernate 的一个子集。

事实上,是先有 Hibernate 后有 JPAJPA 规范的起草者也是 Hibernate 的作者。

2,什么是 Spring Data

  • Spring DataSpring 的一个子项目,致力于简化数据库访问,通过规范的方法名称来分析开发者的一同,进而减少数据访问层的代码量。
  • Spring Data 不仅支持关系型数据库,也支持非关系型数据库。
  • Spring Data JPA 可以有效地简化关系型数据库访问代码。

3,安装配置

(1)首先编辑 pom.xml 文件,添加相关依赖:spring-boot-starter-data-jpa:提供对 Spring Data JPA 的支持
mysql-connector-javaMySQL 数据库驱动
druidDruid 是阿里巴巴开发的号称为监控而生的数据库连接池,也是目前最好的数据库连接池。

<!-- Spring Data JPA 依赖 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
 
<!-- 数据库驱动依赖 -->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
</dependency>
 
<!-- 数据库连接池 -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid</artifactId>
    <version>1.1.9</version>
</dependency>

(2)接着在 application.properties 中配置数据库基本信息以及 JPA 相关配置:

spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.url=jdbc:mysql://localhost:3306/hangge
spring.datasource.username=root
spring.datasource.password=hangge1234
#是否在控制台打印JPA执行过程生成的SQL
spring.jpa.show-sql=true 
#表示JPA对应的数据库是MySQL
spring.jpa.database=mysql
#表示在项目启动时根据实体类更新数据库中的表
spring.jpa.hibernate.ddl-auto=update
#表示使用的数据库方言是MySQL57Dialect
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL57Dialect

二、基本用法

1,创建实体类

首先我们创建 Book 实体类(注意:由于我们前面的 JPA 配置,数据库不需要预先创建对应的表,程序启动后会自动生成)

代码说明:

  • @Entity 注解表示该类是一个实体类,在项目启动时会根据该类自动生成一张表,表的名称即 @Entity 注解中的 name 值,如果不配置 name,默认表名为类名。
  • 所有的实体类都要有主键,@Id 注解表示该属性是一个主键,@GeneratedValue 注解表示主键自动生成,strategy 则表示主键的生成策略。
  • 默认情况下,生成的表中字段的名称就是实体类中的属性的名称,通过 @Colume 注解可以定制生成的字段的属性,name 表示该属性对应的数据库表中的字段名称,nullable 表示该字段非空。
  • @Transient 注解表示在生成数据库中的表时,该属性被忽略,即不生成对应的字段。
@Entity(name = "t_book")
@Setter
@Getter
@NoArgsConstructor
public class Book {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;
 
    @Column(name = "book_name", nullable = false)
    private String name;
    private String author;
    private Float price;
 
    @Transient
    private String description;
}

创建数据库访问层

接着创建 BookDao 接口,继承 JpaRepository,代码如下:

代码说明:

  • 自定义的 BookDao 继承自 JpaRepositoryJpaRepository 中提供了一些基本的数据操作方法,有基本的增删改查、分页查询、排序查询等。
  • 12 个查询方法我们使用的是既定的方法命名规则。在 Spring Data JPA 中,只要方法的定义符合既定规范,Spring Data 就能分析出开发者的意图,从而避免开发者自定义 SQL
  • 3 个方法我们使用原生的 SQL 进行查询(nativeQuery = true 表示使用原生的 SQL 查询)
  • 4 个方法使用默认的 JPQL 语句。JPQL 是一种面向对象表达式语句,可以将 SQL 语法和简单查询语义绑定在一起。使用这种语言编写的查询是可移植的,可以编译成所有主流数据库服务器上的 SQLJPQL 与原生 SQL 语句类似,并且完全面向对象,通过类名和属性访问,而不是表名和表的属性(类似于 HibernateHQL)。这里的查询我们使用 :id:name 这种方式来进行参数绑定。注意:这里使用的列名是属性名称而不是数据库中列的名称。
  • 5 个方法同样使用 JPQL 查询,不同的是传参方式使用 ?1?2 这种方式。注意:方法中参数的顺序要与参数声明的顺序一致。
  • 如果 BookDao 中的方法涉及修改操作,就需要添加 @Modifying 注解并添加事务。
public interface BookDao extends JpaRepository {
    // 查询以某个字符开始的所有书(使用既定规范命名的方法进行查询)
    List getBooksByAuthorStartingWith(String author);
 
    // 查询单价大衣某个值的所有书(使用既定规范命名的方法进行查询)
    List getBooksByPriceGreaterThan(Float price);
 
    // 查询id最大的书(使用原生的SQL进行查询)
    @Query(value = "select * from t_book where id=(select max(id) from t_book)", nativeQuery = true)
    Book getMaxIdBook();
 
    // 根据id和author进行查询(使用JPQL语句查询)
    @Query("select b from t_book b where b.id>:id and b.author=:author")
    List getBookByIdAndAuthor(@Param("author") String author, @Param("id") Integer id);
 
    // 根据id和name进行查询(使用JPQL语句查询,不过传参使用?1、?2这种方式)
    @Query("select b from t_book b where b.id getBookByIdAndName(String name, Integer id);
}

3,运行测试

(1)创建一个 Contoller,调用 BookDaosave 方法将数据保存到数据库中。

注意save 方法是 JpaRepository 接口原生就提供的。

@RestController
public class HelloController {
 
    @Autowired
    BookDao bookDao;
 
    @RequestMapping("/save")
    public void save(){
        Book book = new Book();
        book.setName("时间的秩序");
        book.setAuthor("卡洛·罗韦利");
        book.setPrice(56f);
        bookDao.save(book); //使用save方法将数据保存到数据库
        return;
    }
}

原文:SpringBoot - 使用Spring Data JPA操作数据库1(安装配置,基本用法)

(2)下面是使用 BookDaofindAll 方法进行分页查询。该方法返回值为 Page<Book>,该对象中包含有分页常用数据,例如总记录数、总页数、没页记录数、当前页记录数等。

注意findAll 方法同样是 JpaRepository 接口原生就提供的。

@RestController
public class HelloController {
 
    @Autowired
    BookDao bookDao;
 
    @RequestMapping("/findAll")
    public void findAll() {
        PageRequest pageable = PageRequest.of(1,2); //第一个参数是页数,从0开始。第二个参数为每页显示条数
        Page page = bookDao.findAll(pageable);
        System.out.println("总页数:" + page.getTotalPages());
        System.out.println("总记录数:" + page.getTotalElements());
        System.out.println("查询结果:" + page.getContent());
        System.out.println("当前页数:" + (page.getNumber()+1));
        System.out.println("当前记录数:" + page.getNumberOfElements());
        System.out.println("每页记录数:" + page.getSize());
    }
}

原文:SpringBoot - 使用Spring Data JPA操作数据库1(安装配置,基本用法)


(3)下面是调用 BookDao 中各个自定义的方法进行数据查询。

@RestController
public class HelloController {
 
    @Autowired
    BookDao bookDao;
 
    @RequestMapping("/search")
    public void search() {
        List bs1 = bookDao.getBooksByAuthorStartingWith("卡");
        List bs2 = bookDao.getBooksByPriceGreaterThan(60f);
        Book b = bookDao.getMaxIdBook();
        List bs3 = bookDao.getBookByIdAndAuthor("冯唐", 2);
        List bs4 = bookDao.getBookByIdAndName("人", 4);
 
        System.out.println("作者名是'卡'开头的书籍:" + bs1);
        System.out.println("价格超过60元的书籍:" + bs2);
        System.out.println("id最大的书籍:" + b);
        System.out.println("id大于1且作者为'冯唐'的书籍:" + bs3);
        System.out.println("id小于4且书名包含'人'的书籍:" + bs4);
    }
}

原文:SpringBoot - 使用Spring Data JPA操作数据库1(安装配置,基本用法)

附:方法命名规则

Spring Data JPA 中,只要方法的定义符合既定规范,Spring Data 就能分析出开发者的意图,从而避免开发者自定义 SQL

所谓的既定规范,就是一定的方法命名规则。支持的命名规则如下表格。

关键字方法命名sql where字句
AndfindByNameAndPwdwhere name= ? and pwd =?
OrfindByNameOrSexwhere name= ? or sex=?
IsEqualsfindById,findByIdEqualswhere id= ?
BetweenfindByIdBetweenwhere id between ? and ?
LessThanfindByIdLessThanwhere id < ?
LessThanEqualsfindByIdLessThanEqualswhere id <= ?
GreaterThanfindByIdGreaterThanwhere id > ?
GreaterThanEqualsfindByIdGreaterThanEqualswhere id > = ?
AfterfindByIdAfterwhere id > ?
BeforefindByIdBeforewhere id < ?
IsNullfindByNameIsNullwhere name is null
isNotNullNotNullfindByNameNotNullwhere name is not null
LikefindByNameLikewhere name like ?
NotLikefindByNameNotLikewhere name not like ?
StartingWithfindByNameStartingWithwhere name like '?%'
EndingWithfindByNameEndingWithwhere name like '%?'
ContainingfindByNameContainingwhere name like '%?%'
OrderByfindByIdOrderByXDescwhere id=? order by x desc
NotfindByNameNotwhere name <> ?
InfindByIdIn(Collection<?> c)where id in (?)
NotInfindByNameNotwhere name <> ?
TruefindByAaaTuewhere aaa = true
FalsefindByAaaFalsewhere aaa = false
IgnoreCasefindByNameIgnoreCasewhere UPPER(name)=UPPER(?)
topfindTop100top 10/where ROWNUM <=10