SpringBoot JPA查询映射到自定义实体类

和 SegmentFault上的文章(//segmentfault.com/a/1190000021869465)一样, 都是俺账号

场景

举一个简单的栗子:
比如有一个User实体类

@Data
@Entity
public class User{

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

private String userName;

private String password;

}

然后有一个Email的实体类

@Data
@Entity
public class Email{

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

private String account;

private String code;

private boolean active;

}

以及一个UserRelation实体类,用来维护其他表与User之间的关联

@Data
@Entity
public class UserRelation{

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

private Long userId;

private Long emailId;

}

每个实体类都有其对应的Repository接口,用来实现CRUD。

最后有一个领域类UserPo

@Data
@Entity
public class UserPo{

private String userName;

private String account;

}

那么这个时候在UserRelationRepository里创建一个 findUserPo( Long userId )方法,如何让findUserPo可以返回一个UserPo对象呢?

public interface UserRelationRepository extends JpaRepository<UserRelation, Long> {

UserPo findUserPo(Long id);

}

实现

JPA可以自定义SQL语句进行查询,然后查询语句可以通过原生SQL语句(原生SQL语句要在@Query注解里加 nativeQuery = true)进行查询也可以通过JPQL进行查询。

这里通过 JPQL(Java Persistence Query Language) 进行查询,其特征与原生SQL语句类似,并且完全面向对象,通过类名和属性访问,而不是表名和表的属性。

由此findUserPo修改之后就像这样

public interface UserRelationRepository extends JpaRepository<UserRelation, Long> {

// 注意这里没有nativeQuery = true
@Query(value = "SELECT new com.xxx.xxx.bean.po.UserPo(u.userName, e.account) "+
"FROM UserRelation ur JOIN User u ON ur.userId = u.id"+
"JOIN Email e ON ur.emailId = e.id WHERE ur.userId = ?1 ")
UserPo findUserPo(Long id);

}
  • 这样就可以在查询的时候返回值自定义实体类了

  • 注意上面的SQL语句都是面向对象的,对应的字段都是实体类里面的属性