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选右表与左表的差集加上交集。暂且如此了。如果哪位看到我的文章有更好的方法请不吝赐教。