整合SpringData JPA
一、Spring Data简介
项目的目的是为了简化构建基于 Spring 框架应用的数据访问技术,包括非关系数据库、
Map-Reduce 框架、云数据服务等等;另外也包含对关系数据库的访问支持。
SpringData为我们提供使用统一的API来对数据访问层进行操作:
Repository<T, ID extends Serializable>:统一接口
RevisionRepository<T, ID extends Serializable, N extends Number & Comparable<N>>:基于乐观
锁机制
CrudRepository<T, ID extends Serializable>:基本CRUD操作
PagingAndSortingRepository<T, ID extends Serializable>:基本CRUD及分页
二、JPA整合示例
工程目录
引入依赖: spring-boot-starter-data-jpa
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency>
1)编写一个实体类(bean)和数据表进行映射,并且配置好映射关系
Entity
Employee类
package com.example.demo.entity; import java.util.Date; import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.ManyToOne; import javax.persistence.OneToMany; import javax.persistence.Table; //使用JPA注解配置映射关系 @Entity //告诉JPA这是一个实体类(和数据表映射的类) @Table(name = "t_employee") //@Table来指定和哪个数据表对应;如果省略默认表名就是user; public class Employee { @Id //这是一个主键 @GeneratedValue(strategy = GenerationType.IDENTITY)//自增主键 private Integer id; @Column(name = "last_name",length = 30) //这是和数据表对应的一个列 private String lastName; @Column(name = "email") private String email; //1 male, 0 female @Column(name = "gender") private Integer gender; @ManyToOne(targetEntity=Department.class,cascade=CascadeType.ALL,optional=true) @JoinColumn(name="department_id",nullable=true) private Department department; @Column(name = "birth") private Date birth; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public Integer getGender() { return gender; } public void setGender(Integer gender) { this.gender = gender; } public Department getDepartment() { return department; } public void setDepartment(Department department) { this.department = department; } public Date getBirth() { return birth; } public void setBirth(Date birth) { this.birth = birth; } public Employee(Integer id, String lastName, String email, Integer gender, Department department, Date birth) { super(); this.id = id; this.lastName = lastName; this.email = email; this.gender = gender; this.department = department; this.birth = birth; } public Employee() { super(); // TODO Auto-generated constructor stub } @Override public String toString() { return "Employee [id=" + id + ", lastName=" + lastName + ", email=" + email + ", gender=" + gender + ", department=" + department + ", birth=" + birth + "]"; } }
Department类
package com.example.demo.entity; import java.util.Set; import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.OneToMany; import javax.persistence.Table; @Entity //告诉JPA这是一个实体类(和数据表映射的类) @Table(name = "t_department") public class Department { @Id //这是一个主键 @GeneratedValue(strategy = GenerationType.IDENTITY)//自增主键 private Integer id; @Column(name = "department_name",length = 50) //这是和数据表对应的一个列 private String departmentName; @OneToMany(mappedBy="department",cascade=CascadeType.ALL) private Set<Employee> emps ; public Department() { } public Department(int i, String string) { this.id = i; this.departmentName = string; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getDepartmentName() { return departmentName; } public void setDepartmentName(String departmentName) { this.departmentName = departmentName; } public Set<Employee> getEmps() { return emps; } public void setEmps(Set<Employee> emps) { this.emps = emps; } @Override public String toString() { return "Department [id=" + id + ", departmentName=" + departmentName + "]"; } }
多表联查的重点是:@ManyToOne@JoinColumn@OneToMany注解的使用
2)编写一个Dao接口来操作实体类对应的数据表(Repository)
repository层
EmployeeRepository
package com.example.demo.repository; import org.springframework.data.domain.Example; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.JpaRepository; import com.example.demo.entity.Employee; public interface EmployeeRepository extends JpaRepository<Employee,Integer>{ @Override public <S extends Employee> Page<S> findAll(Example<S> example, Pageable pageable); }
3)基本的配置JpaProperties
spring.jpa.show-sql=true
Service 层
package com.example.demo.service; import org.springframework.data.domain.Page; import com.example.demo.entity.Employee; public interface EmployeeService { public Page<Employee> findAll(String lastName , Integer gender , Integer deptId,Integer pageNumber,Integer pageSize); }
ServiceImpl 层
package com.example.demo.service.impl; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Example; import org.springframework.data.domain.ExampleMatcher; import org.springframework.data.domain.ExampleMatcher.GenericPropertyMatchers; 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.stereotype.Service; import org.springframework.util.StringUtils; import com.example.demo.entity.Department; import com.example.demo.entity.Employee; import com.example.demo.repository.EmployeeRepository; import com.example.demo.service.EmployeeService; @Service public class EmployeeServiceImpl implements EmployeeService { @Autowired private EmployeeRepository employeeRepository; @Override public Page<Employee> findAll(String lastName , Integer gender , Integer deptId ,Integer pageNumber,Integer pageSize) { Employee emp =new Employee(); if (!StringUtils.isEmpty(lastName)) { emp.setLastName(lastName); } if (gender != null){ emp.setGender(gender); } if (deptId != null){ emp.setDepartment(new Department(deptId,null)); } ExampleMatcher matcher = ExampleMatcher.matching(); if (!StringUtils.isEmpty(lastName)) { matcher.withMatcher("lastName", GenericPropertyMatchers.contains()); } if (gender != null){ matcher.withMatcher("gender", GenericPropertyMatchers.exact()); } if (deptId != null){ matcher.withMatcher("department.id", GenericPropertyMatchers.exact()); } Example<Employee> ex = Example.of(emp, matcher); Pageable pageable = new PageRequest(pageNumber,pageSize,Sort.Direction.ASC,"id"); return employeeRepository.findAll(ex, pageable); } }
由于对Spring Data JPA 应用进行深入研究,此处就只是简单实现了JPA 的分页功能。
测试
package com.example.demo; 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.test.context.junit4.SpringRunner; import com.example.demo.entity.Employee; import com.example.demo.repository.EmployeeRepository; import com.example.demo.service.EmployeeService; @RunWith(SpringRunner.class) @SpringBootTest public class SpringBoot02ApplicationTests { @Autowired EmployeeRepository empRepository; @Autowired EmployeeService employeeService; @Test public void contextLoads() { Page<Employee> page = employeeService.findAll(null, null, 2, 0, 2); System.out.println(page.getContent()); System.out.println(page.getSize()); System.out.println(page.getTotalPages()); } }
参考:https://blog.csdn.net/qq_34083066/article/details/80733512
http://www.luckyzz.com/java/spring-data-jpa/