如何在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(); }