`
kevin_wanwei
  • 浏览: 117676 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

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
0
分享到:
评论
2 楼 zhangskills 2010-02-20  
没想到也有人这么想的,我也写了一个类似的,一直怕别人笑我的思路,今天也发上来,有空指点指点,呵呵
1 楼 lshaohe 2010-02-04  
恩,不錯,學習了

相关推荐

    Spring笔记之整合JdbcTemplate.doc

    &lt;version&gt;1.2&lt;/version&gt; ``` **4.2 正常搭建Struts2框架** 在`web.xml`文件中配置Struts2过滤器: ```xml &lt;filter-name&gt;struts2 &lt;filter-class&gt;org.apache.struts2.dispatcher.ng.filter....

    玩转模板--自动代码生成工程

    1.2 以single.为前缀的参数(可设定设定多个),可在模板中直接调用输出 例如: single.name=xixi 模版调用: $name 输出:xixi 1.3 无任何前缀的参数,为工程要强制使用的参数,必须填写 2. 封装数据库表参数,目前只...

    SpringBoot快速入门.zip

    &lt;version&gt;1.2&lt;/version&gt; ``` 2. 然后,由于SpringBoot默认使用的是Whitelabel错误页,所以你需要自定义错误页处理器,以支持JSP错误页面。创建一个名为`ErrorController`的控制器类,并重写`error`方法,返回JSP...

    mybatis学习笔记LBY.pdf

    - **SQL 语句易于管理和维护**:将 SQL 语句放在 XML 文件中,便于集中管理,并且可以使用模板引擎进行动态 SQL 的生成。 - **高度灵活**:Mybatis 支持动态 SQL,可以根据条件生成不同的 SQL 语句,满足复杂的需求...

    JasperReport+IReport开发Java报表入门级教程.pdf

    验证方法:打开命令行窗口,输入 `java -version`,如果能看到 Java 版本信息,则说明配置成功。 ###### 1.2.2 下载 iReport iReport 可以从其官方网站免费下载。选择版本 0.3.2,解压后双击 `iReport.bat` 文件,...

    IReport报表开发教程

    - **验证:** 在命令行输入`java -version`查看是否正确安装 **1.2.2 下载iReport** - **地址:** [iReport官方网站](http://ireport.sourceforge.net/) - **版本:** 0.3.2 (推荐) - **安装:** 解压缩至任意目录 - **...

    cms后台管理

    可以找到类DynamicPageAct,此类是首页模板。 在类DynamicPageAct中有 public static final String TPL_INDEX = "tpl.index"; 找到WEB-INF\languages\jeecms_front下messages_zh_CN.properties配置文件,可以找到...

    ssh(structs,spring,hibernate)框架中的上传下载

    对于那些仅封装了Connection而未包括Statement的简单数据连接池,SimpleNativeJdbcExtractor是效率最高的抽取器实现类,但具体到apache的BasicDataSource连接池,它封装了所有JDBC的对象,这时就需要使用...

    hibernate 帮助文档

    - **视图渲染**:使用JSP或其他模板引擎来渲染页面。 **1.3.3 部署与测试** - **应用部署**:将应用部署到Web服务器上。 - **功能测试**:测试应用的各项功能是否正常。 **1.4 总结** - **学习成果**:回顾本...

    测试培训教材

    The VAPI-XP testing tool enables you to create new testing scripts using Microsoft VBScript, Microsoft JavaScript (JScript version), PerlScript, and PythonScript, and integrate these scripts into your...

Global site tag (gtag.js) - Google Analytics