基于Hibernate JPA,使用EntityManager实现
全部serviceImpl服务都继承通用服务类。避免频繁创建实体类。通用一个dao层。使用手搓SQL查询(sql注入使用其他方式解决)
支持返回:List<Map>、List<T>、Integer、String、<T>、Map
支持方法:save、delete、update、findOne、executeBySQL、batchSave、batchUpdate、getListBySQL、getNumBySQL、getStringBySQL
1、SQL结果转换类
import lombok.extern.slf4j.Slf4j;
import org.hibernate.transform.AliasToBeanResultTransformer;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
@Slf4j
public class SqlResultTransformer extends AliasToBeanResultTransformer {
private Class resultClass;
public SqlResultTransformer(Class resultClass) {
super(resultClass);
this.resultClass = resultClass;
}
public Object transformTuple(Object[] tuple, String[] aliases) {
Object obj = null;
try {
obj = resultClass.newInstance();
} catch (InstantiationException e1) {
e1.printStackTrace();
} catch (IllegalAccessException e1) {
e1.printStackTrace();
}
Method[] methods = resultClass.getMethods();
for(int k=0;k<aliases.length;k++){
String aliase=aliases[k];
aliase = aliase.replaceAll("_", "").toLowerCase();
char[] ch = aliase.toCharArray();
ch[0] = Character.toUpperCase(ch[0]);
String s = new String(ch);
String[] names = new String[] { ("set" + s).intern(),
("get" + s).intern(), ("is" + s).intern(),
("read" + s).intern() };
Method setter = null;
Method getter = null;
int length = methods.length;
for (int i = 0; i < length; ++i) {
Method method = methods[i];
if (!Modifier.isPublic(method.getModifiers()))
continue;
String methodName = method.getName();
for (String name : names) {
if (name.toLowerCase().equals(methodName.toLowerCase())) {
if (name.startsWith("set") || name.startsWith("read"))
setter = method;
else if (name.startsWith("get") || name.startsWith("is"))
getter = method;
}
}
}
if(getter!=null){
Object[] param = buildParam(getter.getReturnType().getName(), tuple[k]);
try {
setter.invoke(obj, param);
} catch (Exception e) {
e.printStackTrace();
}
}
}
return obj;
}
private final static Object[] buildParam(String paramType, Object value) {
Object[] param = new Object[1];
if (paramType.equalsIgnoreCase("java.lang.String")) {
param[0] = (String)(value);
} else if (paramType.equalsIgnoreCase("int")
|| paramType.equalsIgnoreCase("java.lang.Integer")) {
try {
param[0] = (Integer)(value);
} catch (Exception e) {
param[0] = Integer.valueOf(value.toString());
}
} else if (paramType.equalsIgnoreCase("long")|| paramType.equalsIgnoreCase("java.lang.Long")) {
param[0] = (Long)(value);
} else if (paramType.equalsIgnoreCase("double")|| paramType.equalsIgnoreCase("java.lang.Double")) {
try {
param[0] = (Double)(value);
} catch (Exception e) {
param[0] = Double.valueOf(value.toString());
}
} else if (paramType.equalsIgnoreCase("float")|| paramType.equalsIgnoreCase("java.lang.Float")) {
param[0] = (Float)(value);
} else if (paramType.equalsIgnoreCase("char")
|| paramType.equalsIgnoreCase("Character")) {
param[0] = (char)(value);
} else if (paramType.equalsIgnoreCase("java.util.Date")){
param[0] = (java.util.Date)(value);
}
else if (paramType.equalsIgnoreCase("java.sql.Timestamp")){
param[0] = (java.sql.Timestamp)(value);
}else if (paramType.equalsIgnoreCase("java.math.BigInteger")){
param[0] = (java.math.BigInteger)(value);
}else if (paramType.equalsIgnoreCase("java.math.BigDecimal")){
param[0] = (java.math.BigDecimal)value;
}
return param;
}
}
2、Dao
import org.hibernate.query.internal.NativeQueryImpl;
import org.hibernate.transform.ResultTransformer;
import org.hibernate.transform.Transformers;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import java.io.Serializable;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Component
public class BaseDaoImp {
@PersistenceContext
private EntityManager entityManager;
public void save(Object obj) {
entityManager.persist(obj);
}
public <T, ID extends Serializable> void delete(Class<T> cls, ID id) {
T t = entityManager.find(cls, id);
entityManager.remove(t);
}
public <T> T update(T obj) {
return entityManager.merge(obj);
}
public <T, ID extends Serializable> T findOne(Class<T> cls, ID id) {
return entityManager.find(cls, id);
}
@Transactional(readOnly = true)
public Object getObjectBySQL(final String sql, final ResultTransformer rt) {
Object obj = null;
try {
Query query = entityManager.createNativeQuery(sql);
if (rt != null) {
query.unwrap(NativeQueryImpl.class).setResultTransformer(rt);
}
List list = query.getResultList();
if (null != list && list.size() > 0) {
obj = list.get(0);
}
} catch (Exception e) {
e.printStackTrace();
}
return obj;
}
@Transactional(readOnly = true)
public List getListBySQL(String sql, ResultTransformer rt) {
Query query = entityManager.createNativeQuery(sql);
if (rt != null) {
query.unwrap(NativeQueryImpl.class).setResultTransformer(rt);
}
List list = query.getResultList();
return list;
}
@Transactional(readOnly = true)
public List<Map> getListBySQL(String sql) {
Query query = entityManager.createNativeQuery(sql);
query.unwrap(NativeQueryImpl.class).setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
List<Map> list = query.getResultList();
return list;
}
public List findBySQL(String sql) {
Query query = entityManager.createNativeQuery(sql);
List list = query.getResultList();
return list;
}
public Integer getNumBySQL(String sql) {
Integer num = 0;
Query query = entityManager.createNativeQuery(sql);
Object obj = query.getSingleResult();
num = Integer.valueOf(obj.toString());
return num;
}
public String getStringBySQL(String sql) {
Query query = entityManager.createNativeQuery(sql);
Object obj = query.getSingleResult();
return obj.toString();
}
public Integer executeBySQL(String sql) {
Query query = entityManager.createNativeQuery(sql);
final int i = query.executeUpdate();
return i;
}
public void batchSave(List list) {
for (int i = 0; i < 10000 && i < list.size(); i++) {
entityManager.persist(list.get(i));
if (i % 1000 == 0) {
entityManager.flush();
entityManager.clear();
}
}
}
public void batchUpdate(List list) {
for (int i = 0; i < list.size(); i++) {
entityManager.merge(list.get(i));
if (i % 100 == 0) {
entityManager.flush();
entityManager.clear();
}
}
}
public void insert(Object obj) {
entityManager.persist(obj);
}
@Transactional(readOnly = true)
public List<Map> getBySQL(String sql) {
Query nativeQuery = entityManager.createNativeQuery(sql);
nativeQuery.unwrap(NativeQueryImpl.class).setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
List resultList = nativeQuery.getResultList();
return resultList;
}
public Map uniqueResult(String sql) {
Map re = new HashMap();
List<Map> listMap = getBySQL(sql);
if (null != listMap && listMap.size() > 0) {
re = listMap.get(0);
}
return re;
}
4、Service
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.util.List;
import java.util.Map;
public class BaseServiceImp<T extends Object, ID extends Serializable> {
@Autowired
private BaseDaoImp baseDaoImp;
@Transactional
public void save(T t) {
baseDaoImp.save(t);
}
@Transactional
public void delete(ID id) {
Class<T> tClass = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
baseDaoImp.delete(tClass, id);
}
@Transactional
public void deleteByIds(String ids) {
String strIdArr[] = ids.split(",");
for (String idStr : strIdArr) {
ID id = (ID) idStr;
delete(id);
}
}
@Transactional
public T update(T t) {
return baseDaoImp.update(t);
}
@Transactional
public void batchSave(List list) {
baseDaoImp.batchSave(list);
}
@Transactional
public void batchUpdate(List list) {
baseDaoImp.batchUpdate(list);
}
@Transactional
public Integer executeBySQL(String sql) {
return baseDaoImp.executeBySQL(sql);
}
@Transactional
public T findOne(ID id) {
Class<T> tClass = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
return baseDaoImp.findOne(tClass, id);
}
@Transactional
public void insert(Object obj) {
baseDaoImp.insert(obj);
}
public QueryResultVO queryBySql(String querySql, Class cls) {
int lastIndex = querySql.length();
if (querySql.toLowerCase().indexOf("order by") != -1) {
lastIndex = querySql.toLowerCase().indexOf("order by");
}
String countSql = "select count(*) " + querySql.substring(querySql.toLowerCase().indexOf("from"), lastIndex);
QueryResultVO queryResultVO = new QueryResultVO();
List list = baseDaoImp.getListBySQL(querySql, new SqlResultTransformer(cls));
int count = baseDaoImp.getNumBySQL(countSql);
queryResultVO.setResultList(list);
queryResultVO.setTotalRecords(count);
return queryResultVO;
}
public List getListBySQL(String sql, Class cls) {
return baseDaoImp.getListBySQL(sql, new SqlResultTransformer(cls));
}
public List<Map> getListBySQL(String sql) {
return baseDaoImp.getListBySQL(sql);
}
public Integer getNumBySQL(String sql) {
return baseDaoImp.getNumBySQL(sql);
}
public Object getObjectBySQL(String sql, Class cls) {
return baseDaoImp.getObjectBySQL(sql, new SqlResultTransformer(cls));
}
public <E> E getObjectBySQL(String sql, E e) {
return (E) baseDaoImp.getObjectBySQL(sql, new SqlResultTransformer(e.getClass()));
}
5、使用
@Service
public class ServiceImpl extends BaseServiceImp implements Service
public List<TableDTO> getTableDTOList(VO vo) {
String sql = "SELECT * FROM table ";
sql += this.getWhereSql(vo);
sql += "GROUP BY field";
List<TableDTO> list = this.getListBySQL(sql, TableDTO.class);
return list ;
}
}
@Service
public class ServiceImpl extends BaseServiceImp<MO, Integer> {
@Transactional
public void addMo(MO mo){
this.save(mo);
}
}
import lombok.Data;
import javax.persistence.*;
@Data
@Entity
@Table(name = "table_name")
public class MO {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
}