发表于: 2019-08-29 23:16:46
1 608
今日:
一、看了不少springdatajpa关于orm这边的处理
1.jpa没有insert这个方法,使用的是save()方法,并且需要在增删改方法上加上
@Modifying
注解,以表明这是一个写方法
需要在使用写方法的类中,比如某个ServiceImpl的上面标注
@Transactional
以表示需要事务处理
2.update方面没有看,暂时没用到需要更新的地方,后面用到再去看
3.delete目前还挺顺利的,直接用原生sql写了
/**
* 根据userId删除ForegroundUser
* @param userId 需要删除的用户id
*/
@Modifying
@Query(value = "delete from foreground_user where user_id=:userId",nativeQuery = true)
void deleteForegroundUserByUserId(Long userId);
nativeQuery = true
表示是原生sql,不加这条表示是JPQL
4.select方面,因为是需要经常使用的东西,所以看了不少这个方面的
jpa本身直接通过dao层继承JpaRepository就可以对于简单sql不写实现
比如:
public interface ForegroundUserRepository extends JpaRepository<ForegroundUser,Long>
在这个父类里已经有实现了一些简单方法,并且jpa自身支持方法名拼接生成sql,不需要写实现
比如:
/**
* 根据用户id获取用户对象
* @param userId 用户id
* @return ForegroundUser
*/
ForegroundUser findForegroundUserByUserId(Long userId);
虽然看起来很方便,简单的crud不用写了,但是有一个很严重的问题,就是项目中的查询逻辑不是那么简单,每种查询都用jpa的方法拼一次又很浪费时间
于是我和jpa的动态sql耗了一天,然后我放弃了,选择了原生sql写判断
大概就这样的
@Query(value = "SELECT * from foreground_user where 1=1 and " +
"if(''!=:userId,user_id=:userId,1=1) and " +
"if(''!=:roleId,role_id=:roleId,1=1) and " +
"if(''!=:gradeId,grade_id=:gradeId,1=1) and " +
"if(''!=:packageId,package_id=:packageId,1=1) and " +
"if(''!=:userImg,user_img=:userImg,1=1) and " +
"if(''!=:userNickname,user_nickname=:userNickname,1=1) and " +
"if(''!=:userMobileNumber,user_mobile_number=:userMobileNumber,1=1) and " +
"if(''!=:userState,user_state=:userState,1=1) and " +
"if(''!=:userCreateAt,user_create_at=:userCreateAt,1=1) and " +
"if(''!=:userUpdateAt,user_update_at=:userUpdateAt,1=1) and " +
"if(''!=:userCreateBy,user_create_by=:userCreateBy,1=1) and " +
"if(''!=:userUpdateBy,user_update_by=:userUpdateBy,1=1) and " +
"if(''!=:userCreateAtFrom&&''!=:userCreateAtTo,user_create_at between :userCreateAtFrom and :userCreateAtTo,1=1)",nativeQuery = true)
List<ForegroundUser> findForegroundUsersBy(Long userId,
Long roleId,
Long gradeId,
Long packageId,
String userImg,
String userNickname,
Long userMobileNumber,
Integer userState,
Long userCreateAt,
Long userUpdateAt,
String userCreateBy,
String userUpdateBy,
Long userCreateAtFrom,
Long userCreateAtTo,
Pageable pageable
);
在看资料过程中,我还看了通过继承
JpaSpecificationExecutor<>
来实现拼接sql,不止需要继承,还需要自己用java写这个判断
通过重写其中的拼接方法来实现动态拼接,比如
Specification<Recommend> specification = new Specification<Recommend>() {
@Override
public Predicate toPredicate(Root<Recommend> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {
List<Predicate> predicates = new ArrayList<Predicate>();
if (!StringUtils.isNullOrEmpty(recommend.getRecGrade())){
predicates.add(criteriaBuilder.equal(root.get("recGrade"),recommend.getRecGrade()));
}
if (!StringUtils.isNullOrEmpty(recommend.getRecTitle())){
predicates.add(criteriaBuilder.like(root.get("recTitle"),"%"+recommend.getRecTitle()+"%"));
}
Predicate predicate = criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()]));
return predicate;
}
};
Page<Recommend> recommendPage=recommendRespository.findAll(specification,pageable);
而且要写在serviceimpl里,而且每个不同的pojo都得写,弄得头疼,索性直接上原生sql了
明日:
一部分后台接口的返回数据按照接口文档已经完成了,继续写别的接口
问题:
是我太菜了不会用jpa吗,感觉这个东西想自定义一些东西很麻烦,它设计成全自动的orm,我在用这个的时候都不知道该怎么做优化
收获:
jpa的一些使用
评论