使用SpringDataJPA操作数据库

1、SpringDataJPA

JPA(Java Persistence API) 是指Java中数据对象持久化的过程。所谓持久化是指将内存中创建的数据对象永久的保存在数据库中,即在Java中我们通过JDBC连接数据库并进行增删改查的过程。在JDBC的基础上又出现了许多持久层框架用于简化Java和数据库的交互,其中两个较为流行的框架–Hibernate和Mybatis。但是我们依旧需要在Java中编写调用数据库的接口函数,为了统一和简化这个过程,SpringDataJPA在Hibernate的基础上基于JPA标准统一定义了操作数据库函数的相关接口,这样我们可以按照规范直接使用定义好的接口函数来操作数据库。

首先通过gradle引入SpringDataJPA的依赖以及JDBC数据库连接依赖

dependencies {
	implementation('org.springframework.boot:spring-boot-starter-data-jpa')	//Spring Data JPA
	implementation('mysql:mysql-connector-java')
	......
}

接着在application.properties文件中配置数据库连接和设置SpringJPA。其中ddl-auto代表对数据表的操作方式,如果为create则每次都会为实体对象创建新的数据表,例如为User对象在数据库中创建user表,如果已经存在则会删除原有表。若为update代表在原有表的基础上进行更新。

# 数据库配置
spring.datasource.url=jdbc:mysql://localhost/blog
spring.datasource.username=root
spring.datasource.password=123456

# 控制台打印数据库查询语句
spring.jpa.show-sql=true
# 在原有数据表上进行更新
spring.jpa.hibernate.ddl-auto=update

2、实体类

如下所示创建一个Java实体类User,在其中定义五个字段并生成对应的getter/setter方法,并且需要创建一个空的构造函数User()
使用@Entity表明这是一个实体类,并使用@Id指明主键,@GeneratedValue指明主键的生成策略,这里使用IDENTITY代表由数据库自动生成自增主键。

package com.tory.blog.entity;

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

@Entity
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String username;
    private String password;
    private String email;
    private Date createTime;

    public User() {
    }

    //... getter/seter方法...
}

3、定义JPA接口

SpringDataJPA把对数据库的相关操作都封装在JPA接口中,通过继承接口就可以直接使用操作数据库的方法。按照不同用途SpringJPA提供了不同的接口,比如CrudRepository为封装了常用的数据库增删改查操作的接口,在此基础上PagingAndSortingRepository接口封装了数据分页的函数

public interface CrudRepository<T, ID> extends Repository<T, ID> {
	//保存实体对象
	<S extends T> S save(S entity);
	//保存多个实体对象
	<S extends T> Iterable<S> saveAll(Iterable<S> entities);
	
	//根据id查找对象
	Optional<T> findById(ID id);
	//根据id判断对象是否存在
	boolean existsById(ID id);
	
	//返回所有实体
	Iterable<T> findAll();
	//根据id查询多个实体
	Iterable<T> findAllById(Iterable<ID> ids);
	//统计实体个数
	long count();

	//根据id进行删除
	void deleteById(ID id);
	//根据实体对象进行删除
	void delete(T entity);
	//删除多个实体
	void deleteAll(Iterable<? extends T> entities);
	//删除所有
	void deleteAll();
}

我们可以在上面接口的基础上自定义操作数据库的接口函数,如下所示为继承自CrudRepository的UserRepo接口,并且新增自定义了一些数据库操作函数。SpringJPA可以根据规范的方法名自动生成相应的数据库操作方法,例如我们定义了findByUsername()方法,它会自动根据username字段查找并返回User对象数组。Distinct可以返回不重复的结果,OrderBy可以对返回结果进行排序。

package com.tory.blog.repository;

import com.tory.blog.entity.User;
import org.springframework.data.repository.CrudRepository;

import java.util.List;

public interface UserRepo extends CrudRepository<User, Long> {
    //根据方法名生成操作函数
    List<User> findByUsername(String username);

    //使用Distinct
    List<User> findDistinctByUsername(String username);

    //使用OrderBy
    List<User> findByUsernameOrderByCreateTime(String username);
}

4、Spring中使用接口

如下所示直接在Spring的controller层中调用JPA接口完成和数据库的交互,首先通过@Autowire实例化userRepo对象完成数据库相关操作。

其中用userRepo.findAll()查询所有用户的信息。
userRepo.findById()根据id查询用户信息,需要注意的是该方法返回的是Optional类型的结果,如果查询到结果会放在Optional中,若无则Optional为空。可以通过isPresent()判断结果集是否为空,若非空可以通过get()获取结果集中的数据。
通过userRepo.save()实现对象数据的保存。userRepo.deleteById()实现对象的删除。

package com.tory.blog.controller;

import com.tory.blog.entity.User;
import com.tory.blog.repository.UserRepo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;

import java.util.Date;

@RestController
@RequestMapping("user")
public class UserController {
    @Autowired
    private UserRepo userRepo;

    //查询所有用户信息
    @GetMapping("list")
    public ModelAndView index() {
        return new ModelAndView("user/list", "userList", userRepo.findAll());
    }

    //根据id查询单个用户信息
    @GetMapping("{id}")
    public ModelAndView getById(@PathVariable("id") Long id) {
        ModelAndView modelAndView = new ModelAndView();
        if (userRepo.findById(id).isPresent()) {						//若查询结果不为空
            modelAndView.addObject("user", userRepo.findById(id).get());
        }
        modelAndView.setViewName("user/user");
        return modelAndView;
    }

    //新增用户
    @GetMapping("add")
    public ModelAndView add() {
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.addObject("user", new User());
        modelAndView.addObject("title", "添加用户");
        modelAndView.setViewName("user/form");
        return modelAndView;
    }

    //修改用户信息
    @GetMapping("modify/{id}")
    public ModelAndView modify(@PathVariable("id") Long id) {
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.addObject("user", userRepo.findById(id).get());
        modelAndView.addObject("title", "修改信息");
        modelAndView.setViewName("user/form");
        return modelAndView;
    }

    //保存用户user对象
    @PostMapping("save")
    public ModelAndView saveUser(User user) {
        user.setCreateTime(new Date());
        userRepo.save(user);
        return new ModelAndView("redirect:/user/list");
    }

    //删除用户
    @GetMapping("delete/{id}")
    public ModelAndView delete(@PathVariable("id") Long id) {
        userRepo.deleteById(id);
        return new ModelAndView("redirect:/user/list");
    }
}

前端表单页面如下


<html xmlns:th="http://www.thymeleaf.org">
<head>
    <title th:text="${title}">title>
    <script th:replace="common/head::static">script>
head>
<body>
<form action="/user/save" method="post" th:object="${user}">
    <input type="hidden" name="id" th:value="*{id}"/>
    姓名:<input type="text" name="username" th:value="*{username}"/><br>
    邮箱:<input type="text" name="email" th:value="*{email}"/> <br>
    密码:<input type="password" name="password" th:value="*{password}"/> <br>
    <input type="submit" value="提交">
form>
body>
html>

使用SpringDataJPA操作数据库_第1张图片
当用户访问/user/add页面,填写并提交表单后会发送post请求到/user/save,来到Controller的saveUser()方法,这时Spring会根据表单中的name属性生成相应的User对象,之后调用userRepo.save()将user对象持久化到数据库中。数据表user如下所示:
在这里插入图片描述

你可能感兴趣的:(Java)