Spring Data Jpa 简介
JPA(Java Persistence API)意即Java持久化API,是Sun官方在JDK5.0后提出的Java持久化规范(JSR338,这些接口所在包为javax.persistence,详细内容可参考https://github.com/javaee/jpa-spec)
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:jpa="http://www.springframework.org/schema/data/jpa"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd">
<context:property-placeholder location="classpath:db.properties"/>
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${jdbc.driverClass}"/>
<property name="username" value="${jdbc.user}"/>
<property name="password" value="${jdbc.password}"/>
<property name="url" value="${jdbc.url}"/>
</bean>
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"/>
</bean>
<bean id="studentDAOSpringJdbcImpl" class="com.hzy.dao.impl.StudentDAOSpringJdbcImpl">
<property name="jdbcTemplate" ref="jdbcTemplate"/>
</bean>
</beans>
测试配置文件
package com.hzy;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.util.Assert;
import javax.sql.DataSource;
public class DataSourceTest {
private ApplicationContext ctx=null;
@Before//程序执行前
public void setup(){
ctx=new ClassPathXmlApplicationContext("applicationContext.xml");
}
@After//程序执行后
public void tearDown(){
ctx=null;
}
@Test
public void testDataSource(){
DataSource dataSource= (DataSource) ctx.getBean("dataSource");
System.out.println(dataSource);
Assert.notNull(dataSource);
}
@Test
public void testJdbcTemplate(){
JdbcTemplate jdbcTemplate= (JdbcTemplate) ctx.getBean("jdbcTemplate");
System.out.println(jdbcTemplate);
Assert.notNull(jdbcTemplate);
}
}
传统方式访问数据库
封装JDBCUtil
package com.hzy.util;
import java.io.IOException;
import java.io.InputStream;
import java.sql.*;
import java.util.Properties;
public class JDBCUtil {
public static Connection getConnection() throws ClassNotFoundException, SQLException, IOException {
InputStream in=JDBCUtil.class.getClassLoader().getResourceAsStream("db.properties");
Properties prop=new Properties();
prop.load(in);
String url=prop.getProperty("jdbc.url");
String user=prop.getProperty("jdbc.user");
String password=prop.getProperty("jdbc.password");
String driverClass=prop.getProperty("jdbc.driverClass");
Class.forName(driverClass);
Connection connection=DriverManager.getConnection(url,user,password);
return connection;
}
public static void release(ResultSet resultSet, Statement statement,Connection connection){
try {
if(resultSet!=null) {
resultSet.close();
}
if(statement!=null) {
statement.close();
}
if(connection!=null) {
connection.close();
}
} catch (SQLException e){
e.printStackTrace();
}
}
}
测试JDBCUtil
package com.hzy.util;
import org.junit.Assert;
import org.junit.Test;
import java.io.IOException;
import java.sql.Connection;
import java.sql.SQLException;
public class JDBCUtilTest {
@Test
public void testGetConnection() throws SQLException, ClassNotFoundException {
Connection connection= null;
try {
connection = JDBCUtil.getConnection();
} catch (IOException e) {
e.printStackTrace();
}
// 断言判断是不是为空
Assert.assertNotNull(connection);
}
}
在实现类中编写
package com.hzy.dao.impl;
import com.hzy.dao.StudentDAO;
import com.hzy.domain.Student;
import com.hzy.util.JDBCUtil;
import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
public class StudentDAOImpl implements StudentDAO {
@Override
public List<Student> query() {
Connection connection=null;
String sql="select * from student";
PreparedStatement pstmt=null;
ResultSet rs=null;
List<Student> list=new ArrayList<>();
Student student=null;
try {
connection= JDBCUtil.getConnection();
pstmt = connection.prepareStatement(sql);
rs = pstmt.executeQuery();
while(rs.next()){
int id=rs.getInt("id");
String name=rs.getString("name");
int age=rs.getInt("age");
student=new Student(id,name,age);
list.add(student);
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
JDBCUtil.release(rs, pstmt,connection);
}
return list;
}
@Override
public void save(Student student) {
Connection connection=null;
String sql="insert into student(name,age) values (?,?)";
PreparedStatement pstmt=null;
ResultSet rs=null;
try {
connection= JDBCUtil.getConnection();
pstmt = connection.prepareStatement(sql);
pstmt.setString(1,student.getName());
pstmt.setInt(2,student.getAge());
int i = pstmt.executeUpdate();
if(i>0){
System.out.println("插入成功");
}else{
System.out.println("插入失败");
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
JDBCUtil.release(rs, pstmt,connection);
}
}
}
测试传统方式访问数据库
package com.hzy.dao;
import com.hzy.dao.impl.StudentDAOImpl;
import com.hzy.domain.Student;
import org.junit.Test;
import java.util.List;
public class StudentDAOImplTest {
@Test
public void testQuery(){
StudentDAOImpl studentDAO=new StudentDAOImpl();
List<Student> list= studentDAO.query();
System.out.println(list);
}
@Test
public void testSave(){
StudentDAOImpl studentDAO=new StudentDAOImpl();
Student student=new Student("hzy",19);
studentDAO.save(student);
}
}
使用JdbcTemplate访问数据库
实现类编写
package com.hzy.dao.impl;
import com.hzy.dao.StudentDAO;
import com.hzy.domain.Student;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowCallbackHandler;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
public class StudentDAOSpringJdbcImpl implements StudentDAO {
private JdbcTemplate jdbcTemplate;
public JdbcTemplate getJdbcTemplate() {
return jdbcTemplate;
}
public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
@Override
public List<Student> query() {
String sql="select * from student";
final List<Student> list=new ArrayList<>();
System.out.println("query方法");
jdbcTemplate.query(sql, new RowCallbackHandler() {
@Override
public void processRow(ResultSet rs) throws SQLException {
int id=rs.getInt("id");
String name=rs.getString("name");
int age=rs.getInt("age");
Student student=new Student(id,name,age);
System.out.println(student);
list.add(student);
System.out.println(list);
}
});
System.out.println(list);
return list;
}
@Override
public void save(Student student) {
String sql="insert into student(name,age) values (?,?)";
jdbcTemplate.update(sql,new Object[]{student.getName(),student.getAge()});
}
}
编写测试类进行测试
package com.hzy.dao;
import com.hzy.domain.Student;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.util.List;
public class StudentDAOJdbcmplTest {
private ApplicationContext ctx=null;
private StudentDAO studentDAO=null;
@Before
public void setup(){
ctx=new ClassPathXmlApplicationContext("applicationContext.xml");
studentDAO= (StudentDAO) ctx.getBean("studentDAOSpringJdbcImpl");
}
@After
public void tearDown(){
ctx=null;
}
@Test
public void testQuery(){
List<Student> list= studentDAO.query();
System.out.println(list);
}
@Test
public void testSave(){
Student student=new Student("box",21);
studentDAO.save(student);
}
}
SpringDataJPA使用(JPA使用时无需手动建表)
maven引入坐标
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.imooc</groupId>
<artifactId>springdata</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<!--MySQL Driver-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.38</version>
</dependency>
<!--junit-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.10</version>
</dependency>
<!--spring-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>4.3.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.3.5.RELEASE</version>
</dependency>
<!--spring data jpa-->
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
<version>1.8.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>4.3.6.Final</version>
</dependency>
</dependencies>
</project>
beans-new.xml配置
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:jpa="http://www.springframework.org/schema/data/jpa"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd">
<!--加载配置文件-->
<context:property-placeholder location="classpath:db.properties"/>
<!--1 配置数据源-->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${jdbc.driverClass}"/>
<property name="username" value="${jdbc.user}"/>
<property name="password" value="${jdbc.password}"/>
<property name="url" value="${jdbc.url}"/>
</bean>
<!--2 配置EntityManagerFactory-->
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"/>
</property>
<property name="packagesToScan" value="com.imooc"/>
<property name="jpaProperties">
<props>
<prop key="hibernate.ejb.naming_strategy">org.hibernate.cfg.ImprovedNamingStrategy</prop>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.format_sql">true</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
</props>
</property>
</bean>
<!--3 配置事务管理器-->
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory"/>
</bean>
<!--4 配置支持注解的事务-->
<tx:annotation-driven transaction-manager="transactionManager"/>
<!--5 配置spring data-->
<jpa:repositories base-package="com.imooc" entity-manager-factory-ref="entityManagerFactory"/>
<context:component-scan base-package="com.imooc"/>
</beans>
定义类(会生成表)
package com.hzy.domain;
import org.hibernate.annotations.Proxy;
import javax.persistence.*;
@Entity
@Table(name = "test_employee")
@Proxy(lazy = false)
public class Employee {
private Integer id;
private String name;
private Integer age;
public Employee() {
}
public Employee(String name, Integer age) {
this.name = name;
this.age = age;
}
public Employee(Integer id, String name, Integer age) {
this.id = id;
this.name = name;
this.age = age;
}
@GeneratedValue(strategy= GenerationType.IDENTITY)
@Id
public Integer getId() {
return id;
}
@Override
public String toString() {
return "Employee{" +
"id=" + id +
", name='" + name + '\'' +
", age=" + age +
'}';
}
public void setId(Integer id) {
this.id = id;
}
@Column(length=20)
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
}
- @Entity 表明该类 (Employee) 为一个实体类,它默认对应数据库中的表名是employee 。
- @GeneratedValue(strategy= GenerationType.IDENTITY)
@Id 表示设置id为主键自增 - @Column(length=20) 表示该字段在数据中的长度为20
Spring Data JPA方法命名规则
Spring Data JPA方法命名规则
提供了方法名成查询方式
如果不按照它的方法进行查询,可以使用@Query注解,注解中写sql语句
事务一般是在Service层,事务注解需要写在service层
@Query、@Modifying、@Transactional的综合使用Repository类的定义
public interface Repository<T, ID> {
}
Repository是一个空接口,标记接口,没有包含方法声明的接口
我们定义的接口需要继承Repository例:EmployeeRepository extends Repository<实体类名,主键的类型>
或者使用注解方式@RepositoryDefinition(domain=Employee.class,idClass=Integer.class)
查询不需要事务处理,插入\更新\删除需要
Repository
package com.hzy.repository;
import com.hzy.domain.Employee;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.Repository;
import org.springframework.data.repository.query.Param;
import java.util.List;
//不想继承可以使用注解方式 @RepositoryDefinition(domainClass = Employee.class,idClass = Integer.class)
public interface EmployeeRepository extends Repository<Employee,Integer> {
public Employee findByName(String name);
public List<Employee> findByNameStartingWithAndAgeLessThan(String name,Integer age);
public List<Employee> findByNameEndingWithAndAgeLessThan(String name,Integer age);
public List<Employee> findByNameInOrAgeLessThan(List<String> names,Integer age);
public List<Employee> findByNameInAndAgeLessThan(List<String> names,Integer age);
// 子查询 o是表的别名,因为select后不能使用*所以用o替代
@Query("SELECT o FROM Employee o where id=(select max(id) from Employee t1)")
public Employee getEmployeeMaxById();
// sql语句中的name是方法的第一个参数,age是第二个参数
@Query("SELECT o FROM Employee o where o.name=?1 and o.age=?2")
public List<Employee> queryParams1(String name,Integer age);
@Query("SELECT o FROM Employee o where o.name=:name and o.age=:age")
public List<Employee> queryParams2(@Param("name") String name, @Param("age") Integer age);
@Query("select o from Employee o where o.name like %?1%")
public List<Employee> queryLike1(String name);
@Query("select o from Employee o where o.name like %:name%")
public List<Employee> queryLike2(@Param("name") String name);
@Query(nativeQuery = true,value = "select count(1) from Employee")
public long getCount();
//此方法需要在service中进行事务处理
@Modifying
@Query("update Employee o set o.age=:age where o.id=:id")
public void update(@Param("age")Integer age,@Param("id") Integer id);
}
使用上方接口的方法
package com.hzy.repository;
import com.hzy.domain.Employee;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.util.ArrayList;
import java.util.List;
public class EmployeeRepositoryTest {
private ApplicationContext ctx=null;
private EmployeeRepository employeeRepository=null;
@Before
public void setup(){
ctx=new ClassPathXmlApplicationContext("beans-new.xml");
employeeRepository=ctx.getBean(EmployeeRepository.class);
}
@After
public void tearDown(){
ctx=null;
}
@Test
public void testFindByName(){
Employee employee=employeeRepository.findByName("zhangsan");
System.out.println(employee);
}
@Test
public void testFindByNameStartingWithAndAgeLessThan(){
List<Employee> employees=employeeRepository.findByNameStartingWithAndAgeLessThan("test",22);
System.out.println(employees);
}
@Test
public void testFindByNameEndingWithAndAgeLessThan(){
List<Employee> employees=employeeRepository.findByNameEndingWithAndAgeLessThan("6",23);
System.out.println(employees);
}
@Test
public void testFindByNameInOrAgeLessThan(){
List<String> list=new ArrayList<>();
list.add("test1");
list.add("test2");
list.add("test4");
List<Employee> employees=employeeRepository.findByNameInOrAgeLessThan(list,22);
System.out.println(employees);
}
@Test
public void testFindByNameInAndAgeLessThan(){
List<String> list=new ArrayList<>();
list.add("test1");
list.add("test2");
list.add("test4");
List<Employee> employees=employeeRepository.findByNameInAndAgeLessThan(list,22);
System.out.println(employees);
}
@Test
public void testGetEmployeeMaxById(){
Employee employees=employeeRepository.getEmployeeMaxById();
System.out.println(employees);
}
@Test
public void testQueryParams1(){
List<Employee> employees=employeeRepository.queryParams1("test16",22);
System.out.println(employees);
}
@Test
public void testQueryParams2(){
List<Employee> employees=employeeRepository.queryParams2("test16",22);
System.out.println(employees);
}
@Test
public void testQueryLike1(){
List<Employee> employees=employeeRepository.queryLike1("test");
System.out.println(employees);
}
@Test
public void testQueryLike2(){
List<Employee> employees=employeeRepository.queryLike1("test1");
System.out.println(employees);
}
@Test
public void testGetCount(){
Long employees=employeeRepository.getCount();
System.out.println(employees);
}
//此方法必须用service中定义的使用事务的方法
@Test
public void testUpdate(){
employeeRepository.update(10,2);
}
}
service中在方法上方使用事务处理注解@Transactional
接口支持多继承
定义接口继承extends CrudRepository<Employee,Integer>
继承后不做任何处理
使用
package com.hzy.repository;
import com.hzy.domain.Employee;
import com.hzy.service.EmployeeService;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.util.ArrayList;
import java.util.List;
public class EmployeeCrudRepositoryTest {
private ApplicationContext ctx=null;
private EmployeeService employeeService=null;
@Before
public void setup(){
ctx=new ClassPathXmlApplicationContext("beans-new.xml");
employeeService= ctx.getBean(EmployeeService.class);
}
@After
public void tearDown(){
ctx=null;
}
@Test
public void testSave(){
List<Employee> employees=new ArrayList<Employee>();
Employee employee=null;
for(int i=0;i<100;i++){
employee=new Employee("test"+i,100-i);
employees.add(employee);
}
employeeService.save(employees);
}
}
定义接口继承extends JpaRepository<Employee,Integer>
继承后不做任何处理
使用
package com.hzy.repository;
import com.hzy.domain.Employee;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
public class EmployeeJpaRepositoryTest {
private ApplicationContext ctx=null;
private EmployeeJpaRepository repository=null;
@Before
public void setup(){
ctx=new ClassPathXmlApplicationContext("beans-new.xml");
repository= ctx.getBean(EmployeeJpaRepository.class);
}
@After
public void tearDown(){
ctx=null;
}
@Test
public void testFind(){
Employee employee=repository.getOne(99);
System.out.println(employee);
System.out.println(repository.existsById(10));
System.out.println(repository.existsById(101));
}
}
定义接口继承extends PagingAndSortingRepository<Employee,Integer>
继承后不做任何处理
使用
package com.hzy.repository;
import com.hzy.domain.Employee;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
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 java.util.ArrayList;
import java.util.List;
public class EmployeePagingAndSortingRepositoryTest {
private ApplicationContext ctx=null;
private EmployeePagingAndSortingRepository repository=null;
@Before
public void setup(){
ctx=new ClassPathXmlApplicationContext("beans-new.xml");
repository= ctx.getBean(EmployeePagingAndSortingRepository.class);
}
@After
public void tearDown(){
ctx=null;
}
@Test
public void testPage(){
// page是从0开始的0就代表第一页 每几页 每页显示多少条数据
Pageable pageable=PageRequest.of(0,5);
Page<Employee> page=repository.findAll(pageable);
System.out.println(page);
System.out.println("查询的总页数"+page.getTotalPages());
System.out.println("查询的总记录数"+page.getTotalElements());
System.out.println("查询的当前第几页"+page.getNumber()+1);
System.out.println("查询的当前页面的集合"+page.getContent());
System.out.println("查询的当前页面的记录数"+page.getNumberOfElements());
}
@Test
public void testPageAndSort(){
// page是从0开始的0就代表第一页 每几页 每页显示多少条数据
Sort.Order order=new Sort.Order(Sort.Direction.DESC,"id");
Sort sort=Sort.by(order);
Pageable pageable=PageRequest.of(0,5,sort);
Page<Employee> page=repository.findAll(pageable);
System.out.println(page);
System.out.println("查询的总页数"+page.getTotalPages());
System.out.println("查询的总记录数"+page.getTotalElements());
System.out.println("查询的当前第几页"+page.getNumber()+1);
System.out.println("查询的当前页面的集合"+page.getContent());
System.out.println("查询的当前页面的记录数"+page.getNumberOfElements());
}
}
定义接口继承extends JpaRepository<Employee,Integer>,JpaSpecificationExecutor < Employee >
继承后不做任何处理
使用
package com.hzy.repository;
import com.hzy.domain.Employee;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
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.data.jpa.domain.Specification;
import javax.persistence.criteria.*;
public class EmployeeJpaSpecificationExecutorRepositoryTest {
private ApplicationContext ctx=null;
private EmployeeJpaSpecificationExecutorRepository repository=null;
@Before
public void setup(){
ctx=new ClassPathXmlApplicationContext("beans-new.xml");
repository= ctx.getBean(EmployeeJpaSpecificationExecutorRepository.class);
}
@After
public void tearDown(){
ctx=null;
}
/**
* 分页
* 排序
* 查询条件
* */
@Test
public void testQuery(){
Sort.Order order=new Sort.Order(Sort.Direction.DESC,"id");
Sort sort=Sort.by(order);
Pageable pageable= PageRequest.of(0,5,sort);
/**
* root:就是我们要查询的类型(Employee)
* query:添加查询条件
* cb:构建Predicate
* */
Specification<Employee> specification=new Specification<Employee>() {
@Override
public Predicate toPredicate(Root<Employee> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
Path path=root.get("age");
return cb.gt(path,50);
}
};
Page<Employee> page=repository.findAll(specification,pageable);
//Page<Employee> page=repository.findAll(pageable);
System.out.println(page);
System.out.println("查询的总页数"+page.getTotalPages());
System.out.println("查询的总记录数"+page.getTotalElements());
System.out.println("查询的当前第几页"+page.getNumber()+1);
System.out.println("查询的当前页面的集合"+page.getContent());
System.out.println("查询的当前页面的记录数"+page.getNumberOfElements());
}
}
总结
Spring Data Jpa中一共提供了
Repository:
提供了findBy + 属性方法
@Query
HQL: nativeQuery 默认false
SQL: nativeQuery 默认true
更新的时候,需要配合@Modifying使用
CurdRepository:
继承了Repository 主要提供了对数据的增删改查
PagingAndSortRepository:
继承了CrudRepository 提供了对数据的分页和排序,缺点是只能对所有的数据进行分页或者排序,不能做条件判断
JpaRepository: 继承了PagingAndSortRepository
开发中经常使用的接口,主要继承了PagingAndSortRepository,对返回值类型做了适配
JpaSpecificationExecutor
提供多条件查询