SpringDataJpa系列一之初识及入门案例搭建

本文章参考文档为《SpringDataJpa从入门到精通》

首先, 我觉得入门SpringDataJpa的话, 我们首先要理清楚。 JPA、Hibernate和SpringDataJpa的关系。

什么是JPA?

全称Java Persistence API,可以通过注解或者XML描述【对象-关系表】之间的映射关系,并将实体对象持久化到数据库中。
但是它只是提供了一种规范, 而Hibernate和SpringDataJpa就是实现了这种规范的ORM框架。

而Sun为什么要引入JPA ORM规范, 因为Sun想要整合ORM技术, 实现天下归一。

(怎么样, 是不是很酷)

SpringDataJpa大家族

其实学习JAVA我觉得就是学习其对应技术的API, 如下是SpringDataJpa涉及到的主要类(接口), 先有个印象。
这是使用idea的F4功能看到了所有继承了Repository接口的类(包括我自定义的类以com.example开头), 其中红框的至关重要, 需要重点学习。SpringDataJpa系列一之初识及入门案例搭建_第1张图片
以上的暂时有一个印象就好, 接下来都会就说到。(有一点需要明确, 只要继承了Repository接口, 那么你就算有了SpringDataJpa的能力, 就可以做一些基础的查询了。 如果要是实现了CrudRepository接口, 那么厉害了, 你就可以做增删改查了。 是不是很cool? 记得, 越简单的越NB)

快速入门案例

首先, 开发工具推荐idea, 因为构建起一个SpringDataJpa的项目会灰常的快。
SpringDataJpa系列一之初识及入门案例搭建_第2张图片
SpringDataJpa系列一之初识及入门案例搭建_第3张图片
SpringDataJpa系列一之初识及入门案例搭建_第4张图片
然后一路next, 我们得到了一个SpringDataJpa的开发环境。 对了, 别忘记改一下你的配置文件(把你的数据库配置进去)。
SpringDataJpa系列一之初识及入门案例搭建_第5张图片
然后在数据库中, 推荐学习的时候使用Mysql, 新建一张表, 刚开始简单一点。
新建一张 user 表, 以下是数据结构:
SpringDataJpa系列一之初识及入门案例搭建_第6张图片
然后自定义一个接口, 继承CrudRepository。

public interface UserRepository extends CrudRepository {}

注意, 我这个接口里面什么都没有写。(泛型中的第一个为一个实体类, 第二个为这个实体类的主键类型, 如果是联合主键这里就是一个XXXKey的类)
新建一个Controller类

/**
 * User的控制类
 *
 * @author YangHang
 * @Date 2018/11/28 23:13
 */
@Controller
@RequestMapping(path = "/demo")
public class UserController {

    /**
     * DAO层操作对象
     */
    @Autowired
    private UserRepository userRepository;

    /**
     * 分页DAO层操作对象
     */
    @Autowired
    private UserPagingAndSortingRepository userPagingAndSortingRepository;

    /**
     * 添加用户操作
     *
     * @param name  用户的姓名
     * @param email 用户的邮箱
     * @return message 操作提示信息
     */
    @PostMapping(path = "/addNewUser")
    @ResponseBody
    public String addNewUser(@RequestParam String name, @RequestParam String email) {
        Assert.notNull(name, "NAME MUST BE NOT NULL");
        Assert.notNull(email, "EMAIL MUST BE NOT NULL");

        User user = new User();
        user.setName(name);
        user.setEmail(email);

        userRepository.save(user);
        return "添加用户成功";

    }

    /**
     * 获取所有的用户对象
     *
     * @return userList 用户
     */
    @PostMapping(path = "/getAllUser")
    @ResponseBody
    public List getAllUser() {
        Iterable userIterable = userRepository.findAll();

        List userList = new ArrayList<>();
        if (userIterable != null) {
            userIterable.forEach(user -> userList.add(user));
        }
        return userList;
    }

    /**
     * 根据用户名称查询所有用户
     *
     * @param name 用户名称
     * @return userList 用户
     */
    @PostMapping(path = "/queryUserListByName")
    @ResponseBody
    public List queryUserListByName(@RequestParam String name) {
        Assert.notNull(name, "NAME MUST BE NOT NULL");

        List userList = userRepository.findByName(name);
        return userList;
    }

    /**
     * 根据用户名称和邮箱查询所有用户
     *
     * @param name  用户名称
     * @param email 用户邮箱
     * @return userList 用户
     */
    @PostMapping(path = "/queryUserListByNameAndEmail")
    @ResponseBody
    public List queryUserListByNameAndEmail(@RequestParam String name, @RequestParam String email) {
        Assert.notNull(name, "NAME MUST BE NOT NULL");
        Assert.notNull(email, "EMAIL MUST BE NOT NULL");

        List userList = userRepository.findByNameAndEmail(name, email);
        return userList;
    }

    /**
     * 根据用户id删除
     *
     * @param id 用户主键
     */
    @PostMapping("/deleteById")
    @ResponseBody
    public String deleteById(@RequestParam Long id) {
        Assert.notNull(id, "ID MUST BE NOT NULL");

        userRepository.deleteById(id);
        return "删除对象成功";
    }

    /**
     * 验证分页并排序的方法
     *
     * @param page 页码
     * @param size 每页的条数
     * @return userPage 分页之后的对象集合
     */
    @PostMapping("/queryUserPage")
    @ResponseBody
    public Page getAllUserByPage(@RequestParam int page,@RequestParam int size) {
        return userPagingAndSortingRepository.findAll(PageRequest.of(page, size, new Sort(Sort.Direction.ASC, "name")));
    }
}

我这里的方法比较多, 刚开始接触SpringDataJpa的小伙伴只需要看userRepository的方法即可。
最后呢, 启动项目, 使用POSTMAN调一下下, 你就会发现, 你已经会用SpringDataJpa进行编码了。

相信聪明的小伙伴已经知道了, 之所以叫CrudRepository, 就是默认帮你实现了增删改查的底层类嘛。

关于SpringDataJpa的分页查询

SpringDataJpa最简单的分页实现就是继承JPA大家族的PagingAndSortingRepository接口。
我们可以点开源码开一下。
SpringDataJpa系列一之初识及入门案例搭建_第7张图片
这个接口里面只提供了两个方法, 入参分别是Sort对象和Pageable接口。
我们可以看到Sort是一个类, 我们可以直接传入这个类的对象来实现排序。
主要是Pageable接口, 想要完成分页, 需要传入一个这个接口的实现, 点击F4看一下这个接口的层次, 我们会发现PageRequest这个类, 通过它的of() 方法我们可以构建出这个接口的实现类,看一下源码。

public class PageRequest extends AbstractPageRequest {
    private static final long serialVersionUID = -4541509938956089562L;
    private final Sort sort;

    /** @deprecated */
    @Deprecated
    public PageRequest(int page, int size) {
        this(page, size, Sort.unsorted());
    }

    /** @deprecated */
    @Deprecated
    public PageRequest(int page, int size, Direction direction, String... properties) {
        this(page, size, Sort.by(direction, properties));
    }

    /** @deprecated */
    @Deprecated
    public PageRequest(int page, int size, Sort sort) {
        super(page, size);
        this.sort = sort;
    }

    public static PageRequest of(int page, int size) {
        return of(page, size, Sort.unsorted());
    }

    public static PageRequest of(int page, int size, Sort sort) {
        return new PageRequest(page, size, sort);
    }

    public static PageRequest of(int page, int size, Direction direction, String... properties) {
        return of(page, size, Sort.by(direction, properties));
    }

    public Sort getSort() {
        return this.sort;
    }

    public Pageable next() {
        return new PageRequest(this.getPageNumber() + 1, this.getPageSize(), this.getSort());
    }

    public PageRequest previous() {
        return this.getPageNumber() == 0?this:new PageRequest(this.getPageNumber() - 1, this.getPageSize(), this.getSort());
    }

    public Pageable first() {
        return new PageRequest(0, this.getPageSize(), this.getSort());
    }

    public boolean equals(@Nullable Object obj) {
        if(this == obj) {
            return true;
        } else if(!(obj instanceof PageRequest)) {
            return false;
        } else {
            PageRequest that = (PageRequest)obj;
            return super.equals(that) && this.sort.equals(that.sort);
        }
    }

    public int hashCode() {
        return 31 * super.hashCode() + this.sort.hashCode();
    }

    public String toString() {
        return String.format("Page request [number: %d, size %d, sort: %s]", new Object[]{Integer.valueOf(this.getPageNumber()), Integer.valueOf(this.getPageSize()), this.sort});
    }
}

主要有两个构造函数, 一个是PageRequest(int page, int size) 其中page是第几页(从0开使), size是一页多少条记录
另外一个构造是PageRequest(int page, int size, Sort sort) 多了一个排序的对象, 即可以按固定的排序来分页。
具体的代码?有实例, 即用userPagingAndSortingRepository实现的。

我叫杨小邪, 如果有问题, 请留言讨论哈。 我下一篇会将一下SpringDataJpa的定义式查询方法和注解式查询方法, 希望大家喜欢。

你可能感兴趣的:(SpringDataJpa系列)