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

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

举报
开通vip

SpringJdbcTemplate操作Clob和Blob的通用类封装SpringJdbcTemplate操作Clob和Blob的通用类封装项目中使用SpringJdbcTemplate来操作数据库,简单方便实用(根据项目需求选择技术),目前用到Oracle10g数据库,由于其操作大文本使用Clob类型,故而研究了下jdbctemplate对clob和Blob的操作。jdbctemplate对clob和blob的操作使用起来也很简单,网友提供很多实例和代码。例如:HYPERLINK"http://hi.baidu.com/sileader/item/0b3335f512378fb7...

SpringJdbcTemplate操作Clob和Blob的通用类封装
SpringJdbcTemplate操作Clob和Blob的通用类封装项目中使用SpringJdbcTemplate来操作数据库,简单方便实用(根据项目需求选择技术),目前用到Oracle10g数据库,由于其操作大文本使用Clob类型,故而研究了下jdbctemplate对clob和Blob的操作。jdbctemplate对clob和blob的操作使用起来也很简单,网友提供很多实例和代码。例如:HYPERLINK"http://hi.baidu.com/sileader/item/0b3335f512378fb731c19999"http://hi.baidu.com/sileader/item/0b3335f512378fb731c19999主要是利用jdbctemplate提供的两个类来操作:LobCreator和LobHandler,具体使用方法可参考该链接。但是如果某个Bean属性字段太多的话,代码写起来将会很麻烦。是否可以提供一种通用的方法,让每个业务方法操作数据库Clob和Blob时候也可以像操作其他基本数据类型一样,一句代码就完成。例如插入和修改Bean:Java代码public<T>voidsaveOrUpdate(Stringsql,Tbean){namedParameterJdbcTemplate.update(sql,newBeanPropertySqlParameterSource(bean));}经过一些尝试和摸索,我使用反射和注解,写了一个通用类,可以操作查询、修改、添加,满足了项目中的需求。1、定义了一个注解类,用于bean中属性上,主要是提供属性的数据库字段名以及其数据库类型。Java代码/***@description*@authoraokunsang*@date2013-7-4*/@Target({ElementType.FIELD,ElementType.METHOD})@Retention(RetentionPolicy.RUNTIME)@Documented@Inheritedpublic@interfacePmcColumn{/**数据库中字段类型*@return*/inttype();/***数据库中字段名*@return*/StringcolumnName();/***查询时候是否忽略*@return*/booleanignore()defaultfalse;}2、定义一个反射的工具类,反射操作属性字段的setter和getter方法注入和获取属性值、Java代码/***@description对bean的反射操作*@authoraokunsang*@date2013-7-3*/publicclassBeanUtils{/***@paramobj操作的对象@paramatt操作的属性**/publicstaticObjectgetter(Objectobj,Stringatt){try{Methodmethod=obj.getClass().getMethod("get"+StringUtils.capitalize(att));returnmethod.invoke(obj);}catch(Exceptione){e.printStackTrace();}returnnull;}/***注入数据*@paramobj类的实例*@paramatt属性名*@paramvalue注入数据内容*@paramtype返回的数据类型**/publicstaticvoidsetter(Objectobj,Stringatt,Objectvalue,Class<?>type){try{Methodmethod=obj.getClass().getMethod("set"+StringUtils.capitalize(att),type);method.invoke(obj,value);}catch(Exceptione){e.printStackTrace();}}/***获取某个属性字段的ignore信息*@paramfield*@return*/publicstaticbooleangetPmcColumnIgnore(Fieldfield){Annotationannotation=field.getAnnotation(PmcColumn.class);booleanignore=false;inttype=if(annotation!=null){ignore=((PmcColumn)annotation).ignore();}returnignore;}/***获取某个属性的Type信息*@paramfield*@return*/publicstaticintgetPmcColumnType(Fieldfield){Annotationannotation=field.getAnnotation(PmcColumn.class);Types.VARCHAR;if(annotation!=null){type=((PmcColumn)annotation).type();}returntype;}/***获取某个属性的数据库中字段名*@paramfield*@return*/publicstaticStringgetPmcColumnName(Fieldfield){Annotationannotation=field.getAnnotation(PmcColumn.class);StringcolumnName="";if(annotation!=null){columnName=((PmcColumn)annotation).columnName();}returncolumnName;}}3、定义一个对sql语句的转换类,sql语句进行转变,变成需要的字符串。如:insertintot1values(:a,:b,:c)>insertintot1(A,B,C)values(?,?,?);或者updatet1setA=:a,B=:bwhereC=:c>updatet1setA=?,B=?whereC=?Java代码/***@description工具类*@authoraokunsang*@date2013-1-9*/publicclassUtil{/***分割插入、修改的sql语句*@paramsql@paramcolumnMaps<属性名,数据库中字段名>@return*/publicstaticMap<String,List<String>>spQuerysql(Stringsql,Map<String,String>columnMaps){if(StringUtils.isEmpty(sql))returnnull;String_sql=sql+""Stringkey=_sql.replaceAll(":(.+?),\\s*","?,").replaceAll(":(.+?)[)]\\s*","?)").replaceAll(":(.+?)\\s+","?");Map<String,List<String>>result=newHashMap<String,List<String>>();List<String>fieldList=newLinkedList<String>();Patternpattern=Pattern.compile(":(.+?)[)|,|\\s*]");Matchermatcher=pattern.matcher(_sql);StringBufferinsertString=newStringBuffer();while(matcher.find()){Stringvalue=matcher.group(1);fieldList.add(value);insertString.append(columnMaps.get(value)+",");}if(fieldList.isEmpty()||key.equals(_sql))returnnull;StringBufferkey_sb=newStringBuffer(key);if(!key.trim().matches("insert\\s*into\\s*[\\w|_]+?\\(.*?\\)\\s*values.*")&&!key.trim().contains("update")){//判断insert语句是否有数据库字段,比如:insertintot1(ID,NAME)key_sb.insert(key_sb.indexOf("values")-1,"("+insertString.substring(0,insertString.length()-1)+")");}result.put(key_sb.toString(),fieldList);returnresult;}}4、定义一个对clob和blob的通用类[[关键类],也可以说是已经存在的Dao类的扩展类。Java代码/***@description增强版数据库操作类[添力口对clob和blob的部分操作]*@authoraokunsang*@date2013-7-4*/publicclassStGenericDaoextendsGenericDao/***查询单条记录*@param<T>*@paramsql*@paramclazz@paramargs*@return*/public<T>T_find(Stringsql,finalClass<T>clazz,Object...args){printSqlInfo(sql,args!=null?Arrays.toString(args):"");tryreturnjdbcTemplate.queryForObject(sql,newRowMapper<T>(){@OverridepublicTmapRow(ResultSetrs,intrownum)throwsSQLException{Tbean=null;try{bean=clazz.newInstance();Field[]fields=clazz.getDeclaredFields();//获取所有属性for(Fieldfield:fields){if(field.getAnnotation(PmcColumn.class)==null)continue;if(BeanUtils.getPmcColumnIgnore(field))continue;switch(BeanUtils.getPmcColumnType(field)){//如果Bean中增加了类型,需要在这里以及下面方法中添加casecaseTypes.CLOB:{BeanUtils.setter(bean,field.getName(),lobHandler.getClobAsString(rs,BeanUtils.getPmcColumnName(field)),field.getType());break;}caseTypes.BLOB:{BeanUtils.setter(bean,field.getName(),lobHandler.getBlobAsBytes(rs,BeanUtils.getPmcColumnName(field)),field.getType());break;}caseTypes.TIMESTAMP:{BeanUtils.setter(bean,field.getName(),rs.getTimestamp(BeanUtils.getPmcColumnName(field)),field.getType());break;}caseTypes.DATE:{BeanUtils.setter(bean,field.getName(),rs.getDate(BeanUtils.getPmcColumnName(field)),field.getType());break;}caseTypes.INTEGER:{BeanUtils.setter(bean,field.getName(),rs.getInt(BeanUtils.getPmcColumnName(field)),field.getType());break;}caseTypes.VARCHAR:{BeanUtils.setter(bean,field.getName(),rs.getString(BeanUtils.getPmcColumnName(field)),field.getType());break;}caseTypes.NUMERIC:{BeanUtils.setter(bean,field.getName(),rs.getLong(BeanUtils.getPmcColumnName(field)),field.getType());break;caseTypes.FLOAT:{BeanUtils.setter(bean,field.getName(),rs.getFloat(BeanUtils.getPmcColumnName(field)),field.getType());break;}}}}catch(Exceptione){e.printStackTrace();}returnbean;}},args);}catch(EmptyResultDataAccessExceptione){returnnull;}catch(DataAccessExceptione){thrownewDaoRuntimeException("数据库错误saveOrUpdate()",e);}}/***添加或修改某条记录*@param<T>@paramsql*@parambean*/public<T>void_saveOrUpdate(Stringsql,finalTbean){finalMap<String,Integer>columnTypes=newHashMap<String,Integer>();Map<String,String>columnMaps=newHashMap<String,String>();Field[]fields=bean.getClass().getDeclaredFields();//获取所有属性for(Fieldfield:fields){columnTypes.put(field.getName(),BeanUtils.getPmcColumnType(field));columnMaps.put(field.getName(),BeanUtils.getPmcColumnName(field));}finalMap<String,List<String>>resultMap=Util.spQuerysql(sql,columnMaps);if(resultMap==null)thrownewPmcRuntimeException(String.format("你提供的SQL语句有问题,请详细检查再次尝试运行。SQL:[s%]",sql));Object[]validSql=resultMap.keySet().toArray();//改变后的Sql语句printSqlInfo(sql+"<<>>"+validSql[0].toString(),"");//打印改变前后的sql语句finalList<String>fieldList=resultMap.get(validSql[0]);//对应插入的bean字段jdbcTemplate.execute(validSql[0].toString(),newAbstractLobCreatingPreparedStatementCallback(this.lobHandler){@OverrideprotectedvoidsetValues(PreparedStatementps,LobCreatorlobCreater)throwsSQLException,DataAccessException{for(inti=0,length=fieldList.size();i<length;i++){StringfiledValue=fieldList.get(i);switch(columnTypes.get(filedValue)){caseTypes.CLOB:{lobCreater.setClobAsString(ps,i+1,BeanUtils.getter(bean,filedValue)==null?null:BeanUtils.getter(bean,filedValue).toString());break;}caseTypes.BLOB:{lobCreater.setBlobAsBytes(ps,i+1,BeanUtils.getter(bean,filedValue)==null?null:(byte[])BeanUtils.getter(bean,filedValue));break;}caseTypes.TIMESTAMP:{ps.setTimestamp(i+1,BeanUtils.getter(bean,filedValue)==null?null:(Timestamp)BeanUtils.getter(bean,filedValue));break;}caseTypes.DATE:{ps.setDate(i+1,BeanUtils.getter(bean,filedValue)==null?null:(Date)BeanUtils.getter(bean,filedValue));break;}caseTypes.INTEGER:{ps.setInt(i+1,BeanUtils.getter(bean,filedValue)==null?null:(Integer)BeanUtils.getter(bean,filedValue));break;}caseTypes.VARCHAR:{ps.setString(i+1,BeanUtils.getter(bean,filedValue)==null?null:BeanUtils.getter(bean,filedValue).toString());break;}caseTypes.NUMERIC:{ps.setLong(i+1,BeanUtils.getter(bean,filedValue)==null?null:(Long)BeanUtils.getter(bean,filedValue));break;}caseps.setFloatTypes.FLOAT:{(i+1,BeanUtils.getter(bean,filedValue)==null?null:(Float)BeanUtils.getter(bean,filedValue));break;});}}5、对JDBC的配置文件修改,添加lobHandler类,并且注入到StGenericDao中。Xml代码<!--JDBC上传附件时候使用--><beanid="lobHandler"class="org.springframework.jdbc.support.lob.DefaultLobHandler"/><!--默认数据源[showsql-是否显示sql语句]如果需要操作clob和blob,则声明StGenericDao--><beanid="genericDao"class="com.pmc.dwa.common.dao.StGenericDao"><propertyname="simpleJdbcTemplate"ref="dataSource"></property><propertyname="showsql"value="true"></property><propertyname="lobHandler"ref="lobHandler"></property></bean>如何使用以上方法,需要注意以下2个方面:其一:如果某个Bean类中包括Clob和Blob字段,那么该Bean的字段类型需要加入PmcColumn注解。如:Java代码/***@description*@authoraokunsang*@date2013-7-4*/publicclassTDemoimplementsSerializable{@PmcColumn(columnName="ID",type=Types.NUMERIC)privateLongid;@PmcColumn(columnName="NAME",type=Types.VARCHAR)privateStringname;@PmcColumn(columnName="DEMO_PIC",type=Types.BLOB)privatebyte[]pic;//BLOB类型,属性字段类型为byte[]@PmcColumn(columnName="CONTENT",type=Types.CLOB)privateStringcontent;//CLOB类型,属性字段类型为Stringsetterandgetter...}其二:Service业务方法中注入StGenericdao类,使用其方法即可;当然如果你操作的Bean类没有Clob和Blob类型字段就无需写PmcColumn注解,注入IGenericDao接口也可以。Java代码/***@description*@authoraokunsang*@date2013-7-4*/@ServicepublicclassDemoServiceImplimplementsIDemoService{@Resource(name="genericDao")privateStGenericDaogenericDao;publicvoidsaveDemo(TDemodemo){genericDao._saveOrUpdate("insertintotdemovalues(:id,:name,:pic,:content)",demo);}}
本文档为【SpringJdbcTemplate操作Clob和Blob的通用类封装】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
该文档来自用户分享,如有侵权行为请发邮件ishare@vip.sina.com联系网站客服,我们会及时删除。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。
本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。
网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
下载需要: 免费 已有0 人下载
最新资料
资料动态
专题动态
is_179289
暂无简介~
格式:doc
大小:19KB
软件:Word
页数:0
分类:
上传时间:2018-05-18
浏览量:3