SpringDataJPA动态查询

1. Specifications动态查询

1.1 dao接口实现的JpaSpecificationExecutor中有哪些方法

import java.util.List;

import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;

/**
 *	JpaSpecificationExecutor中定义的方法
 **/
 public interface JpaSpecificationExecutor<T> {
    
    
   	//根据条件查询一个对象
 	T findOne(Specification<T> spec);	
   	//根据条件查询集合
 	List<T> findAll(Specification<T> spec);
   	//根据条件分页查询
 	Page<T> findAll(Specification<T> spec, Pageable pageable);
   	//排序查询查询
 	List<T> findAll(Specification<T> spec, Sort sort);
   	//统计查询
 	long count(Specification<T> spec);
}

可以看到Specification是个很重要的参数,可以理解为查询条件

1.2 demo

//依赖注入customerDao
@Autowired
private CustomerDao customerDao;	
@Test
public void testSpecifications() {
    
    
    //使用匿名内部类的方式,创建一个Specification的实现类,并实现toPredicate方法
    Specification <Customer> spec = new Specification<Customer>() {
    
    
        // Specification中只有这一个方法
        public Predicate toPredicate(Root<Customer> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
    
    
            //root:从实体Customer对象中按照custName属性进行查询
            //cb:构建查询,添加查询方式 
            return cb.like(root.get("custName").as(String.class), "jerry%");
        }
    };
    Customer customer = customerDao.findOne(spec);
    System.out.println(customer);
}

1.3 分页查询

@Test
public void testPage() {
    
    
    //构造查询条件
    Specification<Customer> spec = new Specification<Customer>() {
    
    
        public Predicate toPredicate(Root<Customer> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
    
    
            return cb.like(root.get("custName").as(String.class), "jerry%");
        }
    };

    /**
		 * 构造分页参数
		 * 		Pageable : 接口
		 * 			PageRequest实现了Pageable接口,调用构造方法的形式构造
		 * 				第一个参数:页码(从0开始)
		 * 				第二个参数:每页查询条数
		 */
    Pageable pageable = new PageRequest(0, 5);

    /**
		 * 分页查询,封装为Spring Data Jpa 内部的page bean
		 * 		此重载的findAll方法为分页方法需要两个参数
		 * 			第一个参数:查询条件Specification
		 * 			第二个参数:分页参数
		 */
    Page<Customer> page = customerDao.findAll(spec,pageable);
	
    // 页数
    int pageNums = page.getTotalPages();
    // 记录数量
    int count = page.getTotalElements();
	// 列表数据
    List<Customer> customers = page.getContent();
}

2. 多表查询

2.1 一对一查询

PeopleAddress为例:

@Entity
@Table("people")
public class People {
    
    
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private Long id;//id
    @Column(name = "name")
    private String name;//姓名
    @Column(name = "sex")
    private String sex;//性别
    @OneToOne // 标注这是1对1
    @JoinColumn(name = "address_id", referencedColumnName = "id")//people中的address_id字段参考address表中的id字段
    private Address address;//地址
}
@Entity
public class Address {
    
    
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id", nullable = false)
    private Long id;//id
    @Column(name = "phone", nullable = true, length = 11)
    private String phone;//手机
}

2.2 一对多查询

@Entity//表示当前类是一个实体类
@Table(name="cst_customer")//建立当前实体类和表之间的对应关系
public class Customer implements Serializable {
    
    
	
	@Id//表明当前私有属性是主键
	@GeneratedValue(strategy=GenerationType.IDENTITY)//指定主键的生成策略
	@Column(name="cust_id")//指定和数据库表中的cust_id列对应
	private Long custId;

    
    //配置客户和联系人的一对多关系
  	@OneToMany(targetEntity=LinkMan.class)
	@JoinColumn(name="lkm_cust_id",referencedColumnName="cust_id")
	private Set<LinkMan> linkmans = new HashSet<LinkMan>;
}
@Entity
@Table(name="cst_linkman")
public class LinkMan implements Serializable {
    
    
	@Id
	@GeneratedValue(strategy=GenerationType.IDENTITY)
	@Column(name="lkm_id")
	private Long lkmId;

	//多对一关系映射:多个联系人对应客户
	@ManyToOne(targetEntity=Customer.class)
	@JoinColumn(name="lkm_cust_id",referencedColumnName="cust_id")
	private Customer customer;//用它的主键,对应联系人表中的外键
}

注解说明:

  1. @OneToMany:建立一对多的关系

    1. targetEntityClass:指定多的一方的类的字节码
    2. mappedBy:指定从表实体类中引用主表对象的名称
    3. cascade:指定使用的级联操作
    4. fetch:是否采用延迟加载
    5. orphanRemoval:是否使用孤儿删除
  2. @ManyToOne:建立多对一的关系

    1. targetEntityClass:指定一的一方的类的字节码
    2. cascade:指定使用的级联操作
    3. fetch:是否采用延迟加载
    4. optional:关联是否可选
  3. JointColumn:用于定义主键字段和外键字段的关系

    1. name:外键字段的名称
    2. referencedColumnName:引用主表的主键字段名称
    3. unique:是否唯一
    4. nullable:是否允许为空
    5. insertable:是否允许擦汗如
    6. updatetable:是否允许更新
    7. columnDefinition:列的定义信息
// 插入操作
public class Test {
    
    
    @Autowired
	private CustomerDao customerDao;
	@Autowired
	private LinkManDao linkManDao;
    
    @Transactional  //开启事务
	@Rollback(false)//设置为不回滚
    @Test
    public void test() {
    
    
        Customer cust = new Customer();
        // set操作
        LinkMan link = new LinkMan();
        // set操作
        
        
        c.getLinkMans.add(link);
        l.setCustomer(c);
        
        customerDap.save(cust);
        linkManDao.save(link);
    }
    
}

2.3 多对多查询

/**
 * 用户的数据模型
 */
@Entity
@Table(name="sys_user")
public class SysUser implements Serializable {
    
    
	
	@Id
	@GeneratedValue(strategy=GenerationType.IDENTITY)
	@Column(name="user_id")
	private Long userId;
	
	//多对多关系映射
	@ManyToMany(mappedBy="users")
	private Set<SysRole> roles = new HashSet<SysRole>(0);
	
}
/**
 * 角色的数据模型
 */
@Entity
@Table(name="sys_role")
public class SysRole implements Serializable {
    
    
	
	@Id
	@GeneratedValue(strategy=GenerationType.IDENTITY)
	@Column(name="role_id")s
	private Long roleId;
	
	//多对多关系映射
	@ManyToMany
	@JoinTable(name="user_role_rel",//中间表的名称
			  //中间表user_role_rel字段关联sys_role表的主键字段role_id
			  joinColumns={
    
    @JoinColumn(name="role_id",referencedColumnName="role_id")},
			  //中间表user_role_rel的字段关联sys_user表的主键user_ssid
			  inverseJoinColumns={
    
    @JoinColumn(name="user_id",referencedColumnName="user_id")}
	)
	private Set<SysUser> users = new HashSet<SysUser>(0);
	
}

注解说明:

  1. ManyToMany:多对多映射
    1. cascade:配置级联操作
    2. fetch:是否采用延迟加载
    3. targetEntity:配置目标的实体类
  2. @JoinTable:中间表配置
    1. name:中间表的名称
    2. joinColumns:中间表的外键字段关联当前实体类所对应的主键字段
    3. inverseJoinColumn:中间表的外键字段关联对方表的主键字段
  3. @JointColumn:同上面的

猜你喜欢

转载自blog.csdn.net/weixin_43795939/article/details/112546174
今日推荐