首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 数据库 > 其他数据库 >

JDBC模板种(version 1.2)

2012-10-27 
JDBC模板类(version 1.2)1.2版本中添加了一个新插入的方法: /*** 在Web开发中struts框架中,页数数据在被存

JDBC模板类(version 1.2)

1.2版本中添加了一个新插入的方法: /**  * 在Web开发中struts框架中,页数数据在被存入数据库时会被包装在一个formbean对象中  * 在把这些数据存入数据库时,需要把formbean中值取出来,在插入数据库中这样很麻烦  * 所以我设计了这个方法,只需要一个sql语句(sql语句字段名必须和数据库中的完全一致,字段顺序可以随便)  * 和一个封装好数据对象。  * 这个方法对页面数据提交在存入数据库,有很大方便。  * 在这里插入主键时,主键值也应当包含那个封装对象中  * 思想:主要是对sql语句进行分析,解析出要插入字段名称,在利用反射技术将值set到preparedStatement对象中。  * @param sql 数据库插入 sql语句  * @param obj 已经封装好数据对象  * @return 新增成功记录数  * @throws Exception  */ public int insert(String sql, Object obj) throws Exception {  if(obj==null){   return 0;  }  Connection conn=null;  PreparedStatement ps=null;  ResultSet rs=null;  String [] fieldNames=resolveSQL(sql);  try {   conn=jdbcUtil.getConnection();   ps=jdbcUtil.scrollReadOnlyResultSet(sql,conn);   for(int i=0;i<fieldNames.length;i++){    Object o=valueFromObject(fieldNames[i],obj);    PreparedStatementSetValue(ps,o,i+1);   }   return ps.executeUpdate();  }finally{   jdbcUtil.free(rs,ps,conn);  }   }

?

=================================================================

package daoUtil.daoTemplate;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;import java.sql.Connection;import java.sql.PreparedStatement;import java.sql.ResultSet;import java.sql.SQLException;import java.util.ArrayList;import java.util.Collection;import jdbcUtil.JdbcUtil;import daoUtil.PrimaryKeyer;import daoUtil.RowMapper;/** * 在写jdbc程序是可以清楚的知道 * 在程序中只有sql语句和其参数值是变化 * 其余程序代码几乎类似(获得连接,关闭连接) * 在这里我对以前所写jdbc程序进行了一下改进 * 将获得连接和关闭连接的程序代码交给一个模板类去做 * 再写jdbc程序时,调用模板类中相应的方法,传入sql语句和其参数值 * 这样大大简化jdbc程序,给我们带来方便 * 程序新版本往后日子会不断更新,渴望javaeye里面高手多多给我指点 * @author kevin.wangwei * Email:wanwei.234@163.com * 2010-1-30 */public class DAOTemplate{ /**jdbc工具类*/ private JdbcUtil jdbcUtil=JdbcUtil.getInstance(); /**  * 数据库删除操作  * @param sql 删除操作sql语句  * @param args 删除操作sql语句参数值数组  * @return 删除记录条数  * @throws SQLException  */ public  int delete(String sql, Object[] args) throws SQLException {  if(args==null||args.length==0){   return 0;  }  Connection conn=null;  PreparedStatement ps=null;  ResultSet rs=null;  try {   conn=jdbcUtil.getConnection();   ps=jdbcUtil.scrollReadOnlyResultSet(sql,conn);   for(int i=0;i<args.length;i++){    ps.setObject(i+1,args[i]);//在这里我们应该调用下面的PreparedStatementSetValue方法,                              //不过这样写亦可以,但它不可以处理null值   }   return ps.executeUpdate();  }finally{   jdbcUtil.free(rs,ps,conn);  } } /**  * 数据库更新操作  * @param sql 更新操作sql语句  * @param args sql语句参数值数组  * @return 更新记录条数  * @throws SQLException  */ public int update(String sql, Object[] args) throws SQLException {  if(args==null||args.length==0){   return 0;  }  Connection conn=null;  PreparedStatement ps=null;  ResultSet rs=null;  try {   conn=jdbcUtil.getConnection();   ps=jdbcUtil.scrollReadOnlyResultSet(sql,conn);   for(int i=0;i<args.length;i++){    ps.setObject(i+1,args[i]);   }   return ps.executeUpdate();  }finally{   jdbcUtil.free(rs,ps,conn);  } } /**  * 数据库查询操作 采用反射来给包装sql语句参数赋值  * @param sql 查询操作sql语句  * @param args 删除操作sql语句数组数值  * @return 结果对象  * @throws SQLException  */ public Object find(String sql, Object[] args,RowMapper rowMapper) throws SQLException {  if(args==null||args.length==0){   return 0;  }  Connection conn=null;  PreparedStatement ps=null;  ResultSet rs=null;  try {   conn=jdbcUtil.getConnection();   ps=jdbcUtil.scrollReadOnlyResultSet(sql,conn);   for(int i=0;i<args.length;i++){    try {     PreparedStatementSetValue(ps,args[i],i+1);    } catch (Exception e) {     e.printStackTrace();    }   }   rs=ps.executeQuery();   Object obj=null;   while(rs.next()){    obj=rowMapper.rowMapping(rs);   }   return obj;  }finally{   jdbcUtil.free(rs,ps,conn);  } } /**  * 获得表中记录数  * @param sql sql语句  * @param args 参数数组  * @return 表中记录数  * @throws SQLException  */ public int getRecordCount(String sql, Object[] args) throws SQLException {  if(args==null||args.length==0){   return 0;  }  int count=0;  Connection conn=null;  PreparedStatement ps=null;  ResultSet rs=null;  try {   conn=jdbcUtil.getConnection();   ps=jdbcUtil.scrollReadOnlyResultSet(sql,conn);   for(int i=0;i<args.length;i++){    ps.setObject(i+1,args[i]);   }   rs=ps.executeQuery();   if(rs.next()){    count=rs.getInt(1);   }  }finally{   jdbcUtil.free(rs,ps,conn);  }  return count; } /**  * 根据数据库表名,找到该表中所有记录数  * @param tableName 要查询的表  * @return 表中记录数  * @throws SQLException  */ public int getRecordCount(String tableName) throws SQLException {  if(tableName==null||tableName.equals("")){   return 0;  }  int count=0;  Connection conn=null;  PreparedStatement ps=null;  ResultSet rs=null;  try {   conn=jdbcUtil.getConnection();   String sql="select count(*) from "+tableName;   ps=jdbcUtil.scrollReadOnlyResultSet(sql,conn);   if(rs.next()){    count=rs.getInt(1);   }  }finally{   jdbcUtil.free(rs,ps,conn);  }  return count; } /**  * 数据库插入操作(这是采用接口回调技术,由调用程序来给主键赋值)  * @param sql 插入操作 sql语句  * @param args 插入数  * @param primaryIndex 主键在sql语句中位置(小于-1表示用数据自动生成主键不需要插入)  * @return 插入记录数  * @throws Exception   */ public int insert(String sql, Object[] args, int primaryKeyIndex,PrimaryKeyer primaryKeyer) throws Exception {  if(args==null||args.length==0){   return 0;  }  Connection conn=null;  PreparedStatement ps=null;  ResultSet rs=null;  try {   conn=jdbcUtil.getConnection();   ps=jdbcUtil.scrollReadOnlyResultSet(sql,conn);   if(primaryKeyIndex<=-1){    for(int i=0;i<args.length;i++){     try {      PreparedStatementSetValue(ps,args[i],i+1);     } catch (Exception e) {      e.printStackTrace();     }    }   }else if(primaryKeyIndex>-1&&primaryKeyIndex<args.length){    for(int i=0;i<args.length;i++){     if(i==primaryKeyIndex){      PreparedStatementSetValue(ps,primaryKeyer.getPrimaryKey(),i+1);      //ps.setObject(i+1,primaryKeyer.getPrimaryKey());     }else{      PreparedStatementSetValue(ps,args[i],i+1);     }    }   }else{    throw new IllegalArgumentException("设置主键位置不正确!");   }   return ps.executeUpdate();  }finally{   jdbcUtil.free(rs,ps,conn);  } } /**  * 在Web开发中struts框架中,页数数据在被存入数据库时会被包装在一个formbean对象中  * 在把这些数据存入数据库时,需要把formbean中值取出来,在插入数据库中这样很麻烦  * 所以我设计了这个方法,只需要一个sql语句(sql语句字段名必须和数据库中的完全一致,字段顺序可以随便)  * 和一个封装好数据对象。  * 这个方法对页面数据提交在存入数据库,有很大方便。  * 在这里插入主键时,主键值也应当包含那个封装对象中  * 思想:主要是对sql语句进行分析,解析出要插入字段名称,在利用反射技术将值set到preparedStatement对象中。  * @param sql  * @param obj  * @return  * @throws Exception  */ public int insert(String sql, Object obj) throws Exception {  if(obj==null){   return 0;  }  Connection conn=null;  PreparedStatement ps=null;  ResultSet rs=null;  String [] fieldNames=resolveSQL(sql);  try {   conn=jdbcUtil.getConnection();   ps=jdbcUtil.scrollReadOnlyResultSet(sql,conn);   for(int i=0;i<fieldNames.length;i++){    Object o=valueFromObject(fieldNames[i],obj);    PreparedStatementSetValue(ps,o,i+1);   }   return ps.executeUpdate();  }finally{   jdbcUtil.free(rs,ps,conn);  }   } /**  * 查找符合条件所有记录(这也是采用接口回调技术,由调用程序来决定结果set到什么对象中)  * @param sql 查询sql语句  * @param args 查询参数  * @param rowMapper 结果集映射器  * @return Collection 记录集  * @throws SQLException  */  public Collection ObjectList(String sql, Object[] args,RowMapper rowMapper) throws SQLException {  if(args==null||args.length==0){   return null;  }  Connection conn=null;  PreparedStatement ps=null;  ResultSet rs=null;  Collection list=null;  try {   conn=jdbcUtil.getConnection();   ps=jdbcUtil.scrollReadOnlyResultSet(sql,conn);   for(int i=0;i<args.length;i++){    ps.setObject(i+1,args[i]);   }   list=new ArrayList();   rs=ps.executeQuery();   while(rs.next()){    Object obj=rowMapper.rowMapping(rs);    list.add(obj);   }  }finally{   jdbcUtil.free(rs,ps,conn);  }  return list; } /**  * 依据与表对应的JavaBean的Class(采用反射技术将结果集set到JavaBean对象中)  * 将查询结果封装为一个JavaBean的对象返回  * @param sql 查询sql语句  * @param args 查询参数  * @param javaBeanClass JavaBean的Class  * @return 返回获得JavaBean对象  * @throws Exception  */ public Object find(String sql, Object[] args,Class javaBeanClass) throws Exception {  if(args==null||args.length==0){   return 0;  }  Connection conn=null;  PreparedStatement ps=null;  ResultSet rs=null;  try {   conn=jdbcUtil.getConnection();   ps=jdbcUtil.scrollReadOnlyResultSet(sql,conn);   for(int i=0;i<args.length;i++){    ps.setObject(i+1,args[i]);   }   rs=ps.executeQuery();   String[] names=jdbcUtil.getResultSetFieldName(rs);   Object obj=null;   while(rs.next()){    obj=rowMapper(javaBeanClass,rs,names);   }   return obj;  }finally{   jdbcUtil.free(rs,ps,conn);  } }  /**  * 依据与表对应的JavaBean的Class(上面方法重载方法,采用了不同实现机制)  * 将查询结果封装为一个包含JavaBean的集合对象返回  * @param sql 查询sql语句  * @param args 查询参数  * @param javaBeanClass javaBeanClass JavaBean的Class  * @return 记录集  * @throws Exception  */ public Collection ObjectList(String sql, Object[] args,Class javaBeanClass) throws Exception {  if(args==null||args.length==0){   return null;  }  Connection conn=null;  PreparedStatement ps=null;  ResultSet rs=null;  Collection list=null;  try {   conn=jdbcUtil.getConnection();   ps=jdbcUtil.scrollReadOnlyResultSet(sql,conn);   for(int i=0;i<args.length;i++){    ps.setObject(i+1,args[i]);   }   list=new ArrayList();   rs=ps.executeQuery();   String[] names=jdbcUtil.getResultSetFieldName(rs);   while(rs.next()){    Object obj=rowMapper(javaBeanClass,rs,names);    list.add(obj);   }  }finally{   jdbcUtil.free(rs,ps,conn);  }  return list; } /**  * 这个方法是通过反射来将数据库表中对应的javaBean对象set值  * 该JavaBean对象必须有一个无参数的构造函数  * @param clazz javabean 超类  * @param rs 数据库结果集  * @return Object 对象  * @throws Exception  */ private Object rowMapper(Class clazz,ResultSet rs,String[] names) throws Exception{  Object obj=clazz.newInstance();  for(int i=0;i<names.length;i++){   String columnName=toUpperCaseFirstLetterForSet(names[i]);   Method[] m=clazz.getMethods();      for(int j=0;j<m.length;j++){    String methodName=m[j].getName();    if(columnName.equals(methodName)){     m[j].invoke(obj,rs.getObject(i+1));     break;    }   }  }  return obj; } /**  * 将字符串一个字母转换为大写  * @param name  * @return  */ private String toUpperCaseFirstLetterForSet(String name){  if(name!=null&&name.length()>0){   return "set"+name.substring(0,1).toUpperCase()+name.substring(1);  }  return ""; } /**  * 这是采用反射的方法来给PreparedStatement包装sql 语句参数赋值  * @param ps   * @param obj 数组中对象  * @param index 参数索引位置  * @throws Exception  */ private void PreparedStatementSetValue(PreparedStatement ps,Object obj,int index) throws Exception{  String name=getMethodName(obj);  Method[] m=ps.getClass().getMethods();  for(int i=0;i<m.length;i++){   String methodName=m[i].getName();   if(name.equals(methodName)){    //System.out.println(methodName+"===========");    m[i].invoke(ps,index,obj);    break;   }  }   } /**  * 通过反射获得数组中每个元素类型,  * 从而获得PreparedStatement对象setxxx方法名称  * @param obj  sql语句参数值  * @return PreparedStatement对象要调用setxxx方法名称  */ private String getMethodName(Object obj){  if(obj==null){   return null;  }  //System.out.println(obj+"===========");  String className=obj.getClass().getName();  String[] names=className.split("\\.");  className=names[names.length-1];  if(className.equalsIgnoreCase("Integer")){   className="Int";  }  className="set"+className;  return className; } /**  * 从sql语句中解析出我们需要字段名称  * @param sql 必须是一个有效 sql插入语句(最好不要用别名)  * @return 字段名称数组  */ private String[] resolveSQL(String sql){  sql=sql.toLowerCase();  int left_brackets=sql.indexOf("(");  int right_brackets=sql.indexOf(")");  String fieldString=sql.substring(left_brackets+1,right_brackets);  String[] fieldNames=fieldString.split(",");  return fieldNames; } /**  * 根据字段名从包装数据对象中取出于该字段相对应的值  * 通过反射用get方法来获得  * @param fieldName  * @return  * @throws InvocationTargetException   * @throws IllegalAccessException   * @throws Exception   */ private Object valueFromObject(String fieldName,Object formBean) throws Exception{  String methodName=toUpperCaseFirstLetterForGet(fieldName);  Method[] methods=formBean.getClass().getMethods();  for(Method m:methods){   String mName=m.getName();   if(methodName.equals(mName)){     Object value=m.invoke(formBean);      return value;   }  }  return null; } /**  * 将字符串一个字母转换为大写  * @param name  * @return  */ private String toUpperCaseFirstLetterForGet(String name){  if(name!=null&&name.length()>0){   name=name.trim();   return "get"+name.substring(0,1).toUpperCase()+name.substring(1);  }  return ""; }}

?

2 楼 zhangskills 2010-02-20   没想到也有人这么想的,我也写了一个类似的,一直怕别人笑我的思路,今天也发上来,有空指点指点,呵呵

热点排行