发表于: 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的一些使用


返回列表 返回列表
评论

    分享到