如何将列名添加到ResultSet。我将Java与EntityManager一起使用

时间:2018-01-25 14:17:08

标签: java sql hibernate entitymanager

是否可以读出列名?

我的应用程序:Java,SpringBoot,JPA,Hibernate

我的代码:

Query query = entityManager.createNativeQuery(
          "select name as Name, concat('Time:',time, ' AND:', event) as FOO 
          from XYZ
          where NAME = 'BLA'");
List<Object[]> resultList = query.getResultList();

我需要在ResultSet的第一个Object []中使用列名(Name和FOO) 在其他地方...

我难看的解决方案:

private String getColumnNames(String sql) {
    StringBuilder sb = new StringBuilder();
    String part1 = sql.split("from")[0];

    part1 = part1.replaceAll("\\(.*?\\)", "");

    String[] columns = part1.split(",");
    for (String column : columns) {
        String alias = column;
        if (column.toUpperCase().contains(" AS ")) {
            alias = column.toUpperCase().split(" AS ")[1];
        }
        alias = alias.replace("'","");
        sb.append(alias+",");
    }

    String columnNames = sb.toString();
    if (columnNames.length() != 0) {
        columnNames = columnNames.substring(0, columnNames.length()-1);
    }

    return columnNames;
}

由于

3 个答案:

答案 0 :(得分:1)

您应该使用createNativeQuery()的其他重载版本:

public Query createNativeQuery(String sqlString, Class resultClass);

public Query createNativeQuery(String sqlString, String resultSetMapping);

通过这种方式,您可以将查询结果映射到包含namefoo字段的类。

例如,第一种方式:

Query query = entityManager.createNativeQuery(
          "select name as Name, concat('Time:',time, ' AND:', event) as FOO 
          from XYZ
          where NAME = 'BLA'", Xyz.class);
List<Xyz> resultList = query.getResultList();

请注意,query.getResultList()将返回原始类型。

答案 1 :(得分:0)

你应该做的是:

  1. 首先创建一个包含NameFOO属性的实体,以便您可以将其作为query.getResultList()的结果进行映射。
  2. 然后使用List<YourEntity>代替List<Object[]
  3. 进行映射
  4. 最后一件事是为请求定义一个mapper,以便它可以将这些结果映射到所需的实体,如果查询使用不同于实体中的属性名称,则使用{{ 3}}。
  5. 您可以查看@SqlResultSetMapping以获取更多详细信息。

    修改

    如果您无法创建新的Entity来映射结果,则可以将HashMap中的结果映射到Object[]的每个元素中,如下所示:

    Map results = new HashMap();
    
    results.put("Name", obj[0]);
    results.put("Foo", obj[1]);
    

答案 2 :(得分:0)

是的,有可能。让我们假设您的实体名称为XYZ,而您的存储库将为XYZRepository,让我们创建一个仅包含名称和eventDetais的DTO,因为我们只想从表中提取这两个详细信息。

public class XyzDTO {
    String name;
    String eventDetails;
    public XyzDTO() {
    }
    public XyzDTO(String name, String eventDetails) {
     this.name = name;
     this.eventDetails =eventDetails;
    }
}

此代码将用XYZRepository编写。

@Query(nativeQuery = true)
List<Details> getList();

此代码将以XYZ实体编写。

@SqlResultSetMapping(name = "getList",
        classes = @ConstructorResult(targetClass = XyzDTO.class,
            columns = {@ColumnResult(name = "name", type = String.class),
                @ColumnResult(name = "eventDetails", type = String.class)}))
@NamedNativeQuery(name = "XYZ.getList",
        query = "select name as name, concat('Time:',time, ' AND:', event) as eventDetails from XYZ where name = 'BL")
public class XYZ implements Serializable {

}