zoukankan      html  css  js  c++  java
  • SpringBoot使用JPA来做数据查询

    Spring-Data-JPA在做数据存储方面真的很方便,它的目的就是写更少的代码,更多的事情,但是也有其力有未逮或者说处理起来比较闹心的地方。

      1.先来感受一下使用JPA做数据查询时,代码的简化程度

    
    
    @CacheConfig(cacheNames = "news")
    public interface NewsRepository extends PagingAndSortingRepository<NewsEntity, Long> {
        @Cacheable
        NewsEntity findOne(Long id);
    
        @Cacheable
        NewsEntity findTop1ByOriginId(String originId);
    
        @Transactional
        long deleteByOriginId(String originId);           
        
        Page<NewsEntity> findDistinctByTitleStartingWithAndSimilarIdIsNullOrderByPubDateDesc(String title, Pageable pageable); 
    }

    单表查询时,只需要根据JPA提供的规范去命名,根本不需要自己去写什么查询语句就可以。

      2.当然要自己写SQL语句也没有问题

    @Query(value = "select e.* from news_detail e INNER JOIN news_info n  on e.news_id = n.id where n.pub_date >= ?1", nativeQuery = true)
    List<Object> listBypubDateWithEntityDetail(String pubDate);
    
    @Query(value = "select n.id,GROUP_CONCAT(e.ent_id) from news_info n INNER JOIN map_news_company e on e.news_id = n.id where n.pub_date>= ?1 and n.id>?2 group by n.id order by n.id limit 10000", nativeQuery = true)
    List<Object[]> listBypubDateWithEnts(String pubDate, long news_id);

    使用原生的SQL也可以,JPA就是这么方便,然而总有需要操心的地方——多条件分组查询。用过Hibernate和Mybatis的,在写业务逻辑的时候,拼接查询条件的时候,一定写过很多if条件不为空的判断,这就是JPA操蛋的地方。

      3.看看例子

        @Query(value = "select pub_time,count(1) as count from t_weibo where content like %:keyword% and pub_time>=:dateFrom and pub_time<=:dateTo group by pub_time", nativeQuery = true)
        List<Object[]> getWeibo(@Param("keyword") String keyword, @Param("dateFrom") Date dateFrom, @Param("dateTo") Date dateTo);
    
        @Query(value = "select pub_time,count(1) as count from t_weibo where content like %:keyword% and pub_time>=:dateFrom and pub_time<=:dateTo and region in ( select keyname from t_cell where  provincename=:provincename) group by pub_time", nativeQuery = true)
        List<Object[]> getWeiboByProvince(@Param("provincename") String provincename,@Param("keyword") String keyword,@Param("dateFrom") Date dateFrom, @Param("dateTo") Date dateTo);

    这个例子两个方法的作用一样,条件个数不一样,这就是冗余了。

      4.如果是这样JPA被设计出来的意义是什么,jpa有一套来应对这些的措施,使用Specification这个来来完成条件拼接

    User user1 = (User) userRepository.findOne(new Specification<User>() {
                public Predicate toPredicate(Root<User> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                    /*criteriaQuery.where(criteriaBuilder.equal(root.<String>get("name"), user.getName()),
                            criteriaBuilder.equal(root.<String>get("password"), user.getPwd()));*/
              Predicate predicate = null;
              if(user.getName!=null&&!user.getName().equal){
                if(predicate!=null){
                 predicate =
    criteriaBuilder.equal(root.<String>get("name"), user.getName())
                        }else{
                  predicate =
    criteriaBuilder.and(predicte,criteriaBuilder.equal(root.<String>get("name"), user.getName()))
                        }
                    }
              if(predicate!=null){
                criteriaQuery
    .where(predicate);
              }
    return null; } });

    核心就是使用CriteriaBuilder 进行条件拼接

      5.还有一种方式就是使用QueryDsl插件来组合Spring Data JPA使用

    添加maven依赖
            <!--queryDSL-->
            <dependency>
                <groupId>com.querydsl</groupId>
                <artifactId>querydsl-jpa</artifactId>
                <version>${querydsl.version}</version>
            </dependency>
            <dependency>
                <groupId>com.querydsl</groupId>
                <artifactId>querydsl-apt</artifactId>
                <version>${querydsl.version}</version>
                <scope>provided</scope>
            </dependency>
     配置querydsl插件
        <build>
            <plugins>
                <!--该插件可以生成querysdl需要的查询对象,执行mvn compile即可-->
                <plugin>
                    <groupId>com.mysema.maven</groupId>
                    <artifactId>apt-maven-plugin</artifactId>
                    <version>1.1.3</version>
                    <executions>
                        <execution>
                            <goals>
                                <goal>process</goal>
                            </goals>
                            <configuration>
                                <outputDirectory>target/generated-sources/java</outputDirectory>
                                <processor>com.querydsl.apt.jpa.JPAAnnotationProcessor</processor>
                            </configuration>
                        </execution>
                    </executions>
                </plugin>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                </plugin>
            </plugins>
        </build>

    此时编译(compile)一下maven项目,在这个(target/generated-sources/java)文件夹下看到对应于你建的实体类(User)的QueryDsl类(QUser)

    @Entity
    @Table(name = "users")
    @Data
    public class UserBean
    {
        @Id
        @GeneratedValue
        @Column(name = "u_id")
        private Long id;
        @Column(name = "u_username")
        private String name;
        @Column(name = "u_age")
        private int age;
        @Column(name = "u_score")
        private double socre;
    }

    查询语句

    @PersistenceContext
    EntityManager entityManager;
    @RequestMapping("query")
        public List<GoodEntity> list(){
            QUserBean userBean = QUserBean.userBean;
            JPAQuery<UserBean> jpaQuery = new JPAQuery<>(entityManager);
            return jpaQuery.select(userBean)
                    .from(userBean)
                    .where(userBean.name.eq("haha"))
                    .fetch();
        }

      

  • 相关阅读:
    'Neither SQLALCHEMY_DATABASE_URI nor SQLALCHEMY_BINDS is set.
    flask os.environ 的作用
    flask 中xx.init_app(app)方法
    win10安装ubuntu双系统遇到的问题
    福大软工 · 最终作业
    福大软工 · 第十二次作业
    Beta 冲刺(7/7)
    Beta 冲刺(6/7)
    常用正则
    使用elementUI动态增减表单项 且 使用自定义校验
  • 原文地址:https://www.cnblogs.com/shirandedan/p/8144769.html
Copyright © 2011-2022 走看看