Forráskód Böngészése

提供多种SQL模板技术

zhzhenqin 3 éve
szülő
commit
062f27044f

+ 62 - 45
jpa-sqltemplate/DAOServiceImpl.java

@@ -14,12 +14,15 @@
 package com.primeton.dams.utils.template.impl;
 
 import com.primeton.dams.utils.template.CoreSQLParser;
+import com.primeton.dams.utils.template.DOResultTransformer;
 import com.primeton.dams.utils.template.HibernateStatementSessionFactoryBean;
 import com.primeton.dams.utils.template.IDAOService;
 import com.primeton.dams.utils.template.Page;
+import lombok.NonNull;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang.StringUtils;
 import org.hibernate.SQLQuery;
+import org.hibernate.internal.QueryImpl;
 import org.hibernate.transform.ResultTransformer;
 import org.hibernate.transform.Transformers;
 import org.slf4j.Logger;
@@ -179,8 +182,8 @@ public class DAOServiceImpl implements IDAOService {
     @Override
 	public int execute(String updateSql, Object[] params) {
 		final javax.persistence.Query nativeQuery = entityManager.createNativeQuery(updateSql);
-		for (int i = 0; params != null && i < params.length; i++) {
-			nativeQuery.setParameter(i, params[i]);
+		for (int i=1; params!=null && i<params.length+1; i++) {
+			nativeQuery.setParameter(i, params[i-1]);
 		}
 		return nativeQuery.executeUpdate();
 	}
@@ -216,8 +219,8 @@ public class DAOServiceImpl implements IDAOService {
 	 */
 	@Override
 	public List query(javax.persistence.Query query, Object[] params, ResultTransformer rt, final int firstResult, final int maxResult) {
-		for (int i=0; params!=null && i<params.length; i++) {
-			query.setParameter(i, params[i]);
+		for (int i=1; params!=null && i<params.length+1; i++) {
+			query.setParameter(i, params[i-1]);
 		}
 		query.setMaxResults(maxResult);
 		query.setFirstResult(firstResult);
@@ -233,8 +236,8 @@ public class DAOServiceImpl implements IDAOService {
 
 	@Override
 	public List query(javax.persistence.Query query, Object[] params, ResultTransformer rt) {
-		for (int i=0; params!=null && i<params.length; i++) {
-			query.setParameter(i, params[i]);
+		for (int i=1; params!=null && i<params.length+1; i++) {
+			query.setParameter(i, params[i-1]);
 		}
 		if (rt == null) {
 			query.unwrap(org.hibernate.SQLQuery.class)
@@ -266,10 +269,13 @@ public class DAOServiceImpl implements IDAOService {
 			throw new IllegalArgumentException("undefined statement id: " + id);
 		}
 		final Object[] sqlParams = (params == null ? null : getParam(id, params));
-		final Query nativeQuery = entityClass == null ? entityManager.createNativeQuery(sql) : entityManager.createNativeQuery(sql, entityClass);
+		final Query nativeQuery = entityManager.createNativeQuery(sql);
 		if (entityClass == null) {
 			nativeQuery.unwrap(org.hibernate.SQLQuery.class)
 					.setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
+		} else {
+			nativeQuery.unwrap(org.hibernate.SQLQuery.class)
+					.setResultTransformer(new DOResultTransformer(entityClass));
 		}
 		return query(nativeQuery, sqlParams, entityClass, null, null);
 	}
@@ -290,18 +296,21 @@ public class DAOServiceImpl implements IDAOService {
 			throw new IllegalArgumentException("undefined statement id: " + id);
 		}
 		final Object[] sqlParams = (params == null ? null : getParam(id, params));
-		final Query nativeQuery = entityClass == null ? entityManager.createNativeQuery(sql) : entityManager.createNativeQuery(sql, entityClass);
+		final Query nativeQuery = entityManager.createNativeQuery(sql);
 		if (entityClass == null) {
 			nativeQuery.unwrap(org.hibernate.SQLQuery.class)
 					.setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
+		} else {
+			nativeQuery.unwrap(org.hibernate.SQLQuery.class)
+					.setResultTransformer(new DOResultTransformer(entityClass));
 		}
 		return query(nativeQuery, sqlParams, entityClass, firstResult, maxResult);
 	}
 
 
 	private List query(javax.persistence.Query query, Object[] params, Class entityClass, final Integer firstResult, final Integer maxResult) {
-		for (int i = 0; params != null && i < params.length; i++) {
-			query.setParameter(i, params[i]);
+		for (int i=1; params!=null && i<params.length+1; i++) {
+			query.setParameter(i, params[i-1]);
 		}
 		if (firstResult != null) {
 			query.setFirstResult(firstResult);
@@ -331,8 +340,8 @@ public class DAOServiceImpl implements IDAOService {
 	@Override
 	public List queryForMap(String sql, Object[] params, int firstResult, int maxResult) {
 		final javax.persistence.Query query1 = entityManager.createNativeQuery(sql);
-		for (int i = 0; params != null && i < params.length; i++) {
-			query1.setParameter(i, params[i]);
+		for (int i=1; params!=null && i<params.length+1; i++) {
+			query1.setParameter(i, params[i-1]);
 		}
 
 		query1.setFirstResult(firstResult);
@@ -343,8 +352,8 @@ public class DAOServiceImpl implements IDAOService {
 	}
 	
 	private List queryForEntity(javax.persistence.Query query, Object[] params, Class entityClass) {
-		for (int i = 0; params != null && i < params.length; i++) {
-			query.setParameter(i, params[i]);
+		for (int i=1; params!=null && i<params.length+1; i++) {
+			query.setParameter(i, params[i-1]);
 		}
 		return query.getResultList();
 	}
@@ -352,20 +361,25 @@ public class DAOServiceImpl implements IDAOService {
 	@Override
 	public List queryForEntity(String sql, Class entityClass) {
 		final javax.persistence.Query query1 = entityManager.createQuery(sql, entityClass);
+		query1.unwrap(QueryImpl.class)
+				.setResultTransformer(new DOResultTransformer(entityClass));
 		return query1.getResultList();
 	}
 
 	@Override
 	public List queryForEntity(String sql, Object[] params, Class entityClass) {
-		final javax.persistence.Query query1 = entityManager.createQuery(sql, entityClass);
+		final javax.persistence.Query query1 = entityManager.createQuery(sql);
+		query1.unwrap(QueryImpl.class)
+				.setResultTransformer(new DOResultTransformer(entityClass));
 		return this.queryForEntity(query1, params, entityClass);
 	}
 	
 	@Override
 	public List queryForEntity(String sql, Object[] params,
 							   Class entityClass, int firstResult, int maxResult) {
-		final javax.persistence.Query query1 = entityManager.createQuery(sql, entityClass);
-		SQLQuery query = query1.unwrap(SQLQuery.class);
+		final javax.persistence.Query query1 = entityManager.createQuery(sql);
+		QueryImpl query = query1.unwrap(QueryImpl.class);
+		query.setResultTransformer(new DOResultTransformer(entityClass));
 		query.setMaxResults(maxResult).setFirstResult(firstResult);
 		return this.queryForEntity(query1, params, entityClass);
 	}
@@ -378,11 +392,13 @@ public class DAOServiceImpl implements IDAOService {
 	 * @param <T>
 	 * @return
 	 */
-	public <T> T queryForObject(String sql, Object[] params, Class<T> entityClass) {
-		final javax.persistence.Query query1 = entityManager.createQuery(sql, entityClass);
-		for (int i = 0; params != null && i < params.length; i++) {
-			query1.setParameter(i, params[i]);
+	public <T> T queryForObject(String sql, Object[] params, @NonNull Class<T> entityClass) {
+		final javax.persistence.Query query1 = entityManager.createNativeQuery(sql);
+		for (int i=1; params!=null && i<params.length+1; i++) {
+			query1.setParameter(i, params[i-1]);
 		}
+		query1.unwrap(org.hibernate.SQLQuery.class)
+				.setResultTransformer(new DOResultTransformer(entityClass));
 		try {
 			return (T) query1.getSingleResult();
 		} catch (NoResultException e) {
@@ -395,17 +411,8 @@ public class DAOServiceImpl implements IDAOService {
 	}
 
 	@Override
-	public Long queryForLong(String sql) {
-		return this.queryForLong(sql, null);
-	}
-	
-	@Override
-	public Long queryForLong(String sql, Object[] params) {
-		List list = this.querySQL(sql, params);
-		if (list != null && list.size() > 0 && list.get(0) != null) {
-			return new Long(((Number)list.get(0)).longValue());
-		}
-		return null;
+	public long queryForLong(String sql, Object[] params) {
+		return countSQL(sql, params);
 	}
 
 	@Override
@@ -417,8 +424,8 @@ public class DAOServiceImpl implements IDAOService {
 		final Object[] sqlParams = (params == null ? null : getParam(id, params));
 		SQLQuery query = entityManager.createNativeQuery(sql).unwrap(SQLQuery.class);
 		if (sqlParams != null && sqlParams.length > 0) {
-			for (int i = 0; i < sqlParams.length; i++) {
-				query.setParameter(i, sqlParams[i]);
+			for (int i=1; i<sqlParams.length+1; i++) {
+				query.setParameter(i, sqlParams[i-1]);
 			}
 		}
 		return query.executeUpdate();
@@ -431,8 +438,8 @@ public class DAOServiceImpl implements IDAOService {
 		}
 		SQLQuery query = entityManager.createNativeQuery(sql).unwrap(SQLQuery.class);
 		if (params != null && params.length > 0) {
-			for (int i = 0; i < params.length; i++) {
-				query.setParameter(i, params[i]);
+			for (int i=1; i<params.length+1; i++) {
+				query.setParameter(i, params[i-1]);
 			}
 		}
 		return query.executeUpdate();
@@ -450,8 +457,8 @@ public class DAOServiceImpl implements IDAOService {
 	@Override
 	public List queryPageList(String sql, Object[] params, Page page) {
 		SQLQuery query = entityManager.createNativeQuery(sql).unwrap(SQLQuery.class);
-		for (int i = 0; params != null && i < params.length; i++) {
-			query.setParameter(i, params[i]);
+		for (int i=1; params!=null && i<params.length+1; i++) {
+			query.setParameter(i, params[i-1]);
 		}
 		int totalCount = this.countSQL(sql, params);
 		query.setMaxResults(page.getPageSize());
@@ -473,6 +480,7 @@ public class DAOServiceImpl implements IDAOService {
 		if (totalCount > 0) {
 			final javax.persistence.Query nativeQuery = entityManager.createNativeQuery(sql);
 			SQLQuery query = nativeQuery.unwrap(SQLQuery.class);
+			query.setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
 			query.setMaxResults(page.getPageSize());
 			query.setFirstResult(page.getStartIndex());
 			return this.queryForMap(nativeQuery, params);
@@ -490,15 +498,17 @@ public class DAOServiceImpl implements IDAOService {
 	 * com.primedata.primedatamm.core.common.Page, EntityList)
 	 */
 	@Override
-	public List queryPageEntity(String sql, Object[] params, Page page, Class entityClass) {
+	public List queryPageEntity(String sql, Object[] params, Page page, @NonNull Class entityClass) {
 		int totalCount = this.countSQL(sql, params);
 		List<?> list = new ArrayList();
 		if (totalCount > 0) {
-			final javax.persistence.Query nativeQuery = entityManager.createNativeQuery(sql, entityClass);
+			final javax.persistence.Query nativeQuery = entityManager.createNativeQuery(sql);
 			SQLQuery query = nativeQuery.unwrap(SQLQuery.class);
-			for (int i = 0; params != null && i < params.length; i++) {
-				query.setParameter(i, params[i]);
+			for (int i=1; params!=null && i<params.length+1; i++) {
+				query.setParameter(i, params[i-1]);
 			}
+			nativeQuery.unwrap(org.hibernate.SQLQuery.class)
+						.setResultTransformer(new DOResultTransformer(entityClass));
 			query.setMaxResults(page.getPageSize());
 			query.setFirstResult(page.getStartIndex());
 			return query.list();
@@ -523,9 +533,16 @@ public class DAOServiceImpl implements IDAOService {
 	public int countSQL(String sql, Object[] params) {
     	String strQuery = this.getCountSQL(sql);
 		int count = 0;
-		List<?> list = this.querySQL(strQuery, params);
-		if (list != null && list.get(0) != null) {// 取出count总数
-			count = ((Number)list.get(0)).intValue();
+		final javax.persistence.Query nativeQuery = entityManager.createNativeQuery(strQuery);
+		for (int i=1; params!=null && i<params.length+1; i++) {
+			nativeQuery.setParameter(i, params[i-1]);
+		}
+		if (nativeQuery != null) {
+			// 取出count总数
+			final Object singleResult = nativeQuery.getSingleResult();
+			if(singleResult instanceof Number) {
+				count = ((Number)singleResult).intValue();
+			}
 		}
 		return count;
 	}

+ 147 - 0
jpa-sqltemplate/DOResultTransformer.java

@@ -0,0 +1,147 @@
+package com.primeton.dams.utils.template;
+
+
+import lombok.Getter;
+import lombok.NonNull;
+import lombok.Setter;
+import org.apache.commons.beanutils.BeanUtils;
+import org.apache.commons.lang.StringUtils;
+import org.hibernate.HibernateException;
+import org.hibernate.transform.BasicTransformerAdapter;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.persistence.Column;
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * <pre>
+ *
+ * Created by zhaopx.
+ * User: zhaopx
+ * Date: 2022/3/1
+ * Time: 下午6:35
+ * Vendor: primeton.com
+ *
+ * </pre>
+ *
+ * @author zhaopx
+ */
+public class DOResultTransformer extends BasicTransformerAdapter {
+
+    /**
+     *
+     */
+    private static final long serialVersionUID = 1L;
+    private static Logger logger = LoggerFactory.getLogger(DOResultTransformer.class);
+
+    /**
+     * 驼峰转下划线
+     */
+    private static Pattern HUMP_PATTERN = Pattern.compile("[A-Z]");
+
+    @Getter
+    @Setter
+    class FieldInfo {
+        final String fieldName;
+        final Class<?> fieldType;
+
+        public FieldInfo(String fieldName, Class<?> fieldType) {
+            this.fieldName = fieldName;
+            this.fieldType = fieldType;
+        }
+    }
+
+    private final Class resultClass;
+    private boolean isInitialized;
+    private final Map<String, FieldInfo> aliasFieldMap = new HashMap<>();
+
+    public <T> DOResultTransformer(@NonNull Class<T> resultClass) {
+        this.resultClass = resultClass;
+        isInitialized = false;
+    }
+
+
+    @Override
+    public Object transformTuple(Object tuple[], String aliases[]) {
+        Object result = null;
+        if (!isInitialized) {
+            initialize(aliases);
+        }
+        // 从构造方法进入
+        try {
+            result = resultClass.newInstance();
+            for (int i = 0; i < tuple.length; i++) {
+                final FieldInfo fieldInfo = aliasFieldMap.get(StringUtils.upperCase(aliases[i]));
+                if(fieldInfo == null) {
+                    continue;
+                }
+                BeanUtils.setProperty(result, fieldInfo.getFieldName(), tuple[i]);
+            }
+        } catch (Exception e) {
+            throw new HibernateException((new StringBuilder()).append("Could not instantiate resultclass: ").append(resultClass.getName()).toString());
+        }
+        return result;
+    }
+
+    private void initialize(String aliases[]) {
+        final Field[] declaredFields = resultClass.getDeclaredFields();
+        for (Field declaredField : declaredFields) {
+            // final 和 static 修饰的都不是 bean 字段
+            if(Modifier.isFinal(declaredField.getModifiers()) || Modifier.isStatic(declaredField.getModifiers())) {
+                continue;
+            }
+
+            // 字段名称和类型
+            final String fieldName = declaredField.getName();
+            final Class<?> fieldType = declaredField.getType();
+            // 获取字段上的注解
+            final Column columnAnno = declaredField.getAnnotation(Column.class);
+            if(columnAnno == null || StringUtils.isBlank(columnAnno.name())) {
+                // 无注解
+                aliasFieldMap.put(StringUtils.upperCase(humpToLine(fieldName)), new FieldInfo(fieldName, fieldType));
+            } else {
+                // 有注解, 并且 Column name 不为 null
+                aliasFieldMap.put(StringUtils.upperCase(columnAnno.name()), new FieldInfo(fieldName, fieldType));
+            }
+        }
+        isInitialized = true;
+    }
+
+
+    /**
+     * 驼峰转下划线
+     */
+    public static String humpToLine(String str) {
+        Matcher matcher = HUMP_PATTERN.matcher(str);
+        StringBuffer sb = new StringBuffer();
+        while (matcher.find()) {
+            matcher.appendReplacement(sb, "_" + matcher.group(0).toLowerCase());
+        }
+        matcher.appendTail(sb);
+        return sb.toString();
+    }
+
+
+    public boolean equals(Object o) {
+        if (this == o)
+            return true;
+        if (o == null || getClass() != o.getClass())
+            return false;
+        DOResultTransformer that = (DOResultTransformer) o;
+        if (!resultClass.equals(that.resultClass))
+            return false;
+        return true;
+    }
+
+    public int hashCode() {
+        int result = resultClass.hashCode();
+        result = 31 * result;
+        return result;
+    }
+}

+ 15 - 2
jpa-sqltemplate/IDAOService.java

@@ -187,6 +187,17 @@ public interface IDAOService {
         return query(sql, params, null);
     }
 
+
+    /**
+     * 执行SQL查询
+     * @param sql 脚本
+     * @param params 参数
+     * @return Object[]/Object
+     */
+    default List querySQL(String sql, Object[] params, Class entityClass) {
+        return query(sql, params, null);
+    }
+
     /**
 	 * 执行SQL查询Query
 	 * @param query Query,脚本
@@ -302,7 +313,9 @@ public interface IDAOService {
      * @param sql 脚本
      * @return Long
      */
-    Long queryForLong(String sql);
+    default Long queryForLong(String sql) {
+        return this.queryForLong(sql, null);
+    }
     
     /**
      * 查询整数值
@@ -310,7 +323,7 @@ public interface IDAOService {
      * @param params 参数
      * @return Long
      */
-    Long queryForLong(String sql, Object[] params);
+    long queryForLong(String sql, Object[] params);
 
     /**
      * 执行SQL更新、删除

+ 271 - 0
springjdbc-sql-template/DAOService.java

@@ -0,0 +1,271 @@
+package com.primeton.filetransfer.server.template;
+
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang.StringUtils;
+import org.springframework.jdbc.core.ColumnMapRowMapper;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.jdbc.core.RowCallbackHandler;
+
+import javax.validation.constraints.NotNull;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+
+/**
+ * 为了升级元数据,兼容 hibernate 的 API
+ *
+ * <pre>
+ *
+ * Created by zhaopx.
+ * User: zhaopx
+ * Date: 2020/6/3
+ * Time: 11:12
+ *
+ * </pre>
+ *
+ * @author zhaopx
+ */
+@Slf4j
+public class DAOService {
+
+
+    /**
+     * 构造方法传入
+     */
+    private final JdbcTemplate jdbcTemplate;
+
+
+    public DAOService(JdbcTemplate jdbcTemplate) {
+        this.jdbcTemplate = jdbcTemplate;
+    }
+
+    /** Get HQL from xxxSql.xml file*/
+    public String getSQL(String name) {
+        return HibernateStatementSessionFactoryBean.getStatementText(name);
+    }
+
+    /** Get dynamic HQL from xxxSql.xml file, voOrMap is a VO or a map.*/
+    public String getSQL(String name, Object voOrMap) {
+        return HibernateStatementSessionFactoryBean.getStatementText(name, voOrMap);
+    }
+
+    /** Get dynamic Params from xxxSql.xml file, voOrMap is a VO or a map.*/
+    public Object[] getParam(String name, Object voOrMap) {
+        return HibernateStatementSessionFactoryBean.getStatementParam(name, voOrMap);
+    }
+
+    /** Get dynamic Params from xxxSql.xml file, voOrMap is a VO or a map.*/
+    public Map getMapParam(String name, Object voOrMap) {
+        return HibernateStatementSessionFactoryBean.getStatementParamMap(name, voOrMap);
+    }
+
+
+    /**
+     * 执行查询 SQL 无参数
+     *
+     * @param sql
+     * @return
+     */
+    public List<Map> queryForMap(String sql) {
+        return queryForMap(sql, new String[]{});
+    }
+
+    /**
+     * 执行一次查询
+     *
+     * @param sql
+     * @param params
+     * @return
+     */
+    public List<Map> queryForMap(String sql, Object[] params) {
+        params = Optional.ofNullable(params).orElse(new Object[]{});
+        return (List) jdbcTemplate.query(sql, new ColumnMapRowMapper(), params);
+    }
+
+
+    /**
+     * 执行一次查询
+     * @param sql
+     * @param entityClass
+     * @param <T>
+     * @return
+     */
+    public <T> T queryForObject(String sql, Class<T> entityClass) {
+        return queryForObject(sql, null, entityClass);
+    }
+
+    /**
+     * 执行一次查询
+     *
+     * @param sql
+     * @param params
+     * @param entityClass
+     * @return
+     */
+    public <T> T queryForObject(String sql, Object[] params, Class<T> entityClass) {
+        params = Optional.ofNullable(params).orElse(new Object[]{});
+        final ResultTransformer resultTransformer = (entityClass == null || entityClass == Map.class) ? new MapResultTransformer() : new DOResultTransformer(entityClass);
+        EntityRowCallbackHandler<T> rowCallbackHandler = new EntityRowCallbackHandler(resultTransformer);
+        jdbcTemplate.query(sql, params, rowCallbackHandler);
+        final List<T> result = rowCallbackHandler.getResult();
+        return result.isEmpty() ? null : result.get(0);
+    }
+
+
+    /**
+     * 执行SQL查询
+     * @param id statement id
+     * @return Object[]/Object
+     */
+    public List<Map<String, Object>> queryById(String id) {
+        return queryById(id, null, null);
+    }
+
+    /**
+     * 执行SQL查询
+     * @param id statement id
+     * @return Object[]/Object
+     */
+    public <T> List<T> queryById(String id, Class<T> entityClass) {
+        return queryById(id, null, entityClass);
+    }
+
+
+    /**
+     * 执行SQL查询
+     * @param id 脚本
+     * @param params 参数
+     * @return Object[]/Object
+     */
+    public List<Map<String, Object>> queryById(String id, Map<String, Object> params){
+        return queryById(id, params, null);
+    }
+
+
+    /**
+     * 执行 statement id 的查询,返回  ResultTransformer 的转换结果
+     * @param id statement id
+     * @param params 参数
+     * @param entityClass 结果转换
+     * @return 返回 ResultTransformer 的转换结果
+     */
+    public <T> List<T> queryById(String id, Map<String, Object> params, Class<T> entityClass) {
+        final String sql = getSQL(id);
+        if (StringUtils.isBlank(sql)) {
+            throw new IllegalArgumentException("undefined statement id: " + id);
+        }
+        Object[] sqlParams = (params == null ? null : getParam(id, params));
+        sqlParams = Optional.ofNullable(sqlParams).orElse(new Object[]{});
+        final ResultTransformer resultTransformer = (entityClass == null || entityClass == Map.class) ? new MapResultTransformer() : new DOResultTransformer(entityClass);
+        EntityRowCallbackHandler<T> rowCallbackHandler = new EntityRowCallbackHandler(resultTransformer);
+        jdbcTemplate.query(sql, sqlParams, rowCallbackHandler);
+        return rowCallbackHandler.getResult();
+    }
+
+    /**
+     * 执行一个 更新 SQL
+     *
+     * @param sql
+     * @return
+     */
+    public int updateSQL(String sql) {
+        return updateSQL(sql, new String[]{});
+    }
+
+
+    /**
+     * 执行一个 更新 SQL
+     *
+     * @param sql
+     * @param params
+     * @return
+     */
+    public int updateSQL(String sql, Object[] params) {
+        params = Optional.ofNullable(params).orElse(new Object[]{});
+        return jdbcTemplate.update(sql, params);
+    }
+
+    /**
+     * 执行一个 更新 SQL
+     *
+     * @param id
+     * @return
+     */
+    public int updateById(String id) {
+        return updateSQL(getSQL(id), new Object[]{});
+    }
+
+
+    /**
+     * 执行一个 更新 SQL
+     *
+     * @param id
+     * @param params
+     * @return
+     */
+    public int updateById(String id, Map<String, Object> params) {
+        return updateSQL(getSQL(id, params), getParam(id, params));
+    }
+
+
+    /**
+     * 批量执行 SQL
+     *
+     * @param batchSql
+     * @return
+     */
+    public int[] batchUpdateSQL(String... batchSql) throws SQLException {
+        if (batchSql.length == 0) {
+            return new int[]{};
+        }
+
+        return jdbcTemplate.batchUpdate(batchSql);
+    }
+
+    class EntityRowCallbackHandler<T> implements RowCallbackHandler {
+
+        private final ResultTransformer<T> resultTransformer;
+
+        /**
+         * 结果集
+         */
+        private final List<T> result = new LinkedList<>();
+
+        public EntityRowCallbackHandler(ResultTransformer<T> resultTransformer) {
+            this.resultTransformer = resultTransformer;
+        }
+
+        @Override
+        public void processRow(ResultSet rs) throws SQLException {
+            final int columnCount = rs.getMetaData().getColumnCount();
+            // 返回的字段名字
+            List<String> columnNames = new ArrayList<>(columnCount);
+            for (int i = 1; i <= columnCount; i++) {
+                // 转为大写
+                columnNames.add(StringUtils.upperCase(rs.getMetaData().getColumnName(i)));
+            }
+
+            // 字段列表
+            String[] aliass = columnNames.toArray(new String[0]);
+            // 循环遍历获取值
+            while (rs.next()) {
+                List<Object> tuple = new ArrayList<>(columnCount);
+                for (String columnName : columnNames) {
+                    tuple.add(rs.getObject(columnName));
+                }
+                result.add(resultTransformer.transformTuple(tuple.toArray(new Object[0]), aliass));
+            }
+        }
+
+
+        @NotNull
+        public List<T> getResult() {
+            return result;
+        }
+    }
+
+}

+ 149 - 0
springjdbc-sql-template/DOResultTransformer.java

@@ -0,0 +1,149 @@
+package com.primeton.filetransfer.server.template;
+
+
+import lombok.Getter;
+import lombok.NonNull;
+import lombok.Setter;
+import org.apache.commons.beanutils.BeanUtils;
+import org.apache.commons.lang.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.persistence.Column;
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+import java.sql.SQLException;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ *
+ * JDBC ResultSet 转 Entity Object 快捷方法
+ *
+ * <pre>
+ *
+ * Created by zhaopx.
+ * User: zhaopx
+ * Date: 2022/3/1
+ * Time: 下午6:35
+ * Vendor: primeton.com
+ *
+ * </pre>
+ *
+ * @author zhaopx
+ */
+public class DOResultTransformer<T> implements ResultTransformer<T> {
+
+    /**
+     *
+     */
+    private static final long serialVersionUID = 1L;
+    private static Logger logger = LoggerFactory.getLogger(DOResultTransformer.class);
+
+    /**
+     * 驼峰转下划线
+     */
+    private static Pattern HUMP_PATTERN = Pattern.compile("[A-Z]");
+
+    @Getter
+    @Setter
+    class FieldInfo {
+        final String fieldName;
+        final Class<?> fieldType;
+
+        public FieldInfo(String fieldName, Class<?> fieldType) {
+            this.fieldName = fieldName;
+            this.fieldType = fieldType;
+        }
+    }
+
+    private final Class resultClass;
+    private boolean isInitialized;
+    private final Map<String, FieldInfo> aliasFieldMap = new HashMap<>();
+
+    public DOResultTransformer(@NonNull Class<T> resultClass) {
+        this.resultClass = resultClass;
+        isInitialized = false;
+    }
+
+
+    public T transformTuple(Object tuple[], String aliases[]) throws SQLException {
+        Object result = null;
+        if (!isInitialized) {
+            initialize(aliases);
+        }
+        // 从构造方法进入
+        try {
+            result = resultClass.newInstance();
+            for (int i = 0; i < tuple.length; i++) {
+                final FieldInfo fieldInfo = aliasFieldMap.get(StringUtils.upperCase(aliases[i]));
+                if(fieldInfo == null) {
+                    continue;
+                }
+                BeanUtils.setProperty(result, fieldInfo.getFieldName(), tuple[i]);
+            }
+        } catch (Exception e) {
+            String reason = new StringBuilder().append("Could not instantiate resultclass: ").append(resultClass.getName()).toString();
+            throw new SQLException(reason);
+        }
+        return (T)result;
+    }
+
+    private void initialize(String aliases[]) {
+        final Field[] declaredFields = resultClass.getDeclaredFields();
+        for (Field declaredField : declaredFields) {
+            // final 和 static 修饰的都不是 bean 字段
+            if(Modifier.isFinal(declaredField.getModifiers()) || Modifier.isStatic(declaredField.getModifiers())) {
+                continue;
+            }
+
+            // 字段名称和类型
+            final String fieldName = declaredField.getName();
+            final Class<?> fieldType = declaredField.getType();
+            // 获取字段上的注解
+            final Column columnAnno = declaredField.getAnnotation(Column.class);
+            if(columnAnno == null || StringUtils.isBlank(columnAnno.name())) {
+                // 无注解
+                aliasFieldMap.put(StringUtils.upperCase(humpToLine(fieldName)), new FieldInfo(fieldName, fieldType));
+            } else {
+                // 有注解, 并且 Column name 不为 null
+                aliasFieldMap.put(StringUtils.upperCase(columnAnno.name()), new FieldInfo(fieldName, fieldType));
+            }
+        }
+        isInitialized = true;
+    }
+
+
+    /**
+     * 驼峰转下划线
+     */
+    public static String humpToLine(String str) {
+        Matcher matcher = HUMP_PATTERN.matcher(str);
+        StringBuffer sb = new StringBuffer();
+        while (matcher.find()) {
+            matcher.appendReplacement(sb, "_" + matcher.group(0).toLowerCase());
+        }
+        matcher.appendTail(sb);
+        return sb.toString();
+    }
+
+
+    public boolean equals(Object o) {
+        if (this == o)
+            return true;
+        if (o == null || getClass() != o.getClass())
+            return false;
+        DOResultTransformer that = (DOResultTransformer) o;
+        if (!resultClass.equals(that.resultClass))
+            return false;
+        return true;
+    }
+
+    public int hashCode() {
+        int result = resultClass.hashCode();
+        result = 31 * result;
+        return result;
+    }
+}

+ 36 - 0
springjdbc-sql-template/MapResultTransformer.java

@@ -0,0 +1,36 @@
+package com.primeton.filetransfer.server.template;
+
+import java.sql.SQLException;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ *
+ * JDBC ResultSet 转 Map Object 快捷方法
+ *
+ * <pre>
+ *
+ * Created by zhaopx.
+ * User: zhaopx
+ * Date: 2022/3/7
+ * Time: 下午4:04
+ * Vendor: primeton.com
+ *
+ * </pre>
+ *
+ * @author zhaopx
+ */
+public class MapResultTransformer implements ResultTransformer<Map<String, Object>> {
+
+    @Override
+    public Map<String, Object> transformTuple(Object[] tuple, String[] aliases) {
+        Map<String, Object> result = new HashMap(tuple.length);
+        for ( int i=0; i<tuple.length; i++ ) {
+            String alias = aliases[i];
+            if ( alias!=null ) {
+                result.put( alias, tuple[i] );
+            }
+        }
+        return result;
+    }
+}

+ 32 - 0
springjdbc-sql-template/ResultTransformer.java

@@ -0,0 +1,32 @@
+package com.primeton.filetransfer.server.template;
+
+import java.sql.SQLException;
+
+/**
+ *
+ * JDBC ResultSet 转 Entity Object 快捷方法
+ *
+ * <pre>
+ *
+ * Created by zhaopx.
+ * User: zhaopx
+ * Date: 2022/3/7
+ * Time: 下午4:02
+ * Vendor: primeton.com
+ *
+ * </pre>
+ *
+ * @author zhaopx
+ */
+public interface ResultTransformer<T> {
+
+
+    /**
+     * 转换
+     * @param tuple
+     * @param aliases
+     * @return
+     * @throws SQLException
+     */
+    public T transformTuple(Object tuple[], String aliases[]) throws SQLException;
+}

+ 23 - 7
sql-template-file/HibernateStatementSessionFactoryBean.java

@@ -32,16 +32,17 @@ public class HibernateStatementSessionFactoryBean implements Serializable {
 	private static final String PREFIX = "META-INF/sqlxml/"; // 加载模块的SQL文件的路径前缀
 	private static final String ENDFIX = "*Sql.xml"; // 文件名的扩展后缀名
 
+	final DatabaseRecognizer databaseRecognizer;
 	private HibernateStatementSessionFactoryBean parent;
 	private static HibernateStatementSessionFactoryBean instance;
 	private Map<String, List<HibernateStatementField>> statements;
 	private boolean ready = false;
 	private Resource[] statementLocations;
 	private boolean merge = false;
-	private static Logger log = LoggerFactory.getLogger(HibernateStatementSessionFactoryBean.class);
-	
-	public HibernateStatementSessionFactoryBean() {
+
+	public HibernateStatementSessionFactoryBean(DatabaseRecognizer databaseRecognizer) {
 		instance = this;
+		this.databaseRecognizer = databaseRecognizer;
 		this.statements = new HashMap();
 	}
 
@@ -63,14 +64,13 @@ public class HibernateStatementSessionFactoryBean implements Serializable {
 
 	private void setStatementResources() {
 		try {
+			//TODO 不同数据库,要区别加载数据文件
 			ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
 			statementLocations = resolver.getResources("classpath*:"
 					.concat(PREFIX)
-					.concat(MetadataWebContext.getInstance().getDatabaseName()
-							.toLowerCase()).concat("/").concat(ENDFIX));
-			System.setProperty("dataBaseName", MetadataWebContext.getInstance().getDatabaseName());
+					.concat(databaseRecognizer.getDbType()).concat("/").concat(ENDFIX));
 		} catch (IOException e) {
-			log.error("加载 NativeSQL 异常。", e);
+			log.error("加载 Native QuerySQL 异常。", e);
 		}
 	}
 
@@ -323,4 +323,20 @@ public class HibernateStatementSessionFactoryBean implements Serializable {
 	public static boolean isStateReady() {
 		return instance.isReady();
 	}
+
+
+	public static void main(String[] args) throws Exception {
+		final DatabaseRecognizer databaseRecognizer = new DatabaseRecognizer();
+		databaseRecognizer.setDbType("mysql");
+		HibernateStatementSessionFactoryBean factoryBean = new HibernateStatementSessionFactoryBean(databaseRecognizer);
+		factoryBean.setStatementResources("");
+		factoryBean.init();
+		final HashMap<Object, Object> vo = new HashMap<>();
+		vo.put("code", "abc");
+		vo.put("parentId", "ttttt");
+		vo.put("num", "ss");
+		vo.put("num2", null);
+		System.out.println(factoryBean.getText("onlyOneEndByCode", vo));
+		System.out.println(Arrays.asList(factoryBean.getParam("onlyOneEndByCode", vo)));
+	}
 }