# 2.Spring-data-jpa

> Spring Data JPA特点：
>
> 高效
>
> 可迁移(顶层语句封装）
>
> 标准（java官方标准）

采用jdbc方式写的语句有些繁琐，jpa又做了很好的封装

![](https://3562539340-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfnT314x6hQ7gJbPKxx%2F-LfnTB6gvTwJcyb-RbKo%2F-LfnTJ9GIj-mwQVxONMD%2F2.flow.png?generation=1558862981591848\&alt=media)

jpa 处在Domain和Respository层

## 一、 配置数据源：

pom.xml 文件中加入依赖配置

```markup
<!-- 数据库 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <scope>runtime</scope>
</dependency>
```

![](https://3562539340-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfnT314x6hQ7gJbPKxx%2F-LfnTB6gvTwJcyb-RbKo%2F-LfnTJ9If_4yvioN9b7J%2F2.1.png?generation=1558862981420741\&alt=media)

可以发现jpa仍然依赖jdbc包

配置mysql

application.properties文件中，可以参考多环境配置根据不同环境配置不同的库

```
spring.datasource.url=jdbc:mysql://localhost/demodb?useUnicode=true&characterEncoding=utf-8

spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
```

## 二、 Jpa 配置

application.properties文件中，可以参考多环境配置根据不同环境配置不同的库

```
# JPA
spring.jpa.hibernate.ddl-auto=update

#显示 sql 语句
spring.jpa.show-sql=true
```

## 三、具体过程

![](https://3562539340-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfnT314x6hQ7gJbPKxx%2F-LfnTB6gvTwJcyb-RbKo%2F-LfnTJ9MRYmC0ynvO-cP%2F2.2.png?generation=1558862979617971\&alt=media)

选中的为需要开发文件

1.实体类

bean/DemoUserLog.java

```java
package com.shuju.test2.bean;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import java.util.Date;

@Entity
public class DemoUserLog {

    @Id
    @GeneratedValue
    private Integer id;

    @Column
    private Date createTime;

    @Column
    private String userName;

    @Column
    private String userIp;

    public Integer getId() {
        return id;
    }

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

    public Date getCreateTime() {
        return createTime;
    }

    public void setCreateTime(Date createTime) {
        this.createTime = createTime;
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public String getUserIp() {
        return userIp;
    }

    public void setUserIp(String userIp) {
        this.userIp = userIp;
    }

    @Override
    public String toString() {
        return "RoncooUserLog [id=" + id + ", createTime=" + createTime + ", userName=" + userName + ", userIp=" + userIp + "]";
    }
}
```

2.定义接口（继承 JpaRepository）

dao/DemoUserLogDao.java

这里继承了JpaRepository，里面封装了一些操作，只需要定义接口，无需写实现类，就可以实现Repository这一层大部分操作

> `<DemoUserLog, Integer>` 泛型，第一个是域对象，也就是需要操作的表对象，第二个是主键的数据类型

```java
package com.shuju.test2.dao;

import com.shuju.test2.bean.DemoUserLog;
import org.springframework.data.jpa.repository.JpaRepository;

public interface DemoUserLogDao extends JpaRepository<DemoUserLog, Integer> {

}
```

3.测试

```java
package com.shuju.test2;

import com.shuju.test2.bean.DemoUserLog;
import com.shuju.test2.dao.DemoUserLogDao;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import java.util.Date;

@RunWith(SpringRunner.class)
@SpringBootTest
public class Test2ApplicationTests {

    @Autowired
    private DemoUserLogDao demoUserLogDao;

    @Test
    public void insert() {
        DemoUserLog entity = new DemoUserLog();
        entity.setUserName("无境");
        entity.setUserIp("192.168.0.1");
        entity.setCreateTime(new Date());
        demoUserLogDao.save(entity);
    }


    @Test
    public void delete() {
        demoUserLogDao.deleteById(2);
    }


    @Test
    public void update() {

        DemoUserLog entity = new DemoUserLog();
        entity.setId(2);
        entity.setUserName("无境 2");
        entity.setUserIp("192.168.0.1");
        entity.setCreateTime(new Date());
        demoUserLogDao.save(entity);
    }


    @Test
    public void select() {
        DemoUserLog result = demoUserLogDao.findById(1).get();
        System.out.println(result);
    }
}
```

注意有可能因为版本问题jpa方法有所改变。

## 四、 扩展进行自定义的查询

1.使用内置的关键词查询

<http://docs.spring.io/spring-data/jpa/docs/1.10.2.RELEASE/reference/html/>

如果内置的不能满足，可以使用使用自定义语句查询

2.使用自定义语句查询各种语法，具体查看

<http://docs.spring.io/spring-data/jpa/docs/1.10.2.RELEASE/reference/html/>

这个优先级比第一点的高

```java
@Query(value = "select u from DemoUserLog u where u.userName=?1")
```

具体示例：

同时实现分页

修改接口文件：dao/DemoUserLogDao.java

```java
import com.shuju.test2.bean.DemoUserLog;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;

import java.util.List;

public interface DemoUserLogDao extends JpaRepository<DemoUserLog, Integer> {
    /**
     * @param userName
     * @return
     */
    @Query(value = "select u from DemoUserLog u where u.userName=?1")
    List<DemoUserLog> findByUserName(String userName);

    /**
     * @param string
     * @param string2
     * @return
     */
    List<DemoUserLog> findByUserNameAndUserIp(String string, String string2);

    /**
     * @param userName
     * @param pageable
     * @return
     */
    Page<DemoUserLog> findByUserName(String userName, Pageable pageable);

}
```

修改测试类

```java
package com.shuju.test2;

import com.shuju.test2.bean.DemoUserLog;
import com.shuju.test2.dao.DemoUserLogDao;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.test.context.junit4.SpringRunner;

import java.util.Date;
import java.util.List;

@RunWith(SpringRunner.class)
@SpringBootTest
public class Test2ApplicationTests {

    @Autowired
    private DemoUserLogDao demoUserLogDao;

    @Test
    public void insert() {
        DemoUserLog entity = new DemoUserLog();
        entity.setUserName("无境");
        entity.setUserIp("192.168.0.1");
        entity.setCreateTime(new Date());
        demoUserLogDao.save(entity);
    }


    @Test
    public void delete() {
        demoUserLogDao.deleteById(2);
    }


    @Test
    public void update() {

        DemoUserLog entity = new DemoUserLog();
        entity.setId(2);
        entity.setUserName("无境 2");
        entity.setUserIp("192.168.0.1");
        entity.setCreateTime(new Date());
        demoUserLogDao.save(entity);
    }


    @Test
    public void select() {
        DemoUserLog result = demoUserLogDao.findById(1).get();
        System.out.println(result);
    }

    @Test
    public void select2() {
        List<DemoUserLog> result = demoUserLogDao.findByUserName("无境");
        System.out.println(result);
    }

    @Test
    public void select3() {
        List<DemoUserLog> result = demoUserLogDao.findByUserNameAndUserIp("无境", "192.168.0.1");
        System.out.println(result);
    }

    // 分页
    @Test
    public void queryForPage() {
        Pageable pageable = new PageRequest.of(0, 20, new Sort(new Sort.Order(Direction.DESC, "id")));
        Page<DemoUserLog> result = demoUserLogDao.findByUserName("无境", pageable);
        System.out.println(result.getContent());
    }

}
```

## 资料

[spring boot 中使用 jpa以及jpa介绍](https://blog.csdn.net/wujiaqi0921/article/details/78789087)

[SpringBoot关于SpringDataJpa中findOne()方法报错问题](https://www.cnblogs.com/JohnEricCheng/p/8793718.html)

[springboot(五)：spring data jpa的使用](https://blog.csdn.net/ityouknow/article/details/52688664)

[springboot+jpa+thymeleaf增删改查示例](https://blog.csdn.net/ityouknow/article/details/78091284)
