详解spring boot jpa整合QueryDSL来简化复杂操作

前言

使用过spring data jpa的同学,都很清楚,对于复杂的sql查询,处理起来还是比较复杂的,而本文中的QueryDSL就是用来简化JPA操作的。

Querydsl定义了一种常用的静态类型语法,用于在持久域模型数据之上进行查询。JDO和JPA是Querydsl的主要集成技术。本文旨在介绍如何使用Querydsl与JPA组合使用。JPA的Querydsl是JPQL和Criteria查询的替代方法。QueryDSL仅仅是一个通用的查询框架,专注于通过Java API构建类型安全的SQL查询。

要想使用QueryDSL,需要做两个前提操作:

1、pom文件中,加入依赖

<!--query dsl -->
  <dependency>
   <groupId>com.querydsl</groupId>
   <artifactId>querydsl-jpa</artifactId>
  </dependency>
  <dependency>
   <groupId>com.querydsl</groupId>
   <artifactId>querydsl-apt</artifactId>
   <scope>provided</scope>
  </dependency>

2、pom文件中,加入编译插件

<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>

该插件会查找使用javax.persistence.Entity注解的域类型,并为它们生成对应的查询类型。下面以User实体类来说明,生成的查询类型如下:

package com.chhliu.springboot.jpa.entity;
import static com.querydsl.core.types.PathMetadataFactory.*;
import com.querydsl.core.types.dsl.*;
import com.querydsl.core.types.PathMetadata;
import javax.annotation.Generated;
import com.querydsl.core.types.Path;
/**
 * QUser is a Querydsl query type for User
 */
@Generated("com.querydsl.codegen.EntitySerializer")
public class QUser extends EntityPathBase<User> {
 private static final long serialVersionUID = 1153899872L;
 public static final QUser user = new QUser("user");
 public final StringPath address = createString("address");
 public final NumberPath<Integer> age = createNumber("age", Integer.class);
 public final NumberPath<Integer> id = createNumber("id", Integer.class);
 public final StringPath name = createString("name");
 public QUser(String variable) {
  super(User.class, forVariable(variable));
 } 

 public QUser(Path<? extends User> path) {
  super(path.getType(), path.getMetadata());
 } 

 public QUser(PathMetadata metadata) {
  super(User.class, metadata);
 }
}

我们建立好实体类之后,然后运行mvn clean complie命令,就会在

<outputDirectory>target/generated-sources/java</outputDirectory> 

目录下生成对应的查询类型。然后将生成的类都拷贝到项目中,即可。

本文涉及到的Entity如下:

package com.chhliu.springboot.jpa.entity;
import java.io.Serializable;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name="t_user")
public class User implements Serializable{
  /**
  *
  */
 private static final long serialVersionUID = 1L;
 @Id()
 @GeneratedValue(strategy = GenerationType.AUTO)
 private int id;
 private String name;
 private String address;
 private int age;
 …………省略getter,setter方法…………
 /**
  * attention:
  * Details:方便查看测试结果
  * @author chhliu
  */
 @Override
 public String toString() {
  return "User [id=" + id + ", name=" + name + ", address=" + address + ", age=" + age + "]";
 }
}

上面的这个实体类,主要用于单表操作。

package com.chhliu.springboot.jpa.entity;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToOne;
import javax.persistence.Table;
/**
 * 描述:TODO
 * @author chhliu
 */
@Entity
@Table(name="PERSON")
public class Person {
 @Id
 @GeneratedValue
 private Integer id;
 private String name;
 private String address; 

 @OneToOne(mappedBy="person", cascade={CascadeType.PERSIST, CascadeType.REMOVE, CascadeType.MERGE})
 private IDCard idCard;
  …………省略getter,setter方法…………
 @Override
 public String toString() {
  return "Person [id=" + id + ", name=" + name + ", address=" + address + ", idCard=" + idCard + "]";
 }
} 
package com.chhliu.springboot.jpa.entity;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToOne;
import javax.persistence.Table;
/**
 * 描述:
 * @author chhliu
 */
@Entity
@Table(name="IDCARD")
public class IDCard {
 @Id
 @GeneratedValue
 private Integer id;
 private String idNo;
 @OneToOne(cascade={CascadeType.MERGE, CascadeType.REMOVE, CascadeType.PERSIST}, fetch=FetchType.EAGER)
 private Person person;
  …………省略getter,setter方法…………
 @Override
 public String toString() {
  return "IDCard [id=" + id + ", idNo=" + idNo + ", person=" + person + "]";
 }
} 

上面两个Entity主要用于一对一关系的示例操作

package com.chhliu.springboot.jpa.entity;
import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;
/**
 * 描述:Order实体类
 * @author chhliu
 */
@Entity
@Table(name="ORDER_C")
public class Order {
 @Id
 @GeneratedValue
 @Column(name="ID")
 private Integer id; 

 @Column(length=20, name="ORDER_NAME")
 private String orderName; 

 @Column(name="COUNT")
 private Integer count; 

 @OneToMany(mappedBy = "order",cascade={CascadeType.PERSIST,CascadeType.REMOVE},fetch = FetchType.EAGER)
 private List<OrderItem> orderItems; 

  …………省略getter,setter方法…………
}
package com.chhliu.springboot.jpa.entity;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table; 

/**
 * 描述:OrderItem实体类
 * @author chhliu
 */
@Entity
@Table(name="ORDER_ITEM")
public class OrderItem {
 @Id
 @GeneratedValue
 @Column(name="ID", nullable=false)
 private Integer id; 

 @Column(name="ITEM_NAME", length=20)
 private String itemName; 

 @Column(name="PRICE")
 private Integer price; 

 @ManyToOne(cascade={CascadeType.PERSIST,CascadeType.REMOVE, CascadeType.MERGE}, fetch=FetchType.EAGER)
 @JoinColumn(name = "ORDER_ID")
 private Order order; 

  …………省略getter,setter方法…………
}

上面两个Entity用于展示一对多关系的示例操作。

首先,我们来看单表操作

1、使用spring data jpa

要想使用spring data jpa提供的QueryDSL功能,很简单,直接继承接口即可。Spring Data JPA中提供了QueryDslPredicateExecutor接口,用于支持QueryDSL的查询操作接口,如下:

package com.chhliu.springboot.jpa.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.querydsl.QueryDslPredicateExecutor;
import com.chhliu.springboot.jpa.entity.User;
public interface UserRepositoryDls extends JpaRepository<User, Integer>, QueryDslPredicateExecutor<User>{
// 继承接口
}

QueryDslPredicateExecutor接口提供了如下方法:

public interface QueryDslPredicateExecutor<T> {
 T findOne(Predicate predicate);
 Iterable<T> findAll(Predicate predicate);
 Iterable<T> findAll(Predicate predicate, Sort sort);
 Iterable<T> findAll(Predicate predicate, OrderSpecifier<?>... orders);
 Iterable<T> findAll(OrderSpecifier<?>... orders);
 Page<T> findAll(Predicate predicate, Pageable pageable);
 long count(Predicate predicate);
 boolean exists(Predicate predicate);
}

以上方法的使用和spring data jpa中的其他接口使用方法类似,详情请参考:http://www.jb51.net/article/137757.htm

测试如下:

public User findUserByUserName(final String userName){
  /**
   * 该例是使用spring data QueryDSL实现
   */
  QUser quser = QUser.user;
  Predicate predicate = quser.name.eq(userName);// 根据用户名,查询user表
  return repository.findOne(predicate);
 }

对应的sql如下:

复制代码 代码如下:

select user0_.id as id1_5_, user0_.address as address2_5_, user0_.age as age3_5_, user0_.name as name4_5_ from t_user user0_ where  user0_.name=?

单表操作示例代码如下:

package com.chhliu.springboot.jpa.repository;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import javax.transaction.Transactional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Component;
import com.chhliu.springboot.jpa.entity.QUser;
import com.chhliu.springboot.jpa.entity.User;
import com.querydsl.core.types.Predicate;
import com.querydsl.jpa.impl.JPAQueryFactory; 

/**
 * 描述:QueryDSL JPA
 * @author chhliu
 */
@Component
@Transactional
public class UserRepositoryManagerDsl {
 @Autowired
 private UserRepositoryDls repository; 

 @Autowired
 @PersistenceContext
 private EntityManager entityManager; 

  private JPAQueryFactory queryFactory; 

  @PostConstruct
  public void init() {
  queryFactory = new JPAQueryFactory(entityManager);
  } 

  public User findUserByUserName(final String userName){
  /**
   * 该例是使用spring data QueryDSL实现
   */
  QUser quser = QUser.user;
  Predicate predicate = quser.name.eq(userName);
  return repository.findOne(predicate);
 } 

 /**
  * attention:
  * Details:查询user表中的所有记录
  */
 public List<User> findAll(){
  QUser quser = QUser.user;
  return queryFactory.selectFrom(quser)
     .fetch();
 } 

 /**
  * Details:单条件查询
  */
 public User findOneByUserName(final String userName){
  QUser quser = QUser.user;
  return queryFactory.selectFrom(quser)
   .where(quser.name.eq(userName))
   .fetchOne();
 } 

 /**
  * Details:单表多条件查询
  */
 public User findOneByUserNameAndAddress(final String userName, final String address){
  QUser quser = QUser.user;
  return queryFactory.select(quser)
   .from(quser) // 上面两句代码等价与selectFrom
   .where(quser.name.eq(userName).and(quser.address.eq(address)))// 这句代码等同于where(quser.name.eq(userName), quser.address.eq(address))
   .fetchOne();
 } 

 /**
  * Details:使用join查询
  */
 public List<User> findUsersByJoin(){
  QUser quser = QUser.user;
  QUser userName = new QUser("name");
  return queryFactory.selectFrom(quser)
   .innerJoin(quser)
   .on(quser.id.intValue().eq(userName.id.intValue()))
   .fetch();
 } 

 /**
  * Details:将查询结果排序
  */
 public List<User> findUserAndOrder(){
  QUser quser = QUser.user;
  return queryFactory.selectFrom(quser)
   .orderBy(quser.id.desc())
   .fetch();
 } 

 /**
  * Details:Group By使用
  */
 public List<String> findUserByGroup(){
  QUser quser = QUser.user;
  return queryFactory.select(quser.name)
     .from(quser)
     .groupBy(quser.name)
     .fetch();
 } 

 /**
  * Details:删除用户
  */
 public long deleteUser(String userName){
  QUser quser = QUser.user;
  return queryFactory.delete(quser).where(quser.name.eq(userName)).execute();
 } 

 /**
  * Details:更新记录
  */
 public long updateUser(final User u, final String userName){
  QUser quser = QUser.user;
  return queryFactory.update(quser).where(quser.name.eq(userName))
   .set(quser.name, u.getName())
   .set(quser.age, u.getAge())
   .set(quser.address, u.getAddress())
   .execute();
 } 

 /**
  * Details:使用原生Query
  */
 public User findOneUserByOriginalSql(final String userName){
  QUser quser = QUser.user;
  Query query = queryFactory.selectFrom(quser)
    .where(quser.name.eq(userName)).createQuery();
  return (User) query.getSingleResult();
 } 

 /**
  * Details:分页查询单表
  */
 public Page<User> findAllAndPager(final int offset, final int pageSize){
  Predicate predicate = QUser.user.id.lt(10);
  Sort sort = new Sort(new Sort.Order(Sort.Direction.DESC, "id"));
  PageRequest pr = new PageRequest(offset, pageSize, sort);
  return repository.findAll(predicate, pr);
 }
}

多表操作示例(一对一)如下:

package com.chhliu.springboot.jpa.repository;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.chhliu.springboot.jpa.dto.PersonIDCardDto;
import com.chhliu.springboot.jpa.entity.QIDCard;
import com.chhliu.springboot.jpa.entity.QPerson;
import com.querydsl.core.QueryResults;
import com.querydsl.core.Tuple;
import com.querydsl.core.types.Predicate;
import com.querydsl.jpa.impl.JPAQuery;
import com.querydsl.jpa.impl.JPAQueryFactory; 

@Component
public class PersonAndIDCardManager {
 @Autowired
 @PersistenceContext
 private EntityManager entityManager; 

 private JPAQueryFactory queryFactory; 

 @PostConstruct
 public void init() {
  queryFactory = new JPAQueryFactory(entityManager);
 } 

 /**
  * Details:多表动态查询
  */
 public List<Tuple> findAllPersonAndIdCard(){
  Predicate predicate = (QPerson.person.id.intValue()).eq(QIDCard.iDCard.person.id.intValue());
  JPAQuery<Tuple> jpaQuery = queryFactory.select(QIDCard.iDCard.idNo, QPerson.person.address, QPerson.person.name)
    .from(QIDCard.iDCard, QPerson.person)
    .where(predicate);
  return jpaQuery.fetch();
 } 

 /**
  * Details:将查询结果以DTO的方式输出
  */
 public List<PersonIDCardDto> findByDTO(){
  Predicate predicate = (QPerson.person.id.intValue()).eq(QIDCard.iDCard.person.id.intValue());
  JPAQuery<Tuple> jpaQuery = queryFactory.select(QIDCard.iDCard.idNo, QPerson.person.address, QPerson.person.name)
    .from(QIDCard.iDCard, QPerson.person)
    .where(predicate);
  List<Tuple> tuples = jpaQuery.fetch();
  List<PersonIDCardDto> dtos = new ArrayList<PersonIDCardDto>();
  if(null != tuples && !tuples.isEmpty()){
   for(Tuple tuple:tuples){
    String address = tuple.get(QPerson.person.address);
    String name = tuple.get(QPerson.person.name);
    String idCard = tuple.get(QIDCard.iDCard.idNo);
    PersonIDCardDto dto = new PersonIDCardDto();
    dto.setAddress(address);
    dto.setIdNo(idCard);
    dto.setName(name);
    dtos.add(dto);
   }
  }
  return dtos;
 } 

 /**
  * Details:多表动态查询,并分页
  */
 public QueryResults<Tuple> findByDtoAndPager(int offset, int pageSize){
  Predicate predicate = (QPerson.person.id.intValue()).eq(QIDCard.iDCard.person.id.intValue());
  return queryFactory.select(QIDCard.iDCard.idNo, QPerson.person.address, QPerson.person.name)
    .from(QIDCard.iDCard, QPerson.person)
    .where(predicate)
    .offset(offset)
    .limit(pageSize)
    .fetchResults();
 }
}

上面将查询结果以DTO的方式输出的示例中,在查询结束后,将查询结果手动的转换成了DTO对象,这种方式其实不太优雅,QueryDSL给我们提供了更好的方式,见下面的示例:

/**
  * Details:方式一:使用Bean投影
  */
 public List<PersonIDCardDto> findByDTOUseBean(){
  Predicate predicate = (QPerson.person.id.intValue()).eq(QIDCard.iDCard.person.id.intValue());
  return queryFactory.select(
    Projections.bean(PersonIDCardDto.class, QIDCard.iDCard.idNo, QPerson.person.address, QPerson.person.name))
    .from(QIDCard.iDCard, QPerson.person)
    .where(predicate)
    .fetch();
 } 

 /**
  * Details:方式二:使用fields来代替setter
  */
 public List<PersonIDCardDto> findByDTOUseFields(){
  Predicate predicate = (QPerson.person.id.intValue()).eq(QIDCard.iDCard.person.id.intValue());
  return queryFactory.select(
    Projections.fields(PersonIDCardDto.class, QIDCard.iDCard.idNo, QPerson.person.address, QPerson.person.name))
    .from(QIDCard.iDCard, QPerson.person)
    .where(predicate)
    .fetch();
 } 

 /**
  * Details:方式三:使用构造方法,注意构造方法中属性的顺序必须和构造器中的顺序一致
  */
 public List<PersonIDCardDto> findByDTOUseConstructor(){
  Predicate predicate = (QPerson.person.id.intValue()).eq(QIDCard.iDCard.person.id.intValue());
  return queryFactory.select(
    Projections.constructor(PersonIDCardDto.class, QPerson.person.name, QPerson.person.address, QIDCard.iDCard.idNo))
    .from(QIDCard.iDCard, QPerson.person)
    .where(predicate)
    .fetch();
 }

上面只是提供了几种思路,当然,还可以使用@QueryProjection来实现,非常灵活。

一对多示例:

package com.chhliu.springboot.jpa.repository;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.chhliu.springboot.jpa.entity.QOrder;
import com.chhliu.springboot.jpa.entity.QOrderItem;
import com.querydsl.core.Tuple;
import com.querydsl.core.types.Predicate;
import com.querydsl.jpa.impl.JPAQuery;
import com.querydsl.jpa.impl.JPAQueryFactory;
@Component
public class OrderAndOrderItemManager { 

 @Autowired
 @PersistenceContext
 private EntityManager entityManager; 

 private JPAQueryFactory queryFactory; 

 @PostConstruct
 public void init() {
  queryFactory = new JPAQueryFactory(entityManager);
 } 

 /**
  * Details:一对多,条件查询
  */
 public List<Tuple> findOrderAndOrderItemByOrderName(String orderName){
  //添加查询条件
  Predicate predicate = QOrder.order.orderName.eq(orderName);
  JPAQuery<Tuple> jpaQuery = queryFactory.select(QOrder.order, QOrderItem.orderItem)
          .from(QOrder.order, QOrderItem.orderItem)
          .where(QOrderItem.orderItem.order.id.intValue().eq(QOrder.order.id.intValue()), predicate); 

  //拿到结果
  return jpaQuery.fetch();
 } 

 /**
  * Details:多表连接查询
  */
 public List<Tuple> findAllByOrderName(String orderName){
  //添加查询条件
  Predicate predicate = QOrder.order.orderName.eq(orderName);
  JPAQuery<Tuple> jpaQuery = queryFactory.select(QOrder.order, QOrderItem.orderItem)
          .from(QOrder.order, QOrderItem.orderItem)
          .rightJoin(QOrder.order)
          .on(QOrderItem.orderItem.order.id.intValue().eq(QOrder.order.id.intValue()));
  jpaQuery.where(predicate);
  //拿到结果
  return jpaQuery.fetch();
 }
}

从上面的示例中,我们可以看出,QueryDSL大大的简化了我们的操作

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

您可能感兴趣的文章:

  • Spring Boot中使用Spring-data-jpa实现数据库增删查改
  • SpringBoot集成Spring Data JPA及读写分离
  • SpringBoot JPA 表关联查询实例
  • SpringBoot JPA实现增删改查、分页、排序、事务操作等功能示例
  • Spring Boot + Jpa(Hibernate) 架构基本配置详解
  • 详解基于Spring Boot与Spring Data JPA的多数据源配置
  • 基于spring boot 1.5.4 集成 jpa+hibernate+jdbcTemplate(详解)
  • Spring Boot 添加MySQL数据库及JPA实例
  • 在Spring Boot中使用Spring-data-jpa实现分页查询
时间: 2018-04-01

详解基于Spring Boot与Spring Data JPA的多数据源配置

由于项目需要,最近研究了一下基于spring Boot与Spring Data JPA的多数据源配置问题.以下是传统的单数据源配置代码.这里使用的是Spring的Annotation在代码内部直接配置的方式,没有使用任何XML文件. @Configuration @EnableJpaRepositories(basePackages = "org.lyndon.repository") @EnableTransactionManagement @PropertySource("

Spring Boot + Jpa(Hibernate) 架构基本配置详解

1.基于springboot-1.4.0.RELEASE版本测试 2.springBoot + hibernate + Druid + MySQL + servlet(jsp) 不废话,直接上代码 一.maven的pom文件 <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi=&qu

Spring Boot中使用Spring-data-jpa实现数据库增删查改

在实际开发过程中,对数据库的操作无非就"增删改查".就最为普遍的单表操作而言,除了表和字段不同外,语句都是类似的,开发人员需要写大量类似而枯燥的语句来完成业务逻辑. 为了解决这些大量枯燥的数据操作语句,我们第一个想到的是使用ORM框架,比如:Hibernate.通过整合Hibernate之后,我们以操作Java实体的方式最终将数据改变映射到数据库表中. 为了解决抽象各个Java实体基本的"增删改查"操作,我们通常会以泛型的方式封装一个模板Dao来进行抽象简化,但是这

在Spring Boot中使用Spring-data-jpa实现分页查询

在我们平时的工作中,查询列表在我们的系统中基本随处可见,那么我们如何使用jpa进行多条件查询以及查询列表分页呢?下面我将介绍两种多条件查询方式. 1.引入起步依赖   <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency&

SpringBoot JPA实现增删改查、分页、排序、事务操作等功能示例

今天给大家介绍一下SpringBoot中JPA的一些常用操作,例如:增删改查.分页.排序.事务操作等功能. 下面先来介绍一下JPA中一些常用的查询操作: //And --- 等价于 SQL 中的 and 关键字,比如 findByHeightAndSex(int height,char sex): public List<User> findByHeightAndSex(int height,char sex); // Or --- 等价于 SQL 中的 or 关键字,比如 findByHei

Spring Boot 添加MySQL数据库及JPA实例

最近在学习Spring Boot,继续前面的学习,这一次我们加入MySQL数据库和JPA. 配置: pom.xml文件 <!-- 添加Mysql和JPA--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dep

基于spring boot 1.5.4 集成 jpa+hibernate+jdbcTemplate(详解)

1.pom添加依赖 <!-- spring data jpa,会注入tomcat jdbc pool/hibernate等 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <

SpringBoot集成Spring Data JPA及读写分离

相关代码: github OSCchina JPA是什么 JPA(Java Persistence API)是Sun官方提出的Java持久化规范,它为Java开发人员提供了一种对象/关联映射工具 来管理Java应用中的关系数据.它包括以下几方面的内容: 1.ORM映射 支持xml和注解方式建立实体与表之间的映射. 2.Java持久化API 定义了一些常用的CRUD接口,我们只需直接调用,而不需要考虑底层JDBC和SQL的细节. 3.JPQL查询语言 这是持久化操作中很重要的一个方面,通过面向对象

SpringBoot JPA 表关联查询实例

今天给大家介绍一下如何利用JPA实现表关联查询. 今天给大家举一个一对多的关联查询,并且是使用JPA原生的findBy语句实现的. 例子中总共有两个实体类,一个是Floor(商品楼层类),另一个是FloorContent(商品楼层内容表).下面看两张表的源代码: Floor类: package cms.model; import cms.model.base.BaseDomain; import org.hibernate.annotations.GenericGenerator; import

Yii2.0表关联查询实例分析

本文实例讲述了Yii2.0表关联查询的方法.分享给大家供大家参考,具体如下: 你可以使用 ActiveRecord 来进行关联查询(比如,从A表读取数据时把关联的B表数据也一起读出来), 在Active Record中,获取关联数据可以像访问主表ActiveRecord对象的属性(property)一样简单. 比如,通过合适的关系声明,你可以使用 $customer->orders 来获取一个 Order 对象数组,代表该客户下的订单. 要声明一个关系(relation),定义一个getter方

thinkphp中的多表关联查询的实例详解

thinkphp中的多表关联查询的实例详解 在进行后端管理系统的编程的时候一般会使用框架来进行页面的快速搭建,我最近使用比较多的就是thinkphp框架,thinkphp框架的应用其实就是把前端和后端进行分割管理,前端用户登录查询系统放在thinkphp中的home文件夹中进行管理,后端管理系统放在thinkphp中的admin文件夹中进行管理.对了,在使用thinkphp框架的时候是是要用到mvc架构的,mvc架构就是model(数据模型).view(视图).controller(控制器)的结

MongoDB多表关联查询操作实例详解

本文实例讲述了MongoDB多表关联查询操作.分享给大家供大家参考,具体如下: Mongoose的多表关联查询 首先,我们回忆一下,MySQL多表关联查询的语句: student表: calss表: 通过student的classId关联进行查询学生名称,班级的数据: SELECT student.name,student.age,class.name FROM student,class WHERE student.classId = class.id Mongoose多表联合查询(还是以众所

Yii2.0框架模型多表关联查询示例

本文实例讲述了Yii2.0框架模型多表关联查询.分享给大家供大家参考,具体如下: 联表查询--hasMany: use app\models\User; $right = Right::findOne(2); //$user = User::find()->where(['right_id' => $right->attributes['id']])->all(); $user = $right->hasMany(User::className(),['right_id' =

Mybatis多表关联查询的实现(DEMO)

概要 本节要实现的是多表关联查询的简单demo.场景是根据id查询某商品分类信息,并展示该分类下的商品列表. 一.Mysql测试数据 新建表Category(商品分类)和Product(商品),并插入几条测试数据. create table Category ( Id int not null auto_increment, Name varchar(80) null, constraint pk_category primary key (Id) ); INSERT INTO category

Yii2中多表关联查询hasOne hasMany的方法

表positionContent id position_id content_title content_id is_recommend list_sort update_time create_time 10 14 大成成长 160910 1 1 2017-02-09 11:51:56 2017-02-09 11:51:56 11 15 创新成长 160910 1 1 2017-02-09 11:52:08 2017-02-09 11:52:08 position表 id name titl

Yii2中使用join、joinwith多表关联查询

表结构 现在有客户表.订单表.图书表.作者表, 客户表Customer (id customer_name) 订单表Order (id order_name customer_id book_id) 图书表 (id book_name author_id) 作者表 (id author_name) 模型定义 下面是这4个个模型的定义,只写出其中的关联 Customer class Customer extends \yii\db\ActiveRecord { // 这是获取客户的订单,由上面我们

ThinkPHP中关联查询实例

本文实例讲述了ThinkPHP中关联查询的用法.分享给大家供大家参考.具体分析如下: 在THINKPHP中关联查询(多表查询)可以使用 table() 方法或和join方法,如下示例所示: 1.table() 复制代码 代码如下: $list = $user->table('user_status stats, user_profile profile')->where('stats.id = profile.typeid')->field('stats.id as id, stats.

MongoDB中多表关联查询($lookup)的深入讲解

一.  聚合框架 聚合框架是MongoDB的高级查询语言,它允许我们通过转换和合并多个文档中的数据来生成新的单个文档中不存在的信息. 聚合管道操作主要包含下面几个部分: 命令 功能描述 $project 指定输出文档里的字段. $match 选择要处理的文档,与fine()类似. $limit 限制传递给下一步的文档数量. $skip 跳过一定数量的文档. $unwind 扩展数组,为每个数组入口生成一个输出文档. $group 根据key来分组文档. $sort 排序文档. $geoNear