通用jdbc插入参数设置类InsertSetter

这边文章介绍了一个jdbc中通用的插入值映射工具。

代码

/**
 * 
 */
package com.cmc.tools.jdbc;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.springframework.jdbc.core.BatchPreparedStatementSetter;

import com.google.common.collect.Maps;

/**
 * @desc 通用抽象参数设置器
 * <p>可以将model里的参数设置到预编译SQL中去</>
 * @author cmc
 * @email chenmingchuan@all-in-data.com
 * @date 2019年8月21日 上午9:37:50
 */
public class AdbCommonInsertSetter<T> implements BatchPreparedStatementSetter{
	
	private  List<T> list ; //要插入的数据
	
	private Map<String, String> replaceMap ; //需要改名的字段map
	
	private String [] excludes ; //需要排除的字段
	
	public AdbCommonInsertSetter(List<T> list) {
		this.list=list;
	}
	
	public AdbCommonInsertSetter(List<T> list, String... excludes) {
		this.list=list;
		this.excludes=excludes;
	}
	
	public AdbCommonInsertSetter(List<T> list, Map<String, String> replaceMap) {
		this.list = list;
		this.replaceMap = replaceMap;
	}

	public AdbCommonInsertSetter(List<T> list, Map<String, String> replaceMap, String... excludes) {
		this.list = list;
		this.replaceMap = replaceMap;
		this.excludes = excludes;
	}
	
	@Override
	public void setValues(PreparedStatement ps, int i) throws SQLException {
		T model = list.get(i) ;
		Map<String,String> paramMap = getParamMap(model, excludes) ;
		int index = 1 ;
		for(String name : paramMap.keySet()) {
			String type = paramMap.get(name) ;
			switch(type) {
				case "java.lang.String" : {
					ps.setString(index, getParamValue(name, model) == null ? null : getParamValue(name, model));
				}break ;
				case "byte" : {
					ps.setByte(index, getParamValue(name, model) == null ? null : Byte.parseByte(getParamValue(name, model)));
				}break ;
				case "short" : {
					ps.setShort(index, getParamValue(name, model) == null ? null : Short.parseShort(getParamValue(name, model)));
				}break ;
				case "int" : {
					ps.setInt(index, getParamValue(name, model) == null ? null : Integer.parseInt(getParamValue(name, model)));
				}break ;
				case "long" : {
					ps.setLong(index, getParamValue(name, model) == null ? null : Long.parseLong(getParamValue(name, model)));
				}break ;
				case "float" : {
					ps.setFloat(index, getParamValue(name, model) == null ? null : Float.parseFloat(getParamValue(name, model)));
				}break ;
				case "double" : {
					ps.setDouble(index, getParamValue(name, model) == null ? null : Double.parseDouble(getParamValue(name, model)));
				}break ;
				case "char" : {
					ps.setString(index, getParamValue(name, model) == null ? null : getParamValue(name, model));
				}break ;
				case "boolean" : {
					ps.setBoolean(index,  getParamValue(name, model) == null ? null : Boolean.parseBoolean(getParamValue(name, model)));
				}break ;
				case "java.time.LocalDateTime" : {
					ps.setTimestamp(index, getParamValue(name, model) == null ? null : Timestamp.valueOf(LocalDateTime.parse(getParamValue(name, model))));
				}break ;
				case "java.time.LocalDate" : {
					ps.setTimestamp(index,  getParamValue(name, model) == null ? null : Timestamp.valueOf(LocalDate.parse(getParamValue(name, model)).atStartOfDay()));
				}break ;
				//其他类型一律按String处理
				default : {
					ps.setString(index, getParamValue(name, model) == null ? null : getParamValue(name, model));
				}
			}
			index ++ ;
		}
		
	}

	/**
	 * <p>功能: 反射获取所有参数类型和参数名(参数类型-参数名)</p>
	 * @param model 要传入数据的模型 <br>
	 * @param exclude 需要排除的字段 <br>
	 * <i>有一些字段模型里边有但是数据库里没有(例如发票里的rechargeTradeId字段),可以使用这个参数把这些参数排除</i>
	 * @return
	 */
	private Map<String , String> getParamMap(T model, String [] excludes) {
		Map<String, String> map = Maps.newHashMap() ;
		Field[] fields = model.getClass().getDeclaredFields() ;
		for(Field field : fields) {
			String name = field.getName() ;
			//判断是否跳过该字段
			if(excludes != null && isExclude(excludes, name)) {
				continue ;
			}
			//若map中有替换的参数名,则替换
			if(replaceMap != null && replaceMap.get(name) != null) {
				map.put(replaceMap.get(name), field.getGenericType().getTypeName()) ;
			}else {
				map.put(name, field.getGenericType().getTypeName()) ;
			}
		}
		//方法名按首字母排序
		Map<String, String> sortedMap = Maps.newLinkedHashMap() ;
		map.entrySet()
		   .stream()
		   .sorted(Map.Entry.<String,String>comparingByKey())
		   .forEachOrdered(e -> sortedMap.put(e.getKey(), e.getValue()));
		return sortedMap ;
	}
	
	/**
	 * <p>功能: 根据参数名获取参数值</p>
	 * @param fieldName 要获取的参数名
	 * @param model 要获取参数值的运行时模型
	 * @return
	 */
	private String getParamValue(String fieldName, T model) {
		String value = null ;
		//如果之前有替换参数名,取值的时候需要把参数名替换回去,否则取不到数
		fieldName = getOriginalName(fieldName) ;
		try {
			Field field = model.getClass().getDeclaredField(fieldName) ;
			String methodName = "" ;
			//特殊处理boolean类型
			if(field.getType().getName().equals("boolean")) {
				methodName = "is" + Character.toUpperCase(fieldName.charAt(0)) + fieldName.substring(1) ;
			}else {
				methodName = "get" + Character.toUpperCase(fieldName.charAt(0)) + fieldName.substring(1) ;
			}
			Method method = model.getClass().getMethod(methodName) ;
			value = method.invoke(model) == null ? null : method.invoke(model).toString() ;
		} catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException | NoSuchFieldException e) {
			e.printStackTrace();
		}
		return value ;
	}
	
	/**
	 * <p>功能: 判断是否排除该字段</p>
	 * @param excludes
	 * @param name
	 * @return
	 */
	private static boolean isExclude(String[] excludes, String name) {
		for(String exclude : excludes) {
			if(name.equals(exclude))
				return true ;
		}
		return false;
	}

	@Override
	public int getBatchSize() {
		return list.size();
	}
	
	/**
	 * <p>功能: 获取替换之前原始参数名 </p>
	 * @param name 替换后参数名
	 * @return 替换之前参数名
	 */
	public String getOriginalName(String name) {
		if(replaceMap == null)
			return name ;
		for(Entry<String, String> entry : replaceMap.entrySet()) {
			if(entry.getValue().equals(name)) {
				name = entry.getKey() ;
				return name ;
			}
		}
		return name ;
	}
	
}
 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值