如何使用JPA的nativeQuery将查询出的信息封装为对象

在实际的项目中,很多时候需要很复杂的查询,而JPQL有些功能是不支持的,Criteria的写法又过于复杂了。

用原生sql的方式进行查询会省很多事(缺点是和具体使用的数据库高度耦合了),但是使用JPA的createnativeQuery查询出来的却是一个Object对象,需要我们自己做一些封装的操作。

//查询语句,本地sql
String sql = "SELECT telephone, password FROM user where id = 1";
//查询
Object result = ssoEntityManager.createNativeQuery(sql)
                .getSingleResult();
//将对象转换为数据
Object[] params = (Object[]) result;
//分别封装各个参数
UserDO userDO = new UserDO();
userDO.setTelephone(params[0].toString());
userDO.setPassword(params[1].toString());

如果是查询ResultList,则循环封装

这样的做法很麻烦,而且容易出错。其实JPA已经提供了对应的参数封装方法。

语法如下


query.unwrap(SQLQuery.class)
    .setResultTransformer(
        Transformers.aliasToBean(要转换的类)
    )
    .list();//根据实际情况调用不同的方法,list--》获取一个集合

完整的Demo

public class UserDO {

    public UserDO () {}

    private String telephone;

    private String password;

    //Setter,Getter
}
String sql = "SELECT telephone, password FROM user";

Query query = ssoEntityManager.createNativeQuery(sql);

List list = query.unwrap(SQLQuery.class)
            .setResultTransformer(Transformers.aliasToBean(UserDO.class))
            .list();

要注意:sql中的查询字段要和DO类中的属性相对应,如果有别名,那么别名要和属性对应

原生SQL不支持SetParameter方法,不能使用?0,:param等占位符,否则会报一个奇葩的错。

类中的属性仅支持基本类型、包装类型和String类型。枚举、其它类都是不支持的。(关于这点可以使用取巧用Set方法做转换。例子如下:)

class User{
    private Gender sex;//性别的枚举,

    public void setSex(String sex) {
        this.sex = Gender.valueOf(sex);
    }
}

你可能感兴趣的:(☀框架技术)