package com.ytkj.entity; import javax.persistence.*; import java.io.Serializable; /** * @Entity * 作用:指定当前类是实体类。 * @Table * 作用:指定实体类和表之间的对应关系。 * 属性: * name:指定数据库表的名称 * @Id * 作用:指定当前字段是主键。 * @GeneratedValue * 作用:指定主键的生成方式。。 * 属性: * strategy :指定主键生成策略。 * @Column * 作用:指定实体类属性和数据库表之间的对应关系 * 属性: * name:指定数据库表的列名称。 * unique:是否唯一 * nullable:是否可以为空 * inserttable:是否可以插入 * updateable:是否可以更新 * columnDefinition: 定义建表时创建此列的DDL * secondaryTable: 从表名。如果此列不建在主表上(默认建在主表),该属性定义该列所在从表的名字搭建开发环境[重点] * * 客户实体类 * 配置映射关系 * 实体类和表映射 * 实体类属性和表字段映射 */ @Entity @Table(name = "cst_customer") public class Customer implements Serializable { /** * 声明主键配置 */ @Id /** * 配置主键的生成策略 */ @GeneratedValue(strategy = GenerationType.IDENTITY) /** * 指定实体类属性和数据库表之间的对应关系 */ @Column(name ="cust_id") private Long custId;//客户主键 @Column(name = "cust_name") private String custName;//客户名称 @Column(name ="cust_source" ) private String custSource;//客户来源 @Column(name = "cust_industry") private String custIndustry;//客户行业 @Column(name ="cust_level") private String custLevel;//客户级别 @Column(name ="cust_address") private String custAddress;//客户地址 @Column(name = "cust_phone") private String custPhone;//客户电话 public Long getCustId() { return custId; } public void setCustId(Long custId) { this.custId = custId; } public String getCustName() { return custName; } public void setCustName(String custName) { this.custName = custName; } public String getCustSource() { return custSource; } public void setCustSource(String custSource) { this.custSource = custSource; } public String getCustIndustry() { return custIndustry; } public void setCustIndustry(String custIndustry) { this.custIndustry = custIndustry; } public String getCustLevel() { return custLevel; } public void setCustLevel(String custLevel) { this.custLevel = custLevel; } public String getCustAddress() { return custAddress; } public void setCustAddress(String custAddress) { this.custAddress = custAddress; } public String getCustPhone() { return custPhone; } public void setCustPhone(String custPhone) { this.custPhone = custPhone; } @Override public String toString() { return "Customer{" + "custId=" + custId + ", custName='" + custName + '\'' + ", custSource='" + custSource + '\'' + ", custIndustry='" + custIndustry + '\'' + ", custLevel='" + custLevel + '\'' + ", custAddress='" + custAddress + '\'' + ", custPhone='" + custPhone + '\'' + '}'; } }
Specifications动态查询 JpaSpecificationExecutor 方法列表 T findOne(Specification<T> spec); //查询单个对象 List<T> findAll(Specification<T> spec); //查询列表 //查询全部,分页 //pageable:分页参数 //返回值:分页pageBean(page:是springdatajpa提供的) Page<T> findAll(Specification<T> spec, Pageable pageable); //查询列表 //Sort:排序参数 List<T> findAll(Specification<T> spec, Sort sort); long count(Specification<T> spec);//统计查询 * Specification :查询条件 自定义我们自己的Specification实现类 实现 //root:查询的根对象(查询的任何属性都可以从根对象中获取) //CriteriaQuery:顶层查询对象,自定义查询方式(了解:一般不用) //CriteriaBuilder:查询的构造器,封装了很多的查询条件 Predicate toPredicate(Root<T> root, CriteriaQuery<?> query, CriteriaBuilder cb); //封装查询条件
Demo
/** * JpaRepository<实体类类型,主键类型>:用来完成基本CRUD操作 * JpaSpecificationExecutor<实体类类型>:用于复杂查询(分页等查询操作) */ public interface CustomerDao extends JpaRepository<Customer,Long>, JpaSpecificationExecutor<Customer> { }
import com.ytkj.dao.CustomerDao; import com.ytkj.entity.Customer; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; 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 org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import javax.persistence.criteria.*; import java.util.List; /** * Specifications动态查询 */ @RunWith(SpringJUnit4ClassRunner.class)//声明spring提供的单元测试环境 @ContextConfiguration(locations = "classpath:applicationContext.xml")//指定spring容器的配置信息 public class SpringdatajpaSpecification { @Autowired CustomerDao customerDao; /** * * 根据单个条件查询 */ @Test public void test(){ //匿名内部类 /** * 自定义查询条件 * 1:实现Specification接口(提供泛型,查询对象的类型) * 2.实现Specification接口中的toPredicate方法(构造查询条件) * 3.根据方法中的两个参数: * root:获取需要查询对象的属性名称 * criteriaBuilder:构造查询条件,内部封装了很多查询条件 * 根据名称查询 * */ Specification<Customer> specification=new Specification<Customer>() { @Override public Predicate toPredicate(Root<Customer> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) { //1.获取查询属性名称 Path<Object> custName = root.get("custName"); //2.构造查询条件 select * from cst_customer where cust_name='者超超' /** * 第一个参数:需要比较的属性 * 第二个参数:当前需要比较的取值 */ Predicate predicate = criteriaBuilder.equal(custName, "者超超");//精准匹配 return predicate; } }; Customer customer = customerDao.findOne(specification); System.out.println(customer); } /** * * 根据多个条件查询 */ @Test public void test2(){ //匿名内部类 /** * 自定义查询条件 * 1:实现Specification接口(提供泛型,查询对象的类型) * 2.实现Specification接口中的toPredicate方法(构造查询条件) * 3.根据方法中的两个参数: * root:获取需要查询对象的属性名称 * criteriaBuilder:构造查询条件,内部封装了很多查询条件 * 根据名称和地址查询 * */ Specification<Customer> specification=new Specification<Customer>() { @Override public Predicate toPredicate(Root<Customer> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) { //1.获取查询属性名称 Path<Object> custName = root.get("custName"); Path<Object> custAddress = root.get("custAddress"); //2.构造查询条件 /** * 第一个参数:path对象需要比较的属性 * 第二个参数:当前需要比较的取值 */ Predicate predicate = criteriaBuilder.equal(custName, "者超超");//精准匹配 Predicate predicate2 = criteriaBuilder.equal(custAddress, "昆明");//精准匹配 //3.将多个查询条件组合起来:组合(根据自己的业务而定)比如:满足条件一并且满足条件二,满足条件一或者满足条件二 Predicate and = criteriaBuilder.and(predicate, predicate2); return and; } }; Customer customer = customerDao.findOne(specification); System.out.println(customer); } /** * 更具电话号码模糊查询 * equal :直接的到path对象(属性),然后进行比较即可 * gt,lt,ge,le,like : 得到path对象,根据path指定比较的参数类型,再去进行比较 * 指定参数类型:path.as(类型的字节码对象) */ @Test public void test3(){ Specification<Customer> specification=new Specification<Customer>() { @Override public Predicate toPredicate(Root<Customer> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) { //1.获取查询对象的属性 Path<Object> custPhone = root.get("custPhone"); //2.拼接查询条件 Predicate like = criteriaBuilder.like(custPhone.as(String.class), "18%"); return like; } }; List<Customer> list = customerDao.findAll(specification); for (Customer customer : list) { System.out.println(customer); } } /** * 排序查询 * 更具电话号码模糊 降序查询 * equal :直接的到path对象(属性),然后进行比较即可 * gt,lt,ge,le,like : 得到path对象,根据path指定比较的参数类型,再去进行比较 * 指定参数类型:path.as(类型的字节码对象) */ @Test public void test4(){ Specification<Customer> specification=new Specification<Customer>() { @Override public Predicate toPredicate(Root<Customer> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) { //1.获取查询对象的属性 Path<Object> custPhone = root.get("custPhone"); //2.拼接查询条件 Predicate like = criteriaBuilder.like(custPhone.as(String.class), "18%"); return like; } }; //添加排序 //创建排序对象,需要调用构造方法实例化sort对象 //第一个参数:排序的顺序(倒序,正序) // Sort.Direction.DESC:倒序 // Sort.Direction.ASC : 升序 //第二个参数:排序的属性名称 Sort sort=new Sort(Sort.Direction.DESC,"custId"); List<Customer> list = customerDao.findAll(specification, sort); for (Customer customer : list) { System.out.println(customer); } } /** * 根据id分页查询 * Specification: 查询条件 * Pageable:分页参数 * 分页参数:查询的页码,每页查询的条数 * findAll(Specification,Pageable):带有条件的分页 * findAll(Pageable):没有条件的分页 * 返回:Page(springDataJpa为我们封装好的pageBean对象,数据列表,共条数) */ @Test public void test5(){ //匿名内部类 /** * 自定义查询条件 * 1:实现Specification接口(提供泛型,查询对象的类型) * 2.实现Specification接口中的toPredicate方法(构造查询条件) * 3.根据方法中的两个参数: * root:获取需要查询对象的属性名称 * criteriaBuilder:构造查询条件,内部封装了很多查询条件 * 根据名称查询 * */ Specification<Customer> specification=new Specification<Customer>() { @Override public Predicate toPredicate(Root<Customer> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) { //1.获取查询属性名称 Path<Object> custId = root.get("custId"); //2.构造查询条件 select * from cst_customer where custId>3 limit 0,5 /** * 第一个参数:需要比较的属性 * 第二个参数:当前需要比较的取值 */ Predicate predicate = criteriaBuilder.gt(custId.as(Long.class), 3L);//精准匹配 return predicate; } }; /** * public PageRequest(int page, int size) { * this(page, size, null); * } */ Pageable pageable=new PageRequest(0,2); //分页查询 Page<Customer> page = customerDao.findAll(specification, pageable); List<Customer> list = page.getContent(); for (Customer customer : list) { System.out.println(customer); } System.out.println(page.getContent()); //得到数据集合列表 System.out.println(page.getTotalElements());//得到总条数 System.out.println(page.getTotalPages());//得到总页数 } }