spring boot with data jpa

作者: JerryL_ | 来源:发表于2017-02-20 11:24 被阅读0次

在spring boot的项目中使用spring data jpa真的很简单,写起来真的是笔下生风,神清气爽。非常适合喜欢偷懒的人,可以让你抛开反复编写的dao层代码以及一些写吐了的简单查询语句。
首先spring data jpa用起来就很简单,再加上集成在spring boot的项目中,还省去了xml配置,就更是开箱即用了。

spring data jpa简介

首先jpa(Java Persistence API)是一种orm框架的规范,让一个实体类自身就可以通过注解描述其与数据库表的对应关系。
jpa只是一个接口规范,用的最多的实现是hibernate。而spring data jpa就是采用hibernate作为实现的基础上,又进行的一层封装,更加屏蔽掉了hibernate的使用细节,降低了学习门槛。

spring data jpa的使用

1.基本配置
要使用spring data jpa需要在pom.xml种添加一个依赖:

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

要访问数据库肯定需要配置数据库的url,账号密码等信息。
这些信息可以在application.yml文件中配置

spring:
  datasource:
   url: jdbc:mysql://127.0.0.1:3306/数据库名
   username: 账号
   password: 密码

这里先打断一下,如果想要修改数据源的实现,可以在java代码的配置类中配置想要的数据源实现的bean。
比如我使用alibaba的druid数据源实现,除了在pom.xml中加入依赖之外,需要在配置类中加入对应bean的配置:

    @Autowired
    Environment environment;
    @Bean
    public DataSource dataSource() throws SQLException {
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setUrl(environment.getProperty("spring.datasource.url"));
        dataSource.setUsername(environment.getProperty("spring.datasource.username"));//用户名
        dataSource.setPassword(environment.getProperty("spring.datasource.password"));//密码
        dataSource.setInitialSize(2);
        dataSource.setMaxActive(500);
        dataSource.setMinIdle(0);
        dataSource.setMaxWait(60000);
        dataSource.setValidationQuery("SELECT 1");
        dataSource.setTestOnBorrow(false);
        dataSource.setTestOnReturn(false);
        dataSource.setTestWhileIdle(true);
        dataSource.setPoolPreparedStatements(false);
        dataSource.setFilters("mergeStat");
        return dataSource;
    }

这是spring4推荐的使用java类进行配置的方式。

继续,然后就是spring data jpa的配置了,因为是采用hibernate来实现的,所以配置中与hibernate有一定联系:

spring: 
  jpa:
    hibernate:
      ddl-auto: update
    show-sql: true

其中ddl-auto有4种策略,与hibernate一样。
create:
每次启动项目,先删除之前创建的表结构,再根据实体类创建表结构。
create-drop :
每次启动项目,根据实体类创建表结构,每次终止项目,删除所有表结构。
update:
每次启动项目,验证实体类对应的数据库表结构,如果不一致就更新结构,如创建新表,新增字段等。
validate :
每次启动项目,验证实体类对应的数据库表结构,如果不一致就抛出异常。

一般使用update。

2.实体类
接下来随便写个实体类:

@Entity(name = "sys_student")
public class Student {
    @Id
    private String code;

    private String name;
    private String age;
    private String banji;

    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getAge() {
        return age;
    }

    public void setAge(String age) {
        this.age = age;
    }

    public String getBanji() {
        return banji;
    }

    public void setBanji(String banji) {
        this.banji = banji;
    }
}

@Entity注解表示该类是一个实体类,name属性表示对应的数据库表名。@Id注解顾名思义,就是指该属性作为数据库的主键。
jpa规范中还有很多注解,这里只用到了最主要的两个。

有了实体类,需要对这个实体类编写增删改查的代码。
此时便到了spring data jpa展现威力的时候了。

3.dao层接口
新建一个接口,作为student的dao层接口。

/**
 * Created by liuruijie on 2017/2/18.
 * student dao
 */
public interface StudentDao extends JpaRepository<Student, String>{
    //按照姓名和班级查询
    List<Student> findByNameAndBanji(String name, String banji);

    //如果配置了@Qurey注解,则会按照里面的sql语句进行查询
    @Query(value = "select s from #{#entityName} s where age<?1")
    List<Student> customselect(Integer age);
}

这个接口继承于JpaRepository接口,后者提供了几乎所有常用的crud方法。
写完dao层接口后,下一步通常是编写实现类,然而,到这里就行了,根本不用自己实现。

4.使用
我们使用一下这个接口,在controller中注入它。

/**
 * Created by liuruijie on 2017/2/18.
 * student controller
 */
@RestController
@RequestMapping("student")
public class StudentController {
    //注入自己建的dao接口
    @Autowired
    StudentDao studentDao;

    //根据主键获取
    @GetMapping("{id}")
    public Object selectOne(@PathVariable("id") String code){
        System.out.println(code);
        return studentDao.findOne(code);
    }

    //自定义查询1
    @GetMapping("nameAndBanji")
    public Object findByNameAndBanji(String name, String banji){
        return studentDao.findByNameAndBanji(name, banji);
    }

    //自定义查询2
    @GetMapping("age/{age}")
    public Object selectByAge(@PathVariable("age") Integer age){
        return studentDao.customselect(age);
    }

    //修改
    @PutMapping("{id}")
    public Object update(@PathVariable("id") String id, Student student) {
        student.setCode(id);
        return studentDao.save(student);
    }

    //新增
    @PostMapping
    public Object insertOne(Student student){
        studentDao.save(student);
        return "ok";
    }
}

测试一下是否真的能用。
先在数据库中插入几条记录。

插入记录 根据主键查询 自定义查询1 自定义查询2

发现完全没问题,也就是说只要我们继承了spring data jpa提供的接口,我们就可以获得基本的一些crud方法,并且自定义的方法也不用自己写实现就能使用。

自定义查询方法

spring data jpa自定义查询方法主要有3种方式
1.按一定规则命名的方法

Keyword Sample JPQL snippet
And findByLastnameAndFirstname … where x.lastname = ?1 and x.firstname = ?2
Or findByLastnameOrFirstname … where x.lastname = ?1 or x.firstname = ?2
Is,Equals findByFirstname,findByFirstnameIs,findByFirstnameEquals … where x.firstname = ?1
Between findByStartDateBetween … where x.startDate between ?1 and ?2
LessThan findByAgeLessThan … where x.age < ?1
LessThanEqual findByAgeLessThanEqual … where x.age <= ?1
GreaterThan findByAgeGreaterThan … where x.age > ?1
GreaterThanEqual findByAgeGreaterThanEqual … where x.age >= ?1
After findByStartDateAfter … where x.startDate > ?1
Before findByStartDateBefore … where x.startDate < ?1
IsNull findByAgeIsNull … where x.age is null
IsNotNull,NotNull findByAge(Is)NotNull … where x.age not null
Like findByFirstnameLike … where x.firstname like ?1
NotLike findByFirstnameNotLike … where x.firstname not like ?1
StartingWith findByFirstnameStartingWith … where x.firstname like ?1 (parameter bound with appended %)
EndingWith findByFirstnameEndingWith … where x.firstname like ?1 (parameter bound with prepended %)
Containing findByFirstnameContaining … where x.firstname like ?1 (parameter bound wrapped in %)
OrderBy findByAgeOrderByLastnameDesc … where x.age = ?1 order by x.lastname desc
Not findByLastnameNot … where x.lastname <> ?1
In findByAgeIn(Collection<Age> ages) … where x.age in ?1
NotIn findByAgeNotIn(Collection<Age> age) … where x.age not in ?1
True findByActiveTrue() … where x.active = true
False findByActiveFalse() … where x.active = false
IgnoreCase findByFirstnameIgnoreCase … where UPPER(x.firstame) = UPPER(?1)

2.@NamedQurey注解
这个注解是实体类上的注解,用于指定一个方法名对应的查询语句。

@Entity(name = "sys_student")
@NamedQuery(name = "User.namedquery"
        , query = "select s from sys_student s where s.age<20")
public class Student {
···
public interface StudentDao extends JpaRepository<Student, String>{
···
    //namedQuery
    List<Student> namedquery();
···

这个方式就是将某个名称和查询语句绑定在一起,此时调用namedquery()方法就相当于执行@NamedQurey中配置的查询语句。

3.@Qurey注解
这个注解是方法上的注解,作用于dao层接口的方法上,顾名思义,加上这个注解,就可以将一个查询语句与一个方法绑定起来。

public interface StudentDao extends JpaRepository<Student, String>{
···
    //如果配置了@Qurey注解,则会按照里面的sql语句进行查询
    @Query(value = "select s from #{#entityName} s where age<?1")
    List<Student> customselect(Integer age);
···

?是占位符,1是参数序号,从1开始。#{#entityName}是SpEl表达式,这里的值就是Student的实体名,即@Entity注解中设置的name。

相关文章

网友评论

    本文标题:spring boot with data jpa

    本文链接:https://www.haomeiwen.com/subject/pqarwttx.html