日期:2014-05-16  浏览次数:20539 次

SpringJdbcTemplate操作Clob和Blob的通用类封装

? ? ? ? 项目中使用SpringJdbcTemplate来操作数据库,简单方便实用(根据项目需求选择技术),目前用到Oracle10g数据库,由于其操作大文本使用Clob类型,故而研究了下jdbctemplate对clob和Blob的操作。 ?

? ? ? ?jdbctemplate对clob和blob的操作使用起来也很简单,网友提供很多实例和代码。例如:

http://hi.baidu.com/sileader/item/0b3335f512378fb731c19999

主要是利用jdbctemplate提供的两个类来操作:LobCreator和LobHandler,具体使用方法可参考该链接。

但是如果某个Bean属性字段太多的话,代码写起来将会很麻烦。是否可以提供一种通用的方法,让每个业务方法操作数据库Clob和Blob时候也可以像操作其他基本数据类型一样,一句代码就完成。例如插入和修改Bean:

public <T> void saveOrUpdate(String sql, T bean) {
	namedParameterJdbcTemplate.update(sql, new BeanPropertySqlParameterSource(bean));
}

?经过一些尝试和摸索,我使用反射和注解,写了一个通用类,可以操作查询、修改、添加,满足了项目中的需求。

1、定义了一个注解类,用于bean中属性上,主要是提供属性的数据库字段名以及其数据库类型。

/**
 * @description 
 * @author aokunsang
 * @date 2013-7-4
 */
@Target({ElementType.FIELD,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME) 
@Documented
@Inherited
public @interface PmcColumn {
	/**
	 * 数据库中字段类型
	 * @return
	 */
	int type();
	/**
	 * 数据库中字段名
	 * @return
	 */
	String columnName();
	/**
	 * 查询时候是否忽略
	 * @return
	 */
	boolean ignore() default false;
}

?2、定义一个反射的工具类,反射操作属性字段的setter和getter方法注入和获取属性值、

/**
 * @description 对bean的反射操作
 * @author aokunsang
 * @date 2013-7-3
 */
public class BeanUtils {

	  /** 
     * @param obj 操作的对象 
     * @param att 操作的属性 
     * */
	public static Object getter(Object obj, String att) { 
        try { 
            Method method = obj.getClass().getMethod("get" + StringUtils.capitalize(att)); 
            return method.invoke(obj); 
        } catch (Exception e) { 
            e.printStackTrace(); 
        }
		return null; 
    }
    /**
     * 注入数据
     * @param obj   类的实例
     * @param att   属性名
     * @param value 注入数据内容
     * @param type  返回的数据类型
     * 
     */
	public static void setter(Object obj, String att, Object value, Class<?> type) { 
        try { 
            Method method = obj.getClass().getMethod("set" + StringUtils.capitalize(att), type); 
            method.invoke(obj, value); 
        } catch (Exception e) { 
            e.printStackTrace(); 
        }
    }
	
	/**
	 * 获取某个属性字段的ignore信息
	 * @param field
	 * @return
	 */
	public static boolean getPmcColumnIgnore(Field field){
		Annotation annotation = field.getAnnotation(PmcColumn.class);
		boolean ignore = false;
		if(annotation!=null){
			ignore = ((PmcColumn)annotation).ignore();
		}
		return ignore;
	}
	
	/**
	 * 获取某个属性的Type信息
	 * @param field
	 * @return
	 */
	public static int getPmcColumnType(Field field){
		Annotation annotation = field.getAnnotation(PmcColumn.class);
		int type = Types.VARCHAR;
		if(annotation!=null){
			type = ((PmcColumn)annotation).type();
		}
		return type;
	}
	
	/**
	 * 获取某个属性的数据库中字段名
	 * @param field
	 * @return
	 */
	public static String getPmcColumnName(Field field){
		Annotation annotation = field.getAnnotation(PmcColumn.class);
		String columnName = "";
		if(annotation!=null){
			columnName = ((PmcColumn)annotation).columnName();
		}
		return columnName;
	}
}

?3、定义一个对sql语句的转换类,sql语句进行转变,变成需要的字符串。

如:insert into t1 values(:a,:b,:c) ?----> ? insert into t1(A,B,C) values(?,?,?);

或者update t1 set A=:a,B=:b where C=:c ? ----> update t1 set A=?,B=? where C=?

/**
 * @description 工具类
 * @author aokunsang
 * @date 2013-1-9
 */
public class Util {

	/**
	 * 分割插入、修改的sql语句
	 * @param sql
	 * @param columnMaps   <属性名,数据库中字段名>
	 * @return
	 */
	public static Map<String,List<String>> spQuerysql(String sql,Map<String,String> columnMaps){
		if(StringUtils.isEmpty(sql)) return null;
		String _sql = sql + " ";
		String key = _sql.replaceAll(":(.+?),\\s*", "?,").replaceAll(":(.+?)[)]\\s*", "?)").replaceAll(":(.+?)\\s+", "? ");
		Map<String,List<String>> result = new HashMap<String,