Spring Data JPA初识

2018-02-21  本文已影响112人  云师兄

JPA简介

JPA(Java Persistence Api)是管理java EE 和 Java SE 环境中的持久层,以及对象/关系映射的Java api。

JPA核心概念

  1. 实体表示关系数据库中的表
  2. 每个实体实例对应该表中的行
  3. 类必须用javax.persistence.Entity注解
  4. 类必须有一个public或者protected的无参数的构造函数。
  1. 一对一
  2. 一对多
  3. 多对一
  4. 多对多
  1. 定义用于与持久性上下文进行交互的方法。
  2. 创建和删除持久实体实例,通过实体的主键查找实体。
  3. 运行在实体上运行查询。
  1. 是更大的spring家族的一部分。
  2. 对基于JPA数据访问层的增强的支持。
  3. 更容易构建基于使用spring数据访问技术栈的应用技术。
  1. CrudRepository 增删改查接口
  2. PagingAndSortingRepository 分页和排序的接口
public interface PersonRepository extends Repository<User,Long>{
//find开头,使用and并行查询
  List<Person> findByEmailAddressAndLastname(EmailAddress emailAddress,String lastName);
}

//find开头,由于用了or可能数据有重复,使用distinct进行去重
List<Person> findDistinctByEmailAddressOrLastname(EmailAddress emailAddress,String lastName);
}

//使用IgnoreCase表示忽略大小写
List<Person> findByLastnameIgnoreCase(String lastname);
List<Person> findByLastnameAndFirstnameAllIgnoreCase(String lastname,String firstname);


//使用OrderBy配合asc,desc进行排序
List<Person>  findByLastnameOrderByFirstnameAsc(String lastname);
List<Person>  findByLastnameOrderByFirstnameDesc(String lastname);

JPA简单应用

讲了上面大致概念后,下面使用我之前写的<<Spring Boot整合Thymeleaf>>文章中的工程为基础,使用JPA实现用户增删改查。首先我们从github上下载该工程:https://github.com/yun00/webblog.git
为了在项目中引入JPA,我们需要配置下面几点:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
    <version>1.5.10.RELEASE</version>
</dependency>

<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>6.0.6</version>
</dependency>

第一个是JPA的starter,第二个是mysql驱动。

spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/db_activiti?useUnicode=yes&serverTimezone=GMT
spring.datasource.username=root
spring.datasource.password=123456

上面第二项配置url最后添加参数serverTimezone=GMT的原因是一开始没加会报错如下:

java.sql.SQLException: The server time zone value '�й���׼ʱ��' is unrecognized or represents more than one time zone. You must configure either the server or JDBC driver (via the serverTimezone configuration property) to use a more specifc time zone value if you want to utilize time zone support.
    at com.

上网搜索后,添加这个参数解决了这个关于时区的问题。
另外,细心的同学可能发现,第一个class name和之前配置的略有不同,这可能和当前项目的mysql驱动版本有关系,当我一开始写为spring.datasource.driver-class-name=com.mysql.jdbc.Driver的时候,会有红色的日志打出:

Loading class `com.mysql.jdbc.Driver'. This is deprecated. The new driver class is `com.mysql.cj.jdbc.Driver'. The driver is automatically registered via the SPI and manual loading of the driver class is generally unnecessary.

不过即使写作spring.datasource.driver-class-name=com.mysql.jdbc.Driver,也没有报错,不重要。
除此之外,我们需要相应的在本地数据库中加上user这个表,它的设计如下:

image.png
配置好上述后,环境就OK了,下面我们先从表示用户数据的实体类User开始:
package com.yun.hello.domain;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

@Entity
public class User {
    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private Long id;
    private String name;
    private int age;

    public User() {
    }
    public User(Long id,String name,int age) {
        this.id = id;
        this.name = name;
        this.age = 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 this.age;
    }
    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString(){
        return String.format("User[id=%d,name=%s,age=%d]", this.id,this.name,this.age);
    }
}

上述类中,@Entity注解表示这个类时JPA中的一个实体类,@Id注解表示字段id代表数据库中的主键,
@GeneratedValue(strategy=GenerationType.IDENTITY)注解表示主键为数据库自增策略递增。

编写好实体类后,我们需要改写一下操作数据的接口UserRepository :

package com.yun.hello.repository;
import org.springframework.data.repository.CrudRepository;
import com.yun.hello.domain.User;

public interface UserRepository extends CrudRepository<User,Long>{
}

这个接口继承了CrudRepository接口,我们可以不实现任何方法,在实际进行增删改查操作的时候也不必亲自实现UserRepository接口的实现类,这是因为在spring boot的JPA包中,已经有默认的实现类了,我们只需在需要的地方注入这个接口即可,由此下面这个控制器可以改成如下:

package com.yun.hello.controller;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.ModelAndView;

import com.yun.hello.domain.User;
import com.yun.hello.repository.UserRepository;

@RestController
@RequestMapping("/users")
public class UserController {
    
    @Autowired
    private UserRepository userRepository;
    
    /**
     * 从 用户存储库 获取用户列表
     * @return
     */
    private List<User> getUserlist() {
        return (List<User>) userRepository.findAll();
    }
    
    /**
     * 查询所用用户
     * @param model
     * @return
     */
    @GetMapping
    public ModelAndView list(Model model) {
        model.addAttribute("userList", getUserlist());
        model.addAttribute("title","用户管理");
        return new ModelAndView("users/list","userModel",model);
    }
    
    /**
     * 根据id来查询用户 
     * @param model
     * @return
     */
    @GetMapping("{id}")
    public ModelAndView view(@PathVariable("id") Long id,Model model) {
        User user = userRepository.findOne(id);
        model.addAttribute("user", user);
        model.addAttribute("title","查看用户");
        return new ModelAndView("users/view","userModel",model);
    }
    
    /**
     * 获取创建表单页面 
     * @param model
     * @return
     */
    @GetMapping("/form")
    public ModelAndView createForm(Model model) {
        model.addAttribute("user", new User());
        model.addAttribute("title","创建用户");
        return new ModelAndView("users/form","userModel",model);
    }
    
    /**
     * 新增或者编辑用户信息,并调回到列表页面
     * @param model
     * @return
     */
    @PostMapping
    public ModelAndView saveOrUpdateUser(User user,Model model) {
        user = userRepository.save(user);
        model.addAttribute("userList", getUserlist());
        model.addAttribute("title","用户管理");
        return new ModelAndView("users/list","userModel",model);
    }
    
    /**
     * 删除用户
     * @param id
     * @return
     */
    @GetMapping(value = "delete/{id}")
    public ModelAndView delete(@PathVariable("id") Long id, Model model) {
        userRepository.delete(id);
        model.addAttribute("userList", getUserlist());
        model.addAttribute("title", "删除用户");
        return new ModelAndView("users/list", "userModel", model);
    }

    /**
     * 修改用户
     * @param user
     * @return
     */
    @GetMapping(value = "modify/{id}")
    public ModelAndView modifyForm(@PathVariable("id") Long id, Model model) {
        User user = userRepository.findOne(id);
        model.addAttribute("user", user);
        model.addAttribute("title", "修改用户");
        return new ModelAndView("users/form", "userModel", model);
    }
}

从这个控制器中发现使用@Autowired注解自动注入了UserRepository接口的实现类,我们:

  1. 查询所有数据时调用findAll()方法
  2. 查询单条数据时调用findOne(id)方法
  3. 保存数据时调用save()方法
  4. 删除数据时调用delete()方法
    这样就实现了使用JPA来对用户数据在数据库中进行增删改查操作,具体效果和之前一样,访问http://localhost:8080/uers来进行查看。
    最后代码也上传到了github上,提供下载,地址为https://github.com/yun00/webblog.git
上一篇 下一篇

猜你喜欢

热点阅读