# 2.Spring-data-jpa

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

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

![](/files/-LfnTJ9GIj-mwQVxONMD)

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>
```

![](/files/-LfnTJ9If_4yvioN9b7J)

可以发现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
```

## 三、具体过程

![](/files/-LfnTJ9MRYmC0ynvO-cP)

选中的为需要开发文件

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)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://spring-boot.shujuwajue.com/guan-xi-xing-shu-ju-ku/spring-data-jpa.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
