2006年6月2日

利用回调简化JDBC编程

简单看了一下spring 的jdbc支持,现在又要直接用到jdbc,想想就是痛苦。于是参考了spring,自己写了一些简单的java封装类来简化编程。


废话少说,我这里就用代码来代言吧,看看怎样简化我们的JDBC编程,可以和以前进行对比。


(1) JdbcTemplate。

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;


import javax.sql.DataSource;


import org.winter.util.DBUtil;


/**
 * a simple JDBC template 模仿spring的JdbcTemplate
 *
 * @author bluestone
 * @version 1.0 2006-8-8
 *
 */
public class JdbcTemplate {


 private DataSource dataSource = null;


 public JdbcTemplate(DataSource ds) {
  this.dataSource = ds;
 }


/**
  * 执行更新操作
  *
  * @param sql
  * @param setter
  * @return
  * @throws SQLException
  */
 public int update(String sql, PreparedStatementSetter setter)
   throws SQLException {
  Connection conn = null;
  reparedStatement ps = null;
  try {
   conn = dataSource.getConnection();
   ps = conn.prepareStatement(sql);
   setter.setValues(ps);
   return ps.executeUpdate();
  } finally {
   DBUtil.colseConnection(conn, ps, null);
  }
 }


 /**
  *
  * @param sql
  * @return
  * @throws SQLException
  */
 public boolean execute(String sql) throws SQLException {
  Connection conn = null;
  Statement stmt = null;
  try {
   conn = dataSource.getConnection();
   stmt = conn.createStatement();
   return stmt.execute(sql);
  } finally {
   DBUtil.colseConnection(conn, stmt, null);
  }
 }


 /**
  *
  * @param sql
  * @param setter
  * @param extractor
  * @return
  * @throws SQLException
  */
 public Object query(String sql, PreparedStatementSetter setter,
   ResultSetExtractor extractor) throws SQLException {
  Connection conn = null;
  reparedStatement ps = null;
  ResultSet rs = null;
  try {
   conn = dataSource.getConnection();
   ps = conn.prepareStatement(sql);
   setter.setValues(ps);
   rs = ps.executeQuery();
   return extractor.extractData(rs);
  } finally {
   DBUtil.colseConnection(conn, ps, rs);
  }
 }


 // .........................
}


(2)  PreparedStatementSetter


public interface PreparedStatementSetter {
 void setValues(PreparedStatement ps) throws SQLException;
}


(3)  ResultSetExtractor


public interface ResultSetExtractor {
 Object extractData(ResultSet rs) throws SQLException;
}



(4) 可以参考spring自己定义其他接口。。。


用了这些辅助类,我们就可以像用spring那样编程了(当然这只能用在对事务要求不高的应用环境中)。看看怎么使用:



 private JdbcTemplate template;


 public JobManageDao() throws BusinessException {
  try {
   template = new JdbcTemplate(DBHelper.getDataSource());
  } catch (NamingException e) {
   throw new BusinessException(e);
  }
 }


public long saveJobInfo(final JobInfo info) throws BusinessException {
  final long id = IdGenerator.getIdLong();
  try {
   int j = template.update(INSERT_JOB_SQL, new PreparedStatementSetter() {


  public void setValues(PreparedStatement ps) throws SQLException {
     int i = 1;
     ps.setLong(i++, id);


   //......


   }
   });
      return j > 0 ? id : 0L;
  } catch (SQLException e) {
      throw new BusinessException(e);
  }
 }

posted @ 2006-08-24 12:38 bluestone 阅读(334) | 评论 (0)编辑 收藏
 
web开发经常遇到这样的情形:写代码的模式基本相同,特别是在写jdbc代码时,会经常要先写sql,然后调用PreparedStatement的setXXX方法,而读取数据时要调用ResultSet的getXXX方法。如果表中的字段很多,那可够你受的了;等你耐心把这些写完,可能在某个地方却出错了。

        如果没有用ORM工具,这些又不能省了不写。于是我考虑用代码来生成这些sql 和 setXXX及getXXX方法。

        生成代码有许多方法,比如可以用脚本语言(个人喜欢用perl),也可以用模板技术。发现java里面已经有很多模板技术可以直接使用了,比如velocity、freemaker等。我一开始是直接用perl来生成代码的,方法比较原始,就是字符串拼凑在一起。 后来发现有许多的模板技术可以利用。现在打算用velocity来生成代码。说不定可以直接生成DAO、Biz、Bean、XML等一大堆东西,呵呵。等有空要好好研究一下。

posted @ 2006-08-24 12:37 bluestone 阅读(265) | 评论 (1)编辑 收藏
 
在jsp页面,一个表单如果字段很多的话,要写很多request.getParameter(name)之类的代码,如果用web framework的话,则可以免去写这些代码的麻烦。但如果不用framework是否也可以达到参数自动填充的功能呢? 答案是肯定的。

    下面是我在就业网重构时用到的一个java类,其中就是对BeanUtils进行了简单的封装。

   import java.sql.Date;
   import java.util.Map;


   import org.apache.commons.beanutils.BeanUtils;
   import org.apache.commons.beanutils.ConvertUtils;
   import org.apache.commons.beanutils.converters.SqlDateConverter;

   public class NullSafeBeanUtils {
  

   public final static String EMPTY_STRING = "";
 
   public static boolean isNull(Object obj) {
       return obj == null;
   }

   public static String getProperty(Object bean, String property) {
       if (bean == null) {
            return EMPTY_STRING;
       }
     try {
          String str = BeanUtils.getProperty(bean, property);
          if (str == null) {
              return EMPTY_STRING;
         }
        return str;
     } catch (Exception e) {
         return EMPTY_STRING;
   }
  }

  public static void populate(Object bean, Map props) {
     if (bean == null) {
        return;
     }
    try {
     SqlDateConverter con = new SqlDateConverter(new Date(System.currentTimeMillis()));
      ConvertUtils.register(con, java.sql.Date.class);
      BeanUtils.populate(bean, props);
   } catch (Exception e) {
     e.printStackTrace();
   }
 }
 // 此处省略了一些其他代码
 }


 


    在这里,poplulate方法就是我用来自动填充参数的。要实现自动填充,只需简单调用此方法就行了。看一个例子:


    JobExperience jobExp = new JobExperience();

    NullSafeBeanUtils.populate(jobExp, request.getParameterMap());


   是不是简单了许多?要注意的是表单的各输入字段名要和bean的各属性名对应才能自动填充。另外NullSafeBeanUtils 的getProperty方法也很有用,可以避免写

   if (bean != null) {

      yyy = bean.getXXX()==null?"":bean.getXXX()

   }

   这样的代码,直接写NullSafeBeanUtils.getProperty(bean, "XXX")就可以了。

posted @ 2006-08-24 12:35 bluestone 阅读(937) | 评论 (3)编辑 收藏
 

UNIQ(1)    User Commands         UNIQ(1)

 

NAME
       uniq - remove duplicate lines from a sorted file
SYNOPSIS
       uniq [OPTION]... [INPUT [OUTPUT]]

DESCRIPTION
       Discard all but one of successive identical lines from INPUT (or stan-
       dard input), writing to OUTPUT (or standard output).

       Mandatory arguments to long options are mandatory  for  short  options
       too.

       -c, --count
       prefix lines by the number of occurrences

       -d, --repeated
       only print duplicate lines

       -D, --all-repeated[=delimit-method] print all duplicate lines
       delimit-method={none(default),prepend,separate}  Delimiting  is
       done with blank lines.

       -f, --skip-fields=N
       avoid comparing the first N fields

       -i, --ignore-case
       ignore differences in case when comparing

       -s, --skip-chars=N
       avoid comparing the first N characters

       -u, --unique
       only print unique lines

       -w, --check-chars=N
       compare no more than N characters in lines

       --help display this help and exit

       --version
       output version information and exit

       A field is  a  run  of  whitespace,  then  non-whitespace  characters.
       Fields are skipped before chars.

AUTHOR
       Written by Richard Stallman and David MacKenzie.

REPORTING BUGS
       Report bugs to <bug-coreutils@gnu.org>.

COPYRIGHT
       Copyright © 2004 Free Software Foundation, Inc.
       This  is  free software; see the source for copying conditions. There
       is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICU-
       LAR PURPOSE.

SEE ALSO
       The full documentation for uniq is maintained as a Texinfo manual.  If
       the info and uniq programs are properly installed at  your  site,  the
       command

       info coreutils uniq

       should give you access to the complete manual.

posted @ 2006-06-02 13:46 bluestone 阅读(190) | 评论 (0)编辑 收藏