Spring Data JPA 多个实体类表联合视图查询

Spring Data JPA 查询数据库时,如果两个表有关联,那么就设个外键,在查询的时候用Specification创建Join 查询便可。但是只支持左连接,不支持右连接,虽说左右连接反过来就能实现一样的效果,但是这就关系到谁是谁的外键的问题。外键搞起来有时候确实麻烦。所以为了查询个视图,没有找到更好的办法,只好在service层查两次合并起来了。

两个实体类:

@Entity
@Table(name="tb_user")
public class UserInfo implements Serializable{

    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private Long userId;
    private String userName;
    private String password;
    private String name;
    private int age;
    private String sex;
    private String email;
    private Date dateOfBirth;
    private String telNumber;
    private String education;
    private String school;
//    @ManyToOne
//    @JoinColumn(name="addressId")
//    private Address address;
    private Long addressId;
// getter and setter
}
@Entity
@Table(name="tb_address")
public class Address implements Serializable{
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long addressId;
   private Long userId 
private String areaCode; private String country; private String province; private String city; private String area; private String detailAddress; // getter and setter }

创建一个类包含UserInfo和Address中的所有属性:

public class ViewInfo implements Serializable{
    
    private UserInfo userInfo;
    private Address address;
    public ViewInfo(){
        
    }
    public ViewInfo(UserInfo userInfo){
        Address address = new Address();
        this.userInfo = userInfo;
        this.address = address;
    }
    public ViewInfo(Address address){
        UserInfo userInfo = new UserInfo();
        this.userInfo = userInfo;
        this.address = address;
    }
    public ViewInfo(UserInfo userInfo,Address address){
        this.userInfo = userInfo;
        this.address = address;
    }
// getter and setter
}

接下来就是在DAO层中写自定义查询语句了:

public interface UserInfoRepository extends CrudRepository<UserInfo, Long>{
    @Query(value="SELECT new com.demo.test.Entity.ViewInfo(u,a)FROM "
    + " UserInfo u, com.demo.test.Entity.Address a WHERE u.addressId = a.id) ")
    List<ViewInfo> findViewInfo();
    @Query("SELECT new com.demo.test.Entity.ViewInfo"
    + "(u) FROM UserInfo u WHERE u.addressId IS NULL OR u.addressId NOT IN (SELECT a.id FROM Address a)")
    List<ViewInfo> findViewInfoLeft();
    @Query("SELECT new com.demo.test.Entity.ViewInfo"
    + "(a) FROM Address a WHERE a.id NOT IN (SELECT u.addressId FROM UserInfo u WHERE u.addressId IS NOT NULL)")
    List<ViewInfo> findViewInfoRight();
    
    
}

然后在service层中查询各个部分:

    public void summary(){
      System.out.println("=======middle part=======");
      List<ViewInfo> userInfos = userInfoRepository.findViewInfo();
      for(ViewInfo item : userInfos){
          System.out.println(item.getUserInfo().getUserName()+" "+item.getAddress().getCity());
      }
      System.out.println("=======left part=======");
      List<ViewInfo> userInfoLeft = userInfoRepository.findViewInfoLeft();
      for(ViewInfo item : userInfoLeft){
          System.out.println(item.getUserInfo().getUserName()+" "+item.getAddress().getCity());
      }
      System.out.println("=======right part=======");
      List<ViewInfo> userInfoRight = addressRepository.findViewInfoRight();
      for(ViewInfo item : userInfoRight){
          System.out.println(item.getUserInfo().getUserName()+" "+item.getAddress().getCity());
      }
     
    }

数据库的Inner Join选交集,Outer Join 选并集,Left Join 选左表与右表的差集加上交集,Right Join选右表与左表的差集加上交集。暂且如此了。如果哪位看到我的文章有更好的方法请不吝赐教。

posted @ 2016-08-27 16:52  浮生半瓶醋  阅读(1157)  评论(0编辑  收藏  举报