版权声明:本文为博主原创文章,未经博主允许不得转载。 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);