初次使用 spring data jpa

先了解Spring Data

  Spring Data是一个用于简化数据库访问,并支持云服务的开源框架。其主要目标是使得对数据的访问变得方便快捷,并支持map-reduce框架和云计算数据服务。 Spring Data 包含多个子项目:其中 JPA 主要是简化创建 JPA 数据访问层和跨存储的持久层功能。

一些核心接口

  • Repository:最顶层的接口,是一个空接口,目的是为了统一所有 Repository 的类型,且能让组件扫描的时候自动识别。
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package org.springframework.data.repository;

import java.io.Serializable;

public interface Repository<T, ID extends Serializable> {
}
  • CrudRepository:是Repository 的子接口,提供 CRUD 功能。
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package org.springframework.data.repository;

import java.io.Serializable;

@NoRepositoryBean
public interface CrudRepository<T, ID extends Serializable> extends Repository<T, ID> {
    <S extends T> S save(S var1);

    <S extends T> Iterable<S> save(Iterable<S> var1);

    T findOne(ID var1);

    boolean exists(ID var1);

    Iterable<T> findAll();

    Iterable<T> findAll(Iterable<ID> var1);

    long count();

    void delete(ID var1);

    void delete(T var1);

    void delete(Iterable<? extends T> var1);

    void deleteAll();
}
  • PagingAndSortingRepository:是CrudRepository的子接口,添加分页和排序的功能。
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package org.springframework.data.repository;

import java.io.Serializable;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;

@NoRepositoryBean
public interface PagingAndSortingRepository<T, ID extends Serializable> extends CrudRepository<T, ID> {
    Iterable<T> findAll(Sort var1);

    Page<T> findAll(Pageable var1);
}
  • JpaRepository:是PagingAndSortingRepository的子接口,增加了一些实用的功能,比如:批量操作等。
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package org.springframework.data.jpa.repository;

import java.io.Serializable;
import java.util.List;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.Sort;
import org.springframework.data.repository.NoRepositoryBean;
import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.data.repository.query.QueryByExampleExecutor;

@NoRepositoryBean
public interface JpaRepository<T, ID extends Serializable> extends PagingAndSortingRepository<T, ID>, QueryByExampleExecutor<T> {
    List<T> findAll();

    List<T> findAll(Sort var1);

    List<T> findAll(Iterable<ID> var1);

    <S extends T> List<S> save(Iterable<S> var1);

    void flush();

    <S extends T> S saveAndFlush(S var1);

    void deleteInBatch(Iterable<T> var1);

    void deleteAllInBatch();

    T getOne(ID var1);

    <S extends T> List<S> findAll(Example<S> var1);

    <S extends T> List<S> findAll(Example<S> var1, Sort var2);
}
  • JpaSpecificationExecutor:用来做负责查询的接口。
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package org.springframework.data.jpa.repository;

import java.util.List;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;

public interface JpaSpecificationExecutor<T> {
    T findOne(Specification<T> var1);

    List<T> findAll(Specification<T> var1);

    Page<T> findAll(Specification<T> var1, Pageable var2);

    List<T> findAll(Specification<T> var1, Sort var2);

    long count(Specification<T> var1);
}

  上面的 Specification 表示Spring data jpa 提供的一个查询规范,需要做复杂查询时,围绕这个规范设置查询条件即可。

 

使用maven构建测试项目

  • 新建 spring boot 项目名为 jpa-learn,添加 jpa 依赖和数据库依赖,详细如下:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.daqsoft</groupId>
    <artifactId>jpa-learn</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>jpa-learn</name>
    <description>Demo project for Spring Boot</description>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.6.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <!--连接数据库-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>


</project>
  • 在配置文件 application.properties 或者 application.yml 中配置数据库相关连接(本地使用yml)
spring:
  datasource:
    #url: jdbc:oracle:thin:@192.168.0.159:1521:daqsoftFramework
    url: jdbc:mysql://192.168.2.67:3306/jpatest
    username: root
    password: root
    driver-class-name: com.mysql.jdbc.Driver
  • 创建实体类与数据库表映射
package com.daqsoft.entity;

import javax.persistence.*;
import java.io.Serializable;

/**
 * @author lxx
 */

@Entity
@Table(name = "USER")
public class User implements Serializable {

    /**
     * 主键
     */
    @Id
    @Column(name = "id")
    @GeneratedValue(strategy= GenerationType.IDENTITY)
    private Long id;

    @Column(name = "name")
    private String name;

    @Column(name = "age")
    private int age;

    public Long getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}
  • 根据需要创建 类 / 接口 继承 上述所写 JPA 核心接口(接口也是按照需要继承)。
package com.daqsoft.dao;

import com.daqsoft.entity.User;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Component;

import java.util.List;

/**
 * @author lxx
 */

@Component
public interface UserDao extends JpaRepository<User, Long>, JpaSpecificationExecutor<User>{

    public List<User> findByAge(int age);

    @Query("select u from User u where id = :id")
    public User findUser(@Param(value = "id") long id);


}

 

  • 创建业务层实现业务功能(按需构建)
package com.daqsoft.service;

import com.daqsoft.dao.UserDao;
import com.daqsoft.entity.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.util.ArrayList;
import java.util.List;

/**
 * @author lxx
 */

@Service
public class UserService {
    @Autowired
    private UserDao userDao;

    public List<User> findByName(String name) {
        List<User> userList = userDao.findAll(new Specification<User>() {
            @Override
            public Predicate toPredicate(Root<User> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                List<Predicate> predicateList = new ArrayList<>();
                if (!StringUtils.isEmpty(name)) {
                    predicateList.add(criteriaBuilder.like(root.get("name"), "%" + name + "%"));
                }
          Join<Site, DcHotel> siteJoin = root.join("siteId",JoinType.LEFT);
          predicateList.add(criteriaBuilder.like(siteJoin.get("code"), siteCode));
                criteriaQuery.where(predicateList.toArray(new Predicate[predicateList.size()]));
                return null;
            }
        });
        return userList;
    }

    public List<User> findByAge(int age){
        return userDao.findByAge(age);
    }

    public User findUser(long id){
        return userDao.findUser(id);
    }
}

 

  • 创建控制器进行访问
package com.daqsoft.controller;

import com.daqsoft.entity.User;
import com.daqsoft.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

/**
 * @author lxx
 */

@RestController
@RequestMapping(value = "/user")
public class UserController {

    @Autowired
    private UserService userService;

    @RequestMapping(value = "/findByName", method = RequestMethod.GET)
    public List<User> findByName(String name){
        List<User> userList = userService.findByName(name);
        return userList;
    }

    @RequestMapping(value = "/findByAge", method = RequestMethod.GET)
    public List<User> findByAge(int age){
        List<User> userList = userService.findByAge(age);
        return userList;
    }

    @RequestMapping(value = "/findUser", method = RequestMethod.GET)
    public User findUser(long id){
        User userList = userService.findUser(id);
        return userList;
    }
}

 

  • 整个项目工程目录如下:

 

 可以看出采用 jpa 方式进行数据查询操作时,可以根据:

  1.  利用 jpa 自带功能 使用 属性名 进行查询。
  2. 利用注解 @Query 等进行快速查询。
  3. 复杂查询利用  Specification 查询规范组合查询。

 

 

 

 

 

 

posted on 2017-08-22 15:58  Sunday_xiao  阅读(226)  评论(0)    收藏  举报