2006年8月24日

          利用回調簡化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 閱讀(341) | 評論 (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 閱讀(272) | 評論 (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 閱讀(947) | 評論 (3)編輯 收藏
           
          主站蜘蛛池模板: 金塔县| 麻阳| 清徐县| 辽宁省| 厦门市| 卢湾区| 邻水| 西青区| 洛宁县| 潢川县| 乌鲁木齐县| 叙永县| 大理市| 黎平县| 修文县| 台前县| 天台县| 柳林县| 东乡族自治县| 潞城市| 四川省| 龙游县| 克拉玛依市| 开远市| 遂昌县| 张掖市| 临沂市| 台中市| 新余市| 会理县| 新河县| 遂川县| 从江县| 广平县| 潢川县| 宜章县| 蓝山县| 方城县| 东兰县| 德庆县| 龙陵县|