【代码生成】生成数据库下某个存储过程的访问代码(续)
2013-05-08 15:31
615 查看
【新近补充留言】
我认为:生成存储过程的访问代码最核心的是如何获取存储过程的信息及参数,如何将这些参数存储起来供模板编写时候使用,
如何根据实际项目不同编写一个模板。
每一种语言都有对应的获取方式,所以思路更重要。
========================================================================================
匆匆忙忙写完了自动生成存储过程的一堆方法,(针对的是sql server2005),
【ps:这个只是最初完成品,可能有很多东西需要完善,但是已经将必要的生成等逻辑解决了。】
下面是相关类:
【处理逻辑】
【模板】
【下面将关键代码都贴出来给大家参考】
【DataTypeHelper。java】
【DataTypeHelperWrapper.java 其实这个是为了可以在velocity里面用而不得不将静态方法都封装成一个类了。】
【procedureInfo 这个是为了将需要的存储过程信息封装到一起方便写模板时引用,其实很大的工作量在写模板及完善工具类上面,反正重复性的工作都具有很多共同点】
【SQLDataType.java 这个类是为了区别每一个参数的类型,不过我现在想起来,倒不如利用java.sql.Types的类型来区分好】
【SqlParameterDirection 同样,这个是封装了参数的输入输出类型】
【SQLParameterInfo 同样,这个是封装了存储过程的参数的详细信息,方便查阅】
【SQLProcedureFactory 这个类是核心,用于从数据库中获得符合条件的存储过程及下属所有参数的信息】
【IProcedureFactory 一个接口,原本打算以后可以提供mysql,oracle及postgresql之类数据库的,暂时用不到】
【JavaDataType 枚举,用于辨识属于java的哪一个变量类型】
【ProcedureGenerator 对外的接口,用于获取存储过程信息,并采用模板引擎及模板处理,获得处理后的字符】
【下面是我自行编写的模板引擎的辅助类,VelocityHelper 这篇东西用得到】
【最后是写得很辛苦的一个模板,proc.vm】
【如何使用?】
【得到的结果】
我认为:生成存储过程的访问代码最核心的是如何获取存储过程的信息及参数,如何将这些参数存储起来供模板编写时候使用,
如何根据实际项目不同编写一个模板。
每一种语言都有对应的获取方式,所以思路更重要。
========================================================================================
匆匆忙忙写完了自动生成存储过程的一堆方法,(针对的是sql server2005),
【ps:这个只是最初完成品,可能有很多东西需要完善,但是已经将必要的生成等逻辑解决了。】
下面是相关类:
【处理逻辑】
【模板】
【下面将关键代码都贴出来给大家参考】
【DataTypeHelper。java】
package CodeGen.MSSQL; import CodeGen.JavaDataType; public class DataTypeHelper { /** * 根据字符串获得相应的sqlserver数据类型 * */ public static SQLDataType str2SQLType(String str){ if(str==null){ return SQLDataType.UNKNOWN; } String str_1=str.trim().toLowerCase(); if(str_1.equals("int")){ return SQLDataType.INT; } else if(str_1.equals("bigint")){ return SQLDataType.BIGINT; } else if(str_1.equals("bigint")){ return SQLDataType.BIGINT; } else if(str_1.equals("bit")){ return SQLDataType.BIT; } else if(str_1.equals("char")){ return SQLDataType.CHAR; } else if(str_1.equals("nchar")){ return SQLDataType.NCHAR; } else if(str_1.equals("nvarchar")){ return SQLDataType.NVARCHAR; } else if(str_1.equals("varchar")){ return SQLDataType.VARCHAR; } else if(str_1.equals("ntext")){ return SQLDataType.NTEXT; } else if(str_1.equals("text")){ return SQLDataType.TEXT; } else if(str_1.equals("datetime")){ return SQLDataType.DATETIME; } else if(str_1.equals("decimal")){ return SQLDataType.DECIMAL; } else if(str_1.equals("float")){ return SQLDataType.FLOAT; } else if(str_1.equals("money")){ return SQLDataType.MONEY; } else if(str_1.equals("numberic")){ return SQLDataType.NUMBERIC; } else if(str_1.equals("real")){ return SQLDataType.REAL; } else if(str_1.equals("smalldatetime")){ return SQLDataType.SMALLDATETIME; } else if(str_1.equals("smallint")){ return SQLDataType.SMALLINT; } else if(str_1.equals("smallmoney")){ return SQLDataType.SMALLMONEY; } else if(str_1.equals("tinyint")){ return SQLDataType.TINYINT; } else if(str_1.equals("xml")){ return SQLDataType.XML; } return SQLDataType.UNKNOWN; } /** * 数据库类型转为java数据类型。 * */ public static JavaDataType mssqlType2JavaDataType(SQLDataType sqlType){ if (sqlType== SQLDataType.UNKNOWN){ return JavaDataType.UNKNOWN; } else if( sqlType== SQLDataType.CHAR|| sqlType== SQLDataType.NCHAR|| sqlType== SQLDataType.NVARCHAR|| sqlType== SQLDataType.NTEXT|| sqlType== SQLDataType.TEXT|| sqlType== SQLDataType.XML|| sqlType== SQLDataType.VARCHAR ){ return JavaDataType.STRING; } else if(sqlType== SQLDataType.INT||sqlType== SQLDataType.TINYINT||sqlType== SQLDataType.SMALLINT){ return JavaDataType.INTEGER; } else if (sqlType== SQLDataType.BIGINT){ return JavaDataType.LONG; } else if(sqlType== SQLDataType.BIT){ return JavaDataType.BOOLEAN; } else if(sqlType== SQLDataType.DATETIME||sqlType== SQLDataType.SMALLDATETIME){ return JavaDataType.DATETIME; } else if(sqlType== SQLDataType.DECIMAL||sqlType== SQLDataType.MONEY||sqlType== SQLDataType.NUMBERIC){ return JavaDataType.FLOAT; } else if(sqlType== SQLDataType.REAL||sqlType== SQLDataType.FLOAT){ return JavaDataType.DOUBLE; } return JavaDataType.UNKNOWN; } public static SQLParameterDirection int2Direction(int theDirectionTypeID){ if(theDirectionTypeID==1){ return SQLParameterDirection.Input; } else if(theDirectionTypeID==2){ return SQLParameterDirection.InputOutput; } else if(theDirectionTypeID==5){ return SQLParameterDirection.ReturnValue; } else{ return SQLParameterDirection.UNKNOWN; } } public static String javaDataType2String(JavaDataType jdatatype){ if (jdatatype==JavaDataType.BOOLEAN){ return "boolean"; } if(jdatatype==JavaDataType.DATETIME){ return "Date"; } if(jdatatype==JavaDataType.DOUBLE){ return "double"; } if (jdatatype==JavaDataType.FLOAT){ return "float"; } if(jdatatype==JavaDataType.INTEGER){ return "int"; } if(jdatatype==JavaDataType.LONG){ return "long"; } if(jdatatype==JavaDataType.STRING){ return "String"; } if(jdatatype==JavaDataType.UNKNOWN){ return "Object"; } return "Object"; } }
【DataTypeHelperWrapper.java 其实这个是为了可以在velocity里面用而不得不将静态方法都封装成一个类了。】
package CodeGen.MSSQL; import CodeGen.JavaDataType; import java.util.Date; public class DataTypeHelperWrapper { public String convertJavaDataType2String(JavaDataType jDataType){ return DataTypeHelper.javaDataType2String(jDataType); } public String convertSQLDataType2javaJDBCSQLtype(){ return ""; } public String getJavaTypeDefaultValue(JavaDataType javaDataType){ if(javaDataType==JavaDataType.BOOLEAN){ return "false"; } else if(javaDataType==JavaDataType.DATETIME){ return "new Date()"; } else if(javaDataType==JavaDataType.DOUBLE){ return "0.0"; } else if(javaDataType==JavaDataType.FLOAT){ return "0.0"; } else if(javaDataType==JavaDataType.INTEGER){ return "0"; } else if(javaDataType==JavaDataType.LONG){ return "0"; } else if(javaDataType==JavaDataType.STRING){ return "\"\""; } else if(javaDataType==JavaDataType.UNKNOWN){ return "new Object()"; } return "UNKOWN"; } public boolean checkJtype_isString(JavaDataType jtype){ return jtype==JavaDataType.STRING; } public boolean checkJtype_isBoolean(JavaDataType jtype){ return jtype==JavaDataType.BOOLEAN; } public boolean checkJtype_isDateTime(JavaDataType jtype){ return jtype==JavaDataType.DATETIME; } public boolean checkJtype_isDouble(JavaDataType jtype){ return jtype==JavaDataType.DOUBLE; } public boolean checkJtype_isFloat(JavaDataType jtype){ return jtype==JavaDataType.FLOAT; } public boolean checkJtype_isInteger(JavaDataType jtype){ return jtype==JavaDataType.INTEGER; } public boolean checkJtype_isLong(JavaDataType jtype){ return jtype==JavaDataType.LONG; } public boolean checkJtype_isUnknown(JavaDataType jtype){ return jtype==JavaDataType.UNKNOWN; } }
【procedureInfo 这个是为了将需要的存储过程信息封装到一起方便写模板时引用,其实很大的工作量在写模板及完善工具类上面,反正重复性的工作都具有很多共同点】
package CodeGen.MSSQL; import java.util.ArrayList; /** * PROCEDURE_CAT :JWebBase PROCEDURE_SCHEM :dbo PROCEDURE_NAME :proc_paras_test;1 NUM_INPUT_PARAMS :-1 NUM_OUTPUT_PARAMS :-1 NUM_RESULT_SETS :-1 REMARKS : PROCEDURE_TYPE :2 * * * */ public class ProcedureInfo { public String dataBase=""; public String schem=""; public String name=""; public String getName(){ return name; } protected ArrayList<SQLParamterInfo> paraList=new ArrayList<SQLParamterInfo>(); public ArrayList<SQLParamterInfo> getParameters(){ return paraList; } }
【SQLDataType.java 这个类是为了区别每一个参数的类型,不过我现在想起来,倒不如利用java.sql.Types的类型来区分好】
package CodeGen.MSSQL; public enum SQLDataType { INT, BIGINT, BIT, CHAR, DATETIME, DECIMAL, FLOAT, MONEY, NCHAR, VARCHAR, NVARCHAR, NTEXT, NUMBERIC, REAL, SMALLDATETIME, SMALLINT, SMALLMONEY, TINYINT, TEXT, XML, UNKNOWN }
【SqlParameterDirection 同样,这个是封装了参数的输入输出类型】
package CodeGen.MSSQL; public enum SQLParameterDirection { Input, InputOutput, ReturnValue, UNKNOWN }
【SQLParameterInfo 同样,这个是封装了存储过程的参数的详细信息,方便查阅】
package CodeGen.MSSQL; import CodeGen.JavaDataType; public class SQLParamterInfo { protected String COLUMN_NAME=""; protected String TYPE_NAME=""; protected int LENGTH=0; protected int COLUMN_TYPE=0; protected String PROCEDURE_SCHEM=""; protected String PROCEDURE_NAME=""; public String DATA_TYPE=""; public String getDATATYPE(){ return DATA_TYPE; } protected SQLDataType sqlDataType; protected SQLParameterDirection paraDirection; protected JavaDataType javaDataType; protected String procedureName=""; public String getSqlTypeName(){ return TYPE_NAME; } public String getProceDureName(){ return procedureName; } public String getSchem(){ return PROCEDURE_SCHEM; } public int getSize(){ return LENGTH; } public String getParameterName(){ return COLUMN_NAME.replace('@',' ').trim(); } public SQLDataType getSqlType(){ return sqlDataType; } public JavaDataType getJavaDataType(){ return javaDataType; } public SQLParameterDirection getDirection(){ return paraDirection; } public boolean isString(){ if(javaDataType==JavaDataType.STRING){ return true; } else{ return false; } } public boolean isInputParameter(){ if(paraDirection== SQLParameterDirection.Input){ return true; } else{ return false; } } public boolean isInputOutputParameter(){ return paraDirection== SQLParameterDirection.InputOutput; } public boolean isReturnValueParameter(){ return paraDirection==SQLParameterDirection.ReturnValue; } }
【SQLProcedureFactory 这个类是核心,用于从数据库中获得符合条件的存储过程及下属所有参数的信息】
package CodeGen.MSSQL; import CodeGen.IProcedureFactory; import Easis.DBUtility.DataRow; import Easis.DBUtility.DataTable; import Easis.DBUtility.DataTableHelper; import java.sql.Connection; import java.sql.DatabaseMetaData; import java.sql.ResultSet; import java.util.ArrayList; public class SQLProcedureFactory implements IProcedureFactory { /** * 根据存储过程的名称从连接里面获取相关信息及对应参数,请注意,假如存储过程名称为null或者空,那么就全部存储过程都找出来 * */ public static ArrayList<ProcedureInfo> getProcedureList(Connection mssql_connction,String dbOwner_Shem,String prodcedureName){ ArrayList<ProcedureInfo> procInfoList=new ArrayList<ProcedureInfo>(); try{ DatabaseMetaData dmdata=mssql_connction.getMetaData(); String p_name=(prodcedureName==null||prodcedureName.trim().equals(""))?null:prodcedureName; ResultSet rs_procs= dmdata.getProcedures(null, dbOwner_Shem, p_name); DataTable dt_procs= DataTableHelper.rs2datatable(rs_procs); rs_procs.close(); //--遍历存储过程,获得相关信息 for(DataRow dr_proc:dt_procs.getRows()){ ProcedureInfo prinfo=new ProcedureInfo(); prinfo.dataBase=dr_proc.get("PROCEDURE_CAT").toString(); prinfo.name=dr_proc.get("PROCEDURE_NAME").toString(); if(prinfo.name.indexOf(';')!=-1){ prinfo.name=prinfo.name.substring(0,prinfo.name.lastIndexOf(';')); } prinfo.schem=dr_proc.get("PROCEDURE_SCHEM").toString(); prinfo.paraList=new ArrayList<SQLParamterInfo>(); ResultSet rs_parameters=dmdata.getProcedureColumns(null,prinfo.schem,prinfo.name,null); DataTable dt_columns=DataTableHelper.rs2datatable(rs_parameters); rs_parameters.close(); for (DataRow dr_para:dt_columns.getRows()){ SQLParamterInfo pinfo3=new SQLParamterInfo(); pinfo3.COLUMN_NAME= dr_para.get("COLUMN_NAME").toString().replace('@',(char)32).trim(); pinfo3.LENGTH=dr_para.get("LENGTH").toInt(); pinfo3.PROCEDURE_NAME=prinfo.name; pinfo3.procedureName=prinfo.name; pinfo3.TYPE_NAME=dr_para.get("TYPE_NAME").toString().trim(); pinfo3.PROCEDURE_SCHEM=prinfo.schem; pinfo3.paraDirection=DataTypeHelper.int2Direction(dr_para.get("COLUMN_TYPE").toInt()); pinfo3.sqlDataType=DataTypeHelper.str2SQLType(pinfo3.TYPE_NAME); pinfo3.javaDataType=DataTypeHelper.mssqlType2JavaDataType(pinfo3.sqlDataType); pinfo3.COLUMN_TYPE=dr_para.get("COLUMN_TYPE").toInt(); pinfo3.DATA_TYPE=dr_para.get("DATA_TYPE").toString(); pinfo3.paraDirection=DataTypeHelper.int2Direction(pinfo3.COLUMN_TYPE); //--添加上去 prinfo.paraList.add(pinfo3); } procInfoList.add(prinfo); } } catch (Exception e){ e.printStackTrace(); } return procInfoList; } }
【IProcedureFactory 一个接口,原本打算以后可以提供mysql,oracle及postgresql之类数据库的,暂时用不到】
package CodeGen; public interface IProcedureFactory { }
【JavaDataType 枚举,用于辨识属于java的哪一个变量类型】
package CodeGen; public enum JavaDataType { INTEGER, STRING, LONG, FLOAT, DOUBLE, BOOLEAN, DATETIME, UNKNOWN }
【ProcedureGenerator 对外的接口,用于获取存储过程信息,并采用模板引擎及模板处理,获得处理后的字符】
package CodeGen; import CodeGen.MSSQL.DataTypeHelperWrapper; import CodeGen.MSSQL.SQLProcedureFactory; import CodeGen.MSSQL.ProcedureInfo; import Easis.Common.StringUtilWrapper; import Easis.ViewEngine.VelocityHelper; import java.sql.Connection; import java.util.ArrayList; public class ProcedureGenerator { public ProcedureGenerator(){ } public String GenerateMSSQLProcedures(Connection mssql_conn,String schemName,ArrayList<String> procedureList,String ClassName){ String str1=""; try{ ArrayList<ProcedureInfo> totalProcList=new ArrayList<ProcedureInfo>(); if(procedureList==null||procedureList.size()<=0){ totalProcList=SQLProcedureFactory.getProcedureList(mssql_conn, schemName, null); } else{ for (String procName1:procedureList){ ArrayList<ProcedureInfo> proclist= SQLProcedureFactory.getProcedureList(mssql_conn, schemName, procName1); //--合并相关参数 for (ProcedureInfo ptmp:proclist){ totalProcList.add(ptmp); } } } VelocityHelper _vEngine=new VelocityHelper("/tpl/CodeGen/"); StringUtilWrapper strWrapper=new StringUtilWrapper(); DataTypeHelperWrapper typeHepler=new DataTypeHelperWrapper(); _vEngine.put("ClassName",ClassName); _vEngine.put("ProcedureList",totalProcList); _vEngine.put("StrWrapper",strWrapper); _vEngine.put("typeHelper",typeHepler); String str_res=_vEngine.parseTempalte("/MSSQL/proc.vm","UTF-8"); System.out.println(str_res); } catch (Exception e){ str1=e.toString(); } return str1; } }
【下面是我自行编写的模板引擎的辅助类,VelocityHelper 这篇东西用得到】
package Easis.ViewEngine; import java.io.BufferedWriter; import java.io.OutputStreamWriter; import java.io.StringWriter; import java.util.ArrayList; import java.util.Properties; import org.apache.velocity.Template; import org.apache.velocity.VelocityContext; import org.apache.velocity.app.Velocity; public class VelocityHelper { private String _tplRoot=""; private VelocityContext _context=new VelocityContext(); public VelocityContext getVelocityContext(){ return _context; } public void clear(){ _context=new VelocityContext(); } public VelocityHelper(String tplRootPath){ _initialization("utf-8", "utf-8", tplRootPath); } public VelocityHelper(String input_encoding,String output_encoding,String tplRootPath){ _initialization(input_encoding, output_encoding, tplRootPath); } public boolean put(String key,Object value){ if(_context.containsKey(key)==true){ _context.remove(key); _context.put(key,value); } else{ _context.put(key,value); } return true; } public boolean remove(String key){ if(_context.containsKey(key)==false){ return false; } _context.remove(key); return true; } private void _initialization(String input_encoding,String output_encoding,String tplRootPath){ /* first, we init the runtime engine. Defaults are fine. */ this._tplRoot=tplRootPath==null?"":tplRootPath; Properties p = new Properties(); //设置输入输出编码类型。和这次说的解决的问题无关 p.setProperty(Velocity.INPUT_ENCODING, input_encoding); p.setProperty(Velocity.OUTPUT_ENCODING, output_encoding); //这里加载类路径里的模板而不是文件系统路径里的模板 p.setProperty("file.resource.loader.class", "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader"); //也可以用下面方法指定一个绝对路径,不过这样要求你所有的模板都放在该路径下,是有局限的 //p.setProperty(Velocity.FILE_RESOURCE_LOADER_PATH, "模板路径"); try { Velocity.init(p); } catch(Exception e) { System.out.println("Problem initializing Velocity : " + e ); e.printStackTrace(); return; } } public String parseTempalte(String tplName,String encoding){ try{ String tplroot_and_tplName=""; if(_tplRoot.trim().length()>0){ tplroot_and_tplName=_tplRoot.trim()+"/"+tplName.trim(); } else{ tplroot_and_tplName=tplName.trim(); } tplroot_and_tplName=tplroot_and_tplName.replaceAll("/+","/"); StringWriter sw=new StringWriter(); Velocity.mergeTemplate(tplroot_and_tplName,encoding,_context,sw); String res=sw.toString(); sw.close(); return res; } catch (Exception e){ return e.toString(); } } /** * @return * * */ public String evaluate(String velocityTplStrContent){ try{ StringWriter sw=new StringWriter(); Velocity.evaluate(_context,sw,"Use the velocity as str replacer.",velocityTplStrContent); String res=sw.toString(); sw.close(); return res; } catch (Exception e){ return e.toString(); } } }
【最后是写得很辛苦的一个模板,proc.vm】
#* @vtlvariable name="ClassName" type="java.lang.String" *# #* @vtlvariable name="ProcedureList" type="java.util.ArrayList<CodeGen.MSSQL.ProcedureInfo>" *# #* @vtlvariable name="StrWrapper" type="Easis.Common.StringUtilWrapper" *# #* @vtlvariable name="typeHelper" type="CodeGen.MSSQL.DataTypeHelperWrapper" *# import EWeb.Common.DBReturnInfo; import EWeb.DB.DBConnection; import Easis.Common.StringUtil; import Easis.DBUtility.DataRow; import Easis.DBUtility.DataTable; import Easis.DBUtility.DataTableHelper; import java.util.Date; import java.sql.*; import java.util.List; /** * 这是利用CodeGen工具生成的自动访问数据库的一个模板,作者为“码农下的天桥” *生成的类名称:${ClassName} * @author 码农下的天桥 * @version 1.00 */ public class $ClassName { #if($ProcedureList.size()<=0) /****************************/ /******存储过程列表为空******/ /****************************/ #else #foreach($procInfo in $ProcedureList) #*这里是对存储过程的详细详细解释,让码农不用到处翻存储过程对参数*# /*--这里是对存储过程的详细详细解释,方便查存储过程对参数--- *存储过程名称:$procInfo.getName() #foreach($litem1 in $procInfo.getParameters()) #set($ParaName= $StrWrapper.Lpad_filledStr($litem1.getParameterName()," ",15)) #set($SizeStr=$litem1.getSize()+"") #set($TypeStr=$StrWrapper.Lpad_filledStr($litem1.getSqlTypeName()," ",8)) #if($litem1.isString()) #set($SizeStr=$StrWrapper.Lpad_filledStr($SizeStr," ",12)) #else #set($SizeStr=$StrWrapper.Lpad_filledStr("非字符类型"," ",12))#end #set($DirectionStr="") #if($litem1.isInputParameter()==true) #set($DirectionStr="输入参数") #elseif($litem1.isInputOutputParameter()==true) #set($DirectionStr="输出参数") #elseif($litem1.isReturnValueParameter()==true) #set($DirectionStr="返回值") #else #set($DirectionStr="未知类型") #end *参数名称:$ParaName 参数类型:$TypeStr 长度:$SizeStr 参数方向:$DirectionStr #end */ #*存储过程详细解释结束*# #*对存储过程作解释*# /** *存储过程名称:$procInfo.getName() *存储过程参数:#if($procInfo.getParameters().size()<=0) 参数个数为0 #end #foreach($litem1 in $procInfo.getParameters()) #if($litem1.isInputParameter()==true) #set($ParaName= $StrWrapper.Lpad_filledStr($litem1.getParameterName()," ",15)) #set($SizeStr=$litem1.getSize()+"") #set($TypeStr=$StrWrapper.Lpad_filledStr($litem1.getSqlTypeName()," ",8)) #if($litem1.isString()) #set($SizeStr=$StrWrapper.Lpad_filledStr($SizeStr," ",12)) #else #set($SizeStr=$StrWrapper.Lpad_filledStr("非字符类型"," ",12))#end #set($DirectionStr="") #if($litem1.isInputParameter()==true) #set($DirectionStr="输入参数") #elseif($litem1.isInputOutputParameter()==true) #set($DirectionStr="输出参数") #elseif($litem1.isReturnValueParameter()==true) #set($DirectionStr="返回值") #else #set($DirectionStr="未知类型") #end #set($javaTypeStr=$StrWrapper.Lpad_filledStr($typeHelper.convertJavaDataType2String($litem1.javaDataType)," ",8)) *@param $ParaName 【参数名称:$ParaName 参数类型:$TypeStr 对应java类型:$javaTypeStr 长度:$SizeStr 】 #end #end * *@return DataTable对象。 */ #*对存储过程作解释*# #*参数定义*# #set($functionParas="") #foreach($litem1 in $procInfo.getParameters()) #if($litem1.isInputParameter()==true) #set($functionParas=$functionParas+" "+ $typeHelper.convertJavaDataType2String($litem1.javaDataType).trim()+" "+$litem1.getParameterName()+",") #end #end #if($functionParas.lastIndexOf(',')!=-1) #set($functionParas=$functionParas.substring(0,$functionParas.lastIndexOf(','))) #end #*参数定义结束*# public DataTable ${procInfo.getName()}($functionParas ){ #set($outputParaTotal=0) #foreach($litem1 in $procInfo.getParameters()) #if($litem1.isInputOutputParameter()==true) #set($outputParaTotal=$outputParaTotal+1) #end #end #if($outputParaTotal>0) /*注意: *由于java里面没有out int id 这种参数实现, *所以需要这里额外定义的output参数最好放入DataTable里面, *然后传给界面层使用*/ /*output参数定义*/ #foreach($litem1 in $procInfo.getParameters()) #if($litem1.isInputOutputParameter()==true) #set($jtypeDefStr=$StrWrapper.Lpad_filledStr($typeHelper.convertJavaDataType2String( $litem1.getJavaDataType())," ",10)) #set($pName=$StrWrapper.Lpad_filledStr($litem1.getParameterName()," ",10)) $jtypeDefStr $pName = $StrWrapper.Lpad_filledStr($typeHelper.getJavaTypeDefaultValue($litem1.getJavaDataType())," ",12) ; #end #end /*output参数定义结束*/ #end #set($callable_paras="") #set($cindex_1=0) #foreach($litem1 in $procInfo.getParameters()) #if($litem1.isInputOutputParameter()==true||$litem1.isInputParameter()==true) #set($cindex_1=$cindex_1+1) #set($callable_paras=$callable_paras+" "+$cindex_1+",") #end #end #if($callable_paras.lastIndexOf(",")!=-1) #set($callable_paras=$callable_paras.substring(0,$callable_paras.lastIndexOf(","))) #end /*调用存储过程*/ DataTable res__datatable=new DataTable(); try{ Connection __myconn=DBConnection.getConnection(); CallableStatement _stmt=__myconn.prepareCall("{ call ${procInfo.getName()}($callable_paras)}"); #set($cindex_1=0) #foreach($litem1 in $procInfo.getParameters()) #if($litem1.isInputOutputParameter()==true||$litem1.isInputParameter()==true) #set($cindex_1=$cindex_1+1) #*假如是输入参数*# #if($litem1.isInputParameter()) #if($typeHelper.checkJtype_isBoolean($litem1.getJavaDataType())) _stmt.setBoolean($cindex_1,$litem1.getParameterName()); #elseif($typeHelper.checkJtype_isDateTime($litem1.getJavaDataType())) _stmt.setDate($cindex_1,new java.sql.Date($litem1.getParameterName()));//日期函数--注意,setDate必须为SqlDate的内容 #elseif($typeHelper.checkJtype_isDouble($litem1.getJavaDataType())) _stmt.setDouble($cindex_1,$litem1.getParameterName()); #elseif($typeHelper.checkJtype_isFloat($litem1.getJavaDataType())) _stmt.setFloat($cindex_1,$litem1.getParameterName()); #elseif($typeHelper.checkJtype_isInteger($litem1.getJavaDataType())) _stmt.setInt($cindex_1,$litem1.getParameterName()); #elseif($typeHelper.checkJtype_isLong($litem1.getJavaDataType())) _stmt.setLong($cindex_1,$litem1.getParameterName()); #elseif($typeHelper.checkJtype_isString($litem1.getJavaDataType())) _stmt.setString($cindex_1,$litem1.getParameterName()); #else _stmt.setObject($cindex_1,$litem1.getParameterName()); #end#end #*假如是输出参数*### #if($litem1.isInputOutputParameter()==true) _stmt.registerOutParameter($cindex_1, $litem1.getDATATYPE(),$litem1.getSize()); #end #*输出参数结束*### #end #end ResultSet __rslist =_stmt.executeQuery(); res__datatable=DataTableHelper.rs2datatable(__rslist); #if($outputParaTotal>0) /*取回参数*/ #end #set($cindex_1=0) #foreach($litem1 in $procInfo.getParameters()) #if($litem1.isInputOutputParameter()==true||$litem1.isInputParameter()==true) #set($cindex_1=$cindex_1+1) #*假如是输出参数,那么赋值*### #if($litem1.isInputOutputParameter()==true) #if($typeHelper.checkJtype_isBoolean($litem1.getJavaDataType())) $litem1.getParameterName()=_stmt.getBoolean($cindex_1); #elseif($typeHelper.checkJtype_isDateTime($litem1.getJavaDataType())) $litem1.getParameterName()=_stmt.getDate($cindex_1); #elseif($typeHelper.checkJtype_isDouble($litem1.getJavaDataType())) $litem1.getParameterName()=_stmt.getDouble($cindex_1); #elseif($typeHelper.checkJtype_isFloat($litem1.getJavaDataType())) $litem1.getParameterName()=_stmt.getFloat($cindex_1); #elseif($typeHelper.checkJtype_isInteger($litem1.getJavaDataType())) $litem1.getParameterName()=_stmt.getInt($cindex_1); #elseif($typeHelper.checkJtype_isLong($litem1.getJavaDataType())) $litem1.getParameterName()=_stmt.getLong($cindex_1,$litem1); #elseif($typeHelper.checkJtype_isString($litem1.getJavaDataType())) $litem1.getParameterName()=_stmt.getString($cindex_1); #else $litem1.getParameterName()=_stmt.getObject($cindex_1); #end#end #end #end /*释放资源*/ __rslist.close(); _stmt.close(); } catch (Exception __e){ __e.printStackTrace(); } return res_datatable; } #end #end }
【如何使用?】
package TestCase; import CodeGen.ProcedureGenerator; import EWeb.DB.DBConnection; import java.sql.Connection; import java.util.ArrayList; public class testCodeGenProc { public static void main(String[] args){ ProcedureGenerator sgen=new ProcedureGenerator(); Connection myconn= DBConnection.getConnection(); ArrayList<String> procnames=new ArrayList<String>(); procnames.add("manager_add"); procnames.add("manager_edit"); procnames.add("manager_delete"); procnames.add("proc_paras_test"); String str1= sgen.GenerateMSSQLProcedures(myconn, "dbo", procnames, "mclass"); System.out.println(str1); } }
【得到的结果】
import EWeb.Common.DBReturnInfo; import EWeb.DB.DBConnection; import Easis.Common.StringUtil; import Easis.DBUtility.DataRow; import Easis.DBUtility.DataTable; import Easis.DBUtility.DataTableHelper; import java.util.Date; import java.sql.*; import java.util.List; /** * 这是利用CodeGen工具生成的自动访问数据库的一个模板,作者为“码农下的天桥” *生成的类名称:mclass * @author 码农下的天桥 * @version 1.00 */ public class mclass { /*--这里是对存储过程的详细详细解释,方便查存储过程对参数--- *存储过程名称:manager_add *参数名称:RETURN_VALUE 参数类型:int 长度:非字符类型 参数方向:返回值 *参数名称:userName 参数类型:nvarchar 长度:400 参数方向:输入参数 *参数名称:userPwd 参数类型:nvarchar 长度:400 参数方向:输入参数 *参数名称:realName 参数类型:nvarchar 长度:400 参数方向:输入参数 *参数名称:mobile 参数类型:nvarchar 长度:200 参数方向:输入参数 *参数名称:email 参数类型:nvarchar 长度:400 参数方向:输入参数 *参数名称:isLock 参数类型:bit 长度:非字符类型 参数方向:输入参数 *参数名称:addTime 参数类型:datetime 长度:非字符类型 参数方向:输入参数 */ /** *存储过程名称:manager_add *存储过程参数: *@param userName 【参数名称:userName 参数类型:nvarchar 对应java类型:String 长度:400 】 *@param userPwd 【参数名称:userPwd 参数类型:nvarchar 对应java类型:String 长度:400 】 *@param realName 【参数名称:realName 参数类型:nvarchar 对应java类型:String 长度:400 】 *@param mobile 【参数名称:mobile 参数类型:nvarchar 对应java类型:String 长度:200 】 *@param email 【参数名称:email 参数类型:nvarchar 对应java类型:String 长度:400 】 *@param isLock 【参数名称:isLock 参数类型:bit 对应java类型:boolean 长度:非字符类型 】 *@param addTime 【参数名称:addTime 参数类型:datetime 对应java类型:Date 长度:非字符类型 】 * *@return DataTable对象。 */ public DataTable manager_add( String userName, String userPwd, String realName, String mobile, String email, boolean isLock, Date addTime ){ /*调用存储过程*/ DataTable res__datatable=new DataTable(); try{ Connection __myconn=DBConnection.getConnection(); CallableStatement _stmt=__myconn.prepareCall("{ call manager_add( 1, 2, 3, 4, 5, 6, 7)}"); _stmt.setString(1,userName); _stmt.setString(2,userPwd); _stmt.setString(3,realName); _stmt.setString(4,mobile); _stmt.setString(5,email); _stmt.setBoolean(6,isLock); _stmt.setDate(7,new java.sql.Date(addTime));//日期函数--注意,setDate必须为SqlDate的内容 ResultSet __rslist =_stmt.executeQuery(); res__datatable=DataTableHelper.rs2datatable(__rslist); /*释放资源*/ __rslist.close(); _stmt.close(); } catch (Exception __e){ __e.printStackTrace(); } return res_datatable; } /*--这里是对存储过程的详细详细解释,方便查存储过程对参数--- *存储过程名称:manager_delete *参数名称:RETURN_VALUE 参数类型:int 长度:非字符类型 参数方向:返回值 *参数名称:ids 参数类型:nvarchar 长度:400 参数方向:输入参数 *参数名称:status 参数类型:int 长度:非字符类型 参数方向:输出参数 *参数名称:message 参数类型:nvarchar 长度:400 参数方向:输出参数 */ /** *存储过程名称:manager_delete *存储过程参数: *@param ids 【参数名称:ids 参数类型:nvarchar 对应java类型:String 长度:400 】 * *@return DataTable对象。 */ public DataTable manager_delete( String ids ){ /*注意: *由于java里面没有out int id 这种参数实现, *所以需要这里额外定义的output参数最好放入DataTable里面, *然后传给界面层使用*/ /*output参数定义*/ int status = 0 ; String message = "" ; /*output参数定义结束*/ /*调用存储过程*/ DataTable res__datatable=new DataTable(); try{ Connection __myconn=DBConnection.getConnection(); CallableStatement _stmt=__myconn.prepareCall("{ call manager_delete( 1, 2, 3)}"); _stmt.setString(1,ids); _stmt.registerOutParameter(2, 4,4); _stmt.registerOutParameter(3, -9,400); ResultSet __rslist =_stmt.executeQuery(); res__datatable=DataTableHelper.rs2datatable(__rslist); /*取回参数*/ status=_stmt.getInt(2); message=_stmt.getString(3); /*释放资源*/ __rslist.close(); _stmt.close(); } catch (Exception __e){ __e.printStackTrace(); } return res_datatable; } /*--这里是对存储过程的详细详细解释,方便查存储过程对参数--- *存储过程名称:proc_paras_test *参数名称:RETURN_VALUE 参数类型:int 长度:非字符类型 参数方向:返回值 *参数名称:testBITINT 参数类型:bigint 长度:非字符类型 参数方向:输入参数 *参数名称:testBINARY 参数类型:binary 长度:非字符类型 参数方向:输入参数 *参数名称:test1BIT 参数类型:bit 长度:非字符类型 参数方向:输入参数 *参数名称:testCHAR 参数类型:char 长度:1 参数方向:输入参数 *参数名称:testDATETIME 参数类型:datetime 长度:非字符类型 参数方向:输入参数 *参数名称:testDECIMAL 参数类型:decimal 长度:非字符类型 参数方向:输入参数 *参数名称:testFLOAT 参数类型:float 长度:非字符类型 参数方向:输入参数 *参数名称:testINT 参数类型:int 长度:非字符类型 参数方向:输入参数 *参数名称:testMONEY 参数类型:money 长度:非字符类型 参数方向:输入参数 *参数名称:testNCHAR 参数类型:nchar 长度:2 参数方向:输入参数 *参数名称:testNTEXT 参数类型:ntext 长度:2147483646 参数方向:输入参数 *参数名称:testNUMBERIC 参数类型:numeric 长度:非字符类型 参数方向:输入参数 *参数名称:testNVARCHAR 参数类型:nvarchar 长度:2 参数方向:输入参数 *参数名称:testREAL 参数类型:real 长度:非字符类型 参数方向:输入参数 *参数名称:testSMALLDATETIME 参数类型:smalldatetime 长度:非字符类型 参数方向:输入参数 *参数名称:testSMALLINT 参数类型:smallint 长度:非字符类型 参数方向:输入参数 *参数名称:testSMALLMONEY 参数类型:smallmoney 长度:非字符类型 参数方向:输入参数 *参数名称:testTINYINT 参数类型:tinyint 长度:非字符类型 参数方向:输入参数 *参数名称:testXML 参数类型:xml 长度:2147483646 参数方向:输入参数 *参数名称:testTEXT 参数类型:text 长度:2147483647 参数方向:输入参数 *参数名称:testVARCHAR 参数类型:varchar 长度:200 参数方向:输入参数 *参数名称:testOUTPUT_INT 参数类型:int 长度:非字符类型 参数方向:输出参数 *参数名称:testOUTPUT_BIT 参数类型:bit 长度:非字符类型 参数方向:输出参数 *参数名称:testOUTPUT_NVARCHAR 参数类型:nvarchar 长度:400 参数方向:输出参数 */ /** *存储过程名称:proc_paras_test *存储过程参数: *@param testBITINT 【参数名称:testBITINT 参数类型:bigint 对应java类型:long 长度:非字符类型 】 *@param testBINARY 【参数名称:testBINARY 参数类型:binary 对应java类型:Object 长度:非字符类型 】 *@param test1BIT 【参数名称:test1BIT 参数类型:bit 对应java类型:boolean 长度:非字符类型 】 *@param testCHAR 【参数名称:testCHAR 参数类型:char 对应java类型:String 长度:1 】 *@param testDATETIME 【参数名称:testDATETIME 参数类型:datetime 对应java类型:Date 长度:非字符类型 】 *@param testDECIMAL 【参数名称:testDECIMAL 参数类型:decimal 对应java类型:float 长度:非字符类型 】 *@param testFLOAT 【参数名称:testFLOAT 参数类型:float 对应java类型:double 长度:非字符类型 】 *@param testINT 【参数名称:testINT 参数类型:int 对应java类型:int 长度:非字符类型 】 *@param testMONEY 【参数名称:testMONEY 参数类型:money 对应java类型:float 长度:非字符类型 】 *@param testNCHAR 【参数名称:testNCHAR 参数类型:nchar 对应java类型:String 长度:2 】 *@param testNTEXT 【参数名称:testNTEXT 参数类型:ntext 对应java类型:String 长度:2147483646 】 *@param testNUMBERIC 【参数名称:testNUMBERIC 参数类型:numeric 对应java类型:Object 长度:非字符类型 】 *@param testNVARCHAR 【参数名称:testNVARCHAR 参数类型:nvarchar 对应java类型:String 长度:2 】 *@param testREAL 【参数名称:testREAL 参数类型:real 对应java类型:double 长度:非字符类型 】 *@param testSMALLDATETIME 【参数名称:testSMALLDATETIME 参数类型:smalldatetime 对应java类型:Date 长度:非字符类型 】 *@param testSMALLINT 【参数名称:testSMALLINT 参数类型:smallint 对应java类型:int 长度:非字符类型 】 *@param testSMALLMONEY 【参数名称:testSMALLMONEY 参数类型:smallmoney 对应java类型:Object 长度:非字符类型 】 *@param testTINYINT 【参数名称:testTINYINT 参数类型:tinyint 对应java类型:int 长度:非字符类型 】 *@param testXML 【参数名称:testXML 参数类型:xml 对应java类型:String 长度:2147483646 】 *@param testTEXT 【参数名称:testTEXT 参数类型:text 对应java类型:String 长度:2147483647 】 *@param testVARCHAR 【参数名称:testVARCHAR 参数类型:varchar 对应java类型:String 长度:200 】 * *@return DataTable对象。 */ public DataTable proc_paras_test( long testBITINT, Object testBINARY, boolean test1BIT, String testCHAR, Date testDATETIME, float testDECIMAL, double testFLOAT, int testINT, float testMONEY, String testNCHAR, String testNTEXT, Object testNUMBERIC, String testNVARCHAR, double testREAL, Date testSMALLDATETIME, int testSMALLINT, Object testSMALLMONEY, int testTINYINT, String testXML, String testTEXT, String testVARCHAR ){ /*注意: *由于java里面没有out int id 这种参数实现, *所以需要这里额外定义的output参数最好放入DataTable里面, *然后传给界面层使用*/ /*output参数定义*/ int testOUTPUT_INT = 0 ; boolean testOUTPUT_BIT = false ; String testOUTPUT_NVARCHAR = "" ; /*output参数定义结束*/ /*调用存储过程*/ DataTable res__datatable=new DataTable(); try{ Connection __myconn=DBConnection.getConnection(); CallableStatement _stmt=__myconn.prepareCall("{ call proc_paras_test( 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24)}"); _stmt.setLong(1,testBITINT); _stmt.setObject(2,testBINARY); _stmt.setBoolean(3,test1BIT); _stmt.setString(4,testCHAR); _stmt.setDate(5,new java.sql.Date(testDATETIME));//日期函数--注意,setDate必须为SqlDate的内容 _stmt.setFloat(6,testDECIMAL); _stmt.setDouble(7,testFLOAT); _stmt.setInt(8,testINT); _stmt.setFloat(9,testMONEY); _stmt.setString(10,testNCHAR); _stmt.setString(11,testNTEXT); _stmt.setObject(12,testNUMBERIC); _stmt.setString(13,testNVARCHAR); _stmt.setDouble(14,testREAL); _stmt.setDate(15,new java.sql.Date(testSMALLDATETIME));//日期函数--注意,setDate必须为SqlDate的内容 _stmt.setInt(16,testSMALLINT); _stmt.setObject(17,testSMALLMONEY); _stmt.setInt(18,testTINYINT); _stmt.setString(19,testXML); _stmt.setString(20,testTEXT); _stmt.setString(21,testVARCHAR); _stmt.registerOutParameter(22, 4,4); _stmt.registerOutParameter(23, -7,1); _stmt.registerOutParameter(24, -9,400); ResultSet __rslist =_stmt.executeQuery(); res__datatable=DataTableHelper.rs2datatable(__rslist); /*取回参数*/ testOUTPUT_INT=_stmt.getInt(22); testOUTPUT_BIT=_stmt.getBoolean(23); testOUTPUT_NVARCHAR=_stmt.getString(24); /*释放资源*/ __rslist.close(); _stmt.close(); } catch (Exception __e){ __e.printStackTrace(); } return res_datatable; } }
相关文章推荐
- 根据存储过程名字生成ADO.NET数据库访问代码
- 使用系统表根据存储过程名字生成ADO.NET数据库访问代码
- 使用系统表根据存储过程名字生成ADO.NET数据库访问代码
- 使用系统表根据存储过程名字生成ADO.NET数据库访问代码
- 根据存储过程名字生成ADO.NET数据库访问代码
- 【代码生成】生成数据库下某个存储过程的访问代码
- 数据库分页存储过程代码
- 生成sql server 数据库 脚本的 存储过程和调用
- ASP 调用带返回参数和记录集的存储过程二次访问数据库服务器的解决办法
- Asp.Net访问Oracle 数据库 执行SQL语句和调用存储过程
- 将数据库表中的数据生成Insert脚本的存储过程!!!
- 关于codesmith的一点使用--自动生成数据库中所有表的存储过程使用模板
- 刚才我提出要把数据库处理部分放到代码里,但是有人提出,存储过程有缓存,速度快。我该怎么说啊?
- 将数据库表中的数据生成Insert脚本的存储过程(改版)
- 数据库分页存储过程代码
- 刚才我提出要把数据库处理部分放到代码里,但是有人提出,存储过程有缓存,速度快。我该怎么说啊?
- 几个收藏的根据数据库生成Insert语句的存储过程[修正版]
- 将数据库表中数据生成Insert SQL语气的存储过程
- ORM存储过程和实体类代码生成工具
- SQLServer 生成还原数据库脚本的存储过程!