个人博客开发之旅后端篇03:jpa的日常使用

发表于 2023-07-06 | 后端

前言

之前的文章可能就说过,jpa比较适合单表查询。 对于这个问题,还有不少人说用处不大,其实不是的。 比较小的业务,和数据量比较大的业务,单表查询都是比较多的。 会hibernate可能非常好上手。

默认实现

public interface InyaaBlogDao extends JpaRepository<InyaaBlog, Integer>, InyaaBlogDslDao {
 
}

可以看到,只是继承JpaRepository就可以了。 里面默认有增删改查,findAll、getById等常用接口。

通过命名指定参数

我写过比较麻烦的,可能就是findTopByIdLessThanOrderByCreateTimeDesc 这个根据驼峰规则来看,Top是指取第一个ById,根据id来查询,LessThan是指小于。 联合起来,就是根据创建时间倒叙,查询id小于指定值(传入的参数)的第一条数据。

通过代码来查询

public List<InyaaBlog> findAll(InyaaBlog req) {
        ExampleMatcher matcher = ExampleMatcher.matching();
        Sort sort = Sort.by("createTime").descending();
        Example<InyaaBlog> ex = Example.of(req, matcher);
        return inyaaBlogDao.findAll(ex, sort);
    }

这个没啥好说的,参数放到req里面。

通过注解来查询

@Query("select roleKey from InyaaSysRole where id in (select roleId from InyaaSysRolePermission where permissionId = ?1)")
@Query(value = "select role_key from inyaa_sys_role where id in (select role_id from inyaa_sys_user_role where user_id = ?1)", nativeQuery = true)

我这里放了两个注解,玩过hibernate的应该都知道,没下划线的是hql,有下划线的是原生sql。

querydsl

public Page<InyaaBlogVo> findBlogListPage(InyaaBlogDto req) {
        Pageable page = PageRequest.of(req.getPage(), req.getSize());
        QInyaaBlog qBean = QInyaaBlog.inyaaBlog;
        QInyaaType qInyaaType = QInyaaType.inyaaType;
        QInyaaSysUser qInyaaSysUser = QInyaaSysUser.inyaaSysUser;
        JPAQuery<InyaaBlogVo> jpaQuery = jpaQueryFactory.select(Projections.bean(InyaaBlogVo.class,
                qBean.id, qBean.summary, qBean.title, qBean.status, qBean.isHot,
                qBean.views, qBean.comments, qBean.cover, qInyaaType.id.as("typeId"), qInyaaType.name.as("typeName"),
                qBean.isComment, qBean.updateTime, qBean.createTime, qInyaaSysUser.name.as("author"))).from(qBean);
        jpaQuery.leftJoin(qInyaaSysUser).on(qInyaaSysUser.id.eq(qBean.userId));
        jpaQuery.leftJoin(qInyaaType).on(qInyaaType.id.eq(qBean.typeId));
        if (req.getTypeId() != null) {
            jpaQuery.where(qBean.typeId.eq(req.getTypeId()));
        }
        if (req.getCreateTime() != null) {
            StringTemplate eqTime = Expressions.stringTemplate("DATE_FORMAT({0},'%Y-%m-%d')", req.getCreateTime());
            String queryDate = req.getCreateTime().format(DateTimeFormatter.ISO_DATE);
            jpaQuery.where(eqTime.eq(queryDate));
        }
        if (StringUtils.isNoneBlank(req.getTitle())) {
            jpaQuery.where(qBean.title.like(req.getTitle()));
        }
        if (req.getStatus() != null) {
            jpaQuery.where(qBean.status.eq(req.getStatus()));
        }
        if (req.getTypeId() != null) {
            jpaQuery.where(qBean.typeId.eq(req.getTypeId()));
        }
        if (req.getIsHot() != null) {
            jpaQuery.where(qBean.isHot.eq(req.getIsHot()));
        }
        jpaQuery.orderBy(qBean.createTime.desc());
        jpaQuery.offset(page.getOffset()).limit(page.getPageSize());
        QueryResults<InyaaBlogVo> queryResults = jpaQuery.fetchResults();
        return new PageImpl<>(queryResults.getResults(), page, queryResults.getTotal());
    }

我这里放上了,我的分页查询,Q开头的对象,是编译后自动生成的。有关联,有where。