spring-boot与spring-data-JPA的简单整合

如何在boot中轻松使用JPA

<!--首先引入JPA依赖-->
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency>

以用户角色为例,其中用户表,角色表,还有一张中间表,用户角色表,首先先创建对应的实体类

/**
 * 用户类
  */ 
@Data
@Entity
public class Account extends DefaultValidate implements Login {
    @Id
    @GeneratedValue
    private Integer id;
 
    /**
     * 登录名
     */
    @NotNull(message = "登录名不能为空")
    @Size(min = 2, max = 50)
    @Column(name="login_name")
    private String loginName;
 
    /**
     * 账户名
     */
    @NotNull(message = "账户名不能为空")
    @Size(min = 2, max = 50)
    @Column(name="account_name")
    private String accountName;
 
    /**
     * 登录密码
     */
    @Column(name="login_pwd")
    private String loginPwd;
     
    /**
     * 账户标识码
     */
    @Column(name="account_code")
    private String accountCode;
     
    /**
     * 中间表   并不需要实体类  自动生成
     */
    @ManyToMany(cascade=CascadeType.REFRESH,fetch=FetchType.LAZY)
    @JoinTable(name = "account_role",
    joinColumns = { @JoinColumn(name = "account_id") }, 
    inverseJoinColumns = { @JoinColumn(name = "role_id") })
    private Set<Role> roles = new HashSet<Role>();
}
/*
 * 角色类
 * @date 2018年3月22日上午10:17:11
 */
@Data
@Entity
public class Role extends DefaultValidate {
    @Id
    @GeneratedValue
    private Integer id;
 
    /**
     * 角色标识
     */
    @NotNull(message = "角色标识不能为空")
    @Size(min = 2, max = 50)
    @Column(name="role_code")
    private String roleCode;
 
    /**
     * 角色名称
     */
    @NotNull(message = "角色名称不能为空")
    @Size(min = 2, max = 50)
    @Column(name="role_name")
    private String roleName;
 
}

这样子对应的 实体类便创建完成,上面用到的映射关系为单向的多对多,接着创建对应的repository

@Repository
public interface AccountReposity extends JpaRepository<Account, Integer> {
     

}

使用的时候调用其对应的方法即可。接下去介绍一下对应的动态查询,动态查询需要repository继承JpaSpecificationExecutor类,

public Page<Flow> mySubmission(MySubmitPageDto selectDto) {
		LOGGER.info("查询我的提交开始。。。。") ;

		PageRequest pageable =new PageRequest(selectDto.getPageNum(), selectDto.getPageSize());
		//匿名内部类
		Specification<Flow> specification = new Specification<Flow>() {
			/**
			 * Predicate:代表一个查询条件
			 * root:查询的实体类
			 * query:可以从中得到root对象 ,即告知查询那个实体类,添加查询条件(其中排序什么的可以通过query去设置)
			 * cb:用于创建CriteriaBuilder相关对象的工厂,可以从中获取到Predicate对象
			 */
			@Override
			public Predicate toPredicate(Root<Flow> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
				List<Predicate> predicateList = new ArrayList<Predicate>();	
				predicateList.add(cb.equal(root.<String>get("flowStarter"), selectDto.getUserCode()));
				Predicate[] p =new Predicate[predicateList.size()];
				return cb.and(predicateList.toArray(p));
			}
		};
		Page<Flow> page = flowRepository.findAll(specification, pageable);
		LOGGER.info("查询我的提交结束。。。。") ;
		return page;
	}

如果有很复杂的动态查询,推荐结合Spring-JDBC去操作,写动态的原生sql比较方便开发。

JPA对象的生命周期:

  New:瞬时对象,尚未有id,还未和Persistence Context建立关联的对象。

  Managed:持久化受管对象,有id值,已经和Persistence Context建立了关联的对象。

  Datached:游离态离线对象,有id值,但没有和Persistence Context建立关联的对象。

  Removed:删除的对象,有id值,尚且和Persistence Context有关联,但是已经准备好从数据库中删除  

JPA查询出来的对象处于持久态的时候,调用改对象属性的set方法的时候会去动态的修改数据库。可以通过

@PersistenceContext
 private EntityManager entityManger;

调用manager的clear方法释放对象即可。

如果涉及枚举类属性,可以重写其set,get方法即可,如:

	public WarehouseStatusEnum getState() {
		return WarehouseStatusEnum.getWarehouseStatusEnum(this.state);
	}

	public void setState(WarehouseStatusEnum state) {
		this.state = state.value();
	}

  

posted @ 2018-06-05 13:54  吴振照  阅读(363)  评论(0编辑  收藏  举报