Spring Data非常方便,并且避免了样板代码,从而加快了开发速度。 但是,在某些情况下,注释查询不足以实现您可能想要实现的自定义功能。
因此,spring数据允许我们向Spring数据存储库添加自定义方法。 我将使用前一篇博客文章中的相同项目结构。
我们有一个名为Employee的实体
package com.gkatzioura.springdata.jpa.persistence.entity;import javax.persistence.*;/*** Created by gkatzioura on 6/2/16.*/
@Entity
@Table(name = "employee", schema="spring_data_jpa_example")
public class Employee {@Id@Column(name = "id")@GeneratedValue(strategy = GenerationType.SEQUENCE)private Long id;@Column(name = "firstname")private String firstName;@Column(name = "lastname")private String lastname;@Column(name = "email")private String email;@Column(name = "age")private Integer age;@Column(name = "salary")private Integer salary;public Long getId() {return id;}public void setId(Long id) {this.id = id;}public String getFirstName() {return firstName;}public void setFirstName(String firstName) {this.firstName = firstName;}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 getAge() {return age;}public void setAge(Integer age) {this.age = age;}public Integer getSalary() {return salary;}public void setSalary(Integer salary) {this.salary = salary;}
}
还有Spring Data存储库
package com.gkatzioura.springdata.jpa.persistence.repository;import com.gkatzioura.springdata.jpa.persistence.entity.Employee;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;/*** Created by gkatzioura on 6/2/16.*/
@Repository
public interface EmployeeRepository extends JpaRepository<Employee,Long>{}
假设我们要添加一些自定义的sql功能,例如使用LIKE语句查询并与未映射为实体的表联接。
这仅用于演示目的。 对于您的项目,您可能会有更好的架构。 再加上spring数据具有类似语句的开箱即用功能,请查看EndingWith,Containing,StartingWith 。
我们将创建奖金表并添加对雇员表的引用。
set schema 'spring_data_jpa_example';create table bonus(id serial primary key,employee_id integer,amount real,foreign key (employee_id) references employee (id),unique (employee_id));insert into bonus
( employee_id, amount)
VALUES(1, 100);
我们要实现的sql查询将查询名称以指定文本开头且奖金大于一定数量的员工。 在jdbc中,我们必须传递与字符'%'串联在一起的变量。
所以我们需要一个像这样的本地jpa查询
Query query = entityManager.createNativeQuery("select e.* from spring_data_jpa_example.bonus b, spring_data_jpa_example.employee e\n" +"where e.id = b.employee_id " +"and e.firstname LIKE ? " +"and b.amount> ? ", Employee.class);query.setParameter(1, firstName + "%");query.setParameter(2, bonusAmount);
为了将此功能添加到我们的spring数据存储库中,我们必须添加一个接口。 我们的界面必须遵循$ {Original Repository name} Custom的命名约定。 因此,描述我们自定义功能的界面应为
package com.gkatzioura.springdata.jpa.persistence.repository;import com.gkatzioura.springdata.jpa.persistence.entity.Employee;import java.util.List;/*** Created by gkatzioura on 6/3/16.*/
public interface EmployeeRepositoryCustom {List<Employee> getFirstNamesLikeAndBonusBigger(String firstName, Double bonusAmount);}
实施应该是
package com.gkatzioura.springdata.jpa.persistence.repository;import com.gkatzioura.springdata.jpa.persistence.entity.Employee;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import java.util.List;/*** Created by gkatzioura on 6/3/16.*/
@Repository
@Transactional(readOnly = true)
public class EmployeeRepositoryImpl implements EmployeeRepositoryCustom {@PersistenceContextEntityManager entityManager;@Overridepublic List<Employee> getFirstNamesLikeAndBonusBigger(String firstName, Double bonusAmount) {Query query = entityManager.createNativeQuery("select e.* from spring_data_jpa_example.bonus b, spring_data_jpa_example.employee e\n" +"where e.id = b.employee_id " +"and e.firstname LIKE ? " +"and b.amount> ? ", Employee.class);query.setParameter(1, firstName + "%");query.setParameter(2, bonusAmount);return query.getResultList();}
}
并且我们应该更改原始的spring数据存储库以继承自定义功能。
package com.gkatzioura.springdata.jpa.persistence.repository;import com.gkatzioura.springdata.jpa.persistence.entity.Employee;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;/*** Created by gkatzioura on 6/2/16.*/
@Repository
public interface EmployeeRepository extends JpaRepository<Employee,Long>, EmployeeRepositoryCustom {
}
似乎是一种不错的构图方式。 现在让我们向控制器添加一个方法,该方法将调用此自定义方法
package com.gkatzioura.springdata.jpa.controller;import com.gkatzioura.springdata.jpa.persistence.entity.Employee;import com.gkatzioura.springdata.jpa.persistence.repository.EmployeeRepository;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestParam;import org.springframework.web.bind.annotation.RestController;import java.util.List;/*** Created by gkatzioura on 6/2/16.*/
@RestController
public class TestController {@Autowiredprivate EmployeeRepository employeeRepository;@RequestMapping("/employee")public List<Employee> getTest() {return employeeRepository.findAll();}@RequestMapping("/employee/filter")public List<Employee> getFiltered(String firstName,@RequestParam(defaultValue = "0") Double bonusAmount) {return employeeRepository.getFirstNamesLikeAndBonusBigger(firstName,bonusAmount);}}
源代码可以在github上找到。
翻译自: https://www.javacodegeeks.com/2016/06/add-custom-functionality-spring-data-repository.html