微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在Spring Boot应用程序中将JPQL查询检索为DTO

如何解决在Spring Boot应用程序中将JPQL查询检索为DTO

我基本上想做的是运行一个查询,并将结果放入类Account的对象中。需要强调的是,查询在两个表之间执行了JOIN,而这两个表未映射为@Entity。那我该怎么办呢?

这是我的 FooRepository.java

@Repository
public interface FooRepository extends JpaRepository<Foo,Long> {

  Foo findById(Long id);

@Query(value = "SELECT Q1.ACCOUNT_NAME," +
          "Q2.GROUP_NAME  " +
          "FROM USERS_DEV Q1\n" +
          "JOIN USERS_GROUPS Q2 ON Q1.ACCOUNT_NAME = Q2.ACCOUNT_NAME\n" +
          "WHERE LOWER(Q1.ACCOUNT_NAME) = 'john.pit'",nativeQuery = true)
  List<Account> getAllAccounts();

那我该如何更改查询以获得所需的结果?

这是我的 Account.java

public class Account {

    String samAccountName;
    String groupName;

    public Account(String accountName,String groupName) {
        this.accountName = accountName;
        this.groupName = groupName;
    }

    public String getAccountName() {
        return accountName;
    }

    public void setAccountName(String accountName) {
        this.accountName = accountName;
    }

    public String getGroupName() {
        return groupName;
    }

    public void setGroupName(String groupName) {
        this.groupName = groupName;
    }
}

解决方法

您可以使用EntityManagerResultTransformer

entityManager.createNativeQuery(
    "SELECT Q1.ACCOUNT_NAME," +
    "Q2.GROUP_NAME  " +
    "FROM USERS_DEV Q1 " +
    "JOIN USERS_GROUPS Q2 ON Q1.ACCOUNT_NAME = Q2.ACCOUNT_NAME " +
    "WHERE LOWER(Q1.ACCOUNT_NAME) = 'john.pit'"
)
            .unwrap(NativeQuery.class)
            .setResultTransformer(new ResultTransformer() {
                @Override
                public Object transformTuple(Object[] tuple,String[] aliases) {
                    return new Account(
                        (String) tuple[0],(String) tuple[1]
                    );
                }

                @Override
                public List transformList(List collection) {
                    return collection;
                }

            })
            .getResultList();

可能需要强制转换。

,

作为替代方案,您可以通过以下方式将@NamedNativeQuery@SqlResultSetMapping结合使用:

@Entity
@NamedNativeQuery(
  name = "findAllAccounts",query = 
     "SELECT " +
     "  Q1.ACCOUNT_NAME AS accountName," +
     "  Q2.GROUP_NAME AS groupName " +
     "FROM USERS_DEV Q1 " +
     "JOIN USERS_GROUPS Q2 ON Q1.ACCOUNT_NAME = Q2.ACCOUNT_NAME " + 
     "WHERE LOWER(Q1.ACCOUNT_NAME) = 'john.pit'",resultSetMapping = "findAllAccountsMapping"
)
@SqlResultSetMapping(
   name = "findAllAccountsMapping",classes = @ConstructorResult(
      targetClass = Account.class,columns = {
         @ColumnResult(name="accountName"),@ColumnResult(name="groupName"),}
   )
)
public class Foo {
   // ...
}

FooRepository

@Repository
public interface FooRepository extends JpaRepository<Foo,Long> {

  @Query(name = "findAllAccounts",nativeQuery = true)
  List<Account> getAllAccounts();
}

有关其他详细信息,请参见休眠documentation

,

也许我错了,但我记得您可以(使用HQL)执行以下操作:

@Query("select new Account(u.name,g.groupName) " +
          "from User as u" +
          "join u.group as g" +
          "where LOWER(u.name) = 'john.pit'")

语法可能是错误的,但是我确定如果使用HQL,则可以在select语句中使用DTO构造函数。

希望这对您有帮助:D

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。