借助JDK8函数式轻松实现JPA原生sql转换为普通pojo或dto等model对象

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/c5113620/article/details/90696671

jpa有原生sql查询,.createNativeQuery(sql).getResultList(),但是结果转换需要是Entity才行,对于普通model对象需要自己每次循环list遍历,很不方便
借助函数式编程Function,方便快速实现结果转为普通model对象

import lombok.Data;
import lombok.experimental.Accessors;

import java.util.function.Function;

UserRole.java
@Data
@Accessors(chain = true)
public class UserRole  {


    private int id;
    private String user;
    private String name;

    //lambda函数式,转换jpa原生sql查询结果,一行结果是一个Object[],转为一个对象
    public static Function<Object[], UserRole> function = e->new UserRole().setId((Integer) e[0]).setUser((String) e[1]).setName((String) e[2]);

}
DbUtil.java
import javax.persistence.EntityManager;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Function;

/**
 * jpa原生sql查询工具
 *
 */
public class DbUtil {

    /**
     * jpa原生sql查询后转换为对象
     * @param sql    查询语句
     * @param func   转换一条结果为一个对象,定义在每个接收的model内
     * @param <T>    接收的类型
     * @return  返回list 或 null
     */
    public static  <T> T sqlObj(String sql, Function func){
        List res = SpringUtil.getBean(EntityManager.class).createNativeQuery(sql).getResultList();
        if (res == null || res.isEmpty())
            return null;
        List<T> resList = new ArrayList<>();
        ((List<Object[]>) res).forEach(e->resList.add((T)func.apply(e)));
        return (T) resList;

    }

    /**
     * 方便对sql只有一条结果,直接返回对象,不然需要sqlObj获取list,然后list.get(0)
     * @param sql
     * @param func
     * @param <T>
     * @return
     */
    public static <T> T sqlObjOne(String sql, Function func){
        List res = sqlObj(sql,func);
        if (res == null)
            return null;
        if (res.size()>1)
            throw new RuntimeException("DbUtil.sqlObjOne expect only one result, find "+res.size());
        return (T)res.get(0);
    }

    /**
     * sql查询结果只有一列的,一个总数,一个字符等等
     * @param sql
     * @param T
     * @param <T>
     * @return
     */
    public static <T> T sqlCast(String sql,Class<T> T){
        Object o = SpringUtil.getBean(EntityManager.class).createNativeQuery(sql).getSingleResult();
        //对一些类型做特殊处理
        //count(*)返回BigInteger类型
        if (o instanceof BigInteger){
            Long res = ((BigInteger) o).longValue();
            return (T)res;
        }
        return (T)o;
    }

}
        //list
        List<UserRole> userRoles = DbUtil.sqlObj(sql,UserRole.function);
        userRoles.forEach(e-> System.out.println(e.getUser()));

//        sql+="LIMIT 1";
//        UserRole userRole = DbUtil.sqlObj(sql,UserRole.function);
//        System.out.println(userRole.getUser());
        //one
        sql+="LIMIT 1";
        UserRole userRole = DbUtil.sqlObjOne(sql,UserRole.function);
        System.out.println(userRole.getUser());

        // one string
        sql="select user from t_uac_users limit 1";
        String user = DbUtil.sqlCast(sql,String.class);
        System.out.println(user);

        //total count
        sql = "select count(*) from t_uac_users limit 1";
        long count = DbUtil.sqlCast(sql,Long.class);
        System.out.println(count);

猜你喜欢

转载自blog.csdn.net/c5113620/article/details/90696671