DAO模式的例子

Code:
  1. 虽然DAO模式已经有了好多的成熟的框架,但它仍然是一个比较重要的设计模式。要做一个比较合理的DAO模式,你需要对工厂模式、单例模式、模板模式、策略模式、代理模式、泛型、反射机制、输入输出、异常等知识比较熟悉。下面结合自己理解,设计一个DAO设计模式的例子,希望大家给与指正。   
  2.   
  3. 1、数据库连接池的工具类。   
  4.   
  5.      在数据库连接池的工具类中,采用了开源的DBCP数据库连接池,调用了DataSource接口,DBCP中关于Datasource的Connection采用了动态代理的方式实现,在这里只是提出,感兴趣可以查看其源码,该工具类采用可配置的方式实现的,代码如下:   
  6.   
  7.     
  8.   
  9. Java代码    
  10. package com.cvicse.utils;      
  11.      
  12. import java.io.InputStream;      
  13. import java.sql.Connection;      
  14. import java.sql.ResultSet;      
  15. import java.sql.SQLException;      
  16. import java.sql.Statement;      
  17. import java.util.Properties;      
  18.      
  19. import javax.sql.DataSource;      
  20.      
  21. import org.apache.commons.dbcp.BasicDataSourceFactory;      
  22.      
  23. /**    
  24.  * 数据库连接池操作工具类    
  25.  *     
  26.  */     
  27. public class JDBCUtils {      
  28.     private static DataSource myDataSource = null;      
  29.     private JDBCUtils() {      
  30.     }      
  31.      
  32.     static {      
  33.         try {      
  34.             Properties prop = new Properties();      
  35. //采用了类的加载获取路径下数据库的配置信息      
  36.             InputStream is = JDBCUtils.class.getClassLoader()      
  37.                     .getResourceAsStream("dbcpconfig.properties");      
  38.             prop.load(is);      
  39.             myDataSource = BasicDataSourceFactory.createDataSource(prop);      
  40.         } catch (Exception e) {      
  41.             throw new ExceptionInInitializerError(e);      
  42.         }      
  43.     }      
  44.      
  45.     /**    
  46.      * 获取数据源    
  47.      *     
  48.      * @return    
  49.      */     
  50.     public static DataSource getDataSource() {      
  51.         return myDataSource;      
  52.     }      
  53.      
  54.     /**    
  55.      * 获取连接    
  56.      *     
  57.      * @return    
  58.      * @throws SQLException    
  59.      */     
  60.     public static Connection getConnection() throws SQLException {      
  61.         return myDataSource.getConnection();      
  62.     }      
  63.      
  64.     /**    
  65.      * 关闭资源    
  66.      * @param rs    
  67.      * @param st    
  68.      * @param conn    
  69.      * @throws SQLException    
  70.      */     
  71.     public static void free(ResultSet rs, Statement st, Connection conn)      
  72.             throws SQLException {      
  73.         try {      
  74.             if (rs != null)      
  75.                 rs.close();      
  76.         } catch (SQLException e) {      
  77.             throw new SQLException();      
  78.         } finally {      
  79.             try {      
  80.                 if (st != null)      
  81.                     st.close();      
  82.             } catch (SQLException e) {      
  83.                 throw new SQLException();      
  84.             } finally {      
  85.                 if (conn != null)      
  86.                     try {      
  87.                         conn.close();      
  88.                     } catch (Exception e) {      
  89.                         throw new SQLException();      
  90.                     }      
  91.             }      
  92.         }      
  93.     }      
  94. }     
  95.   
  96. package com.cvicse.utils;   
  97.   
  98. import java.io.InputStream;   
  99. import java.sql.Connection;   
  100. import java.sql.ResultSet;   
  101. import java.sql.SQLException;   
  102. import java.sql.Statement;   
  103. import java.util.Properties;   
  104.   
  105. import javax.sql.DataSource;   
  106.   
  107. import org.apache.commons.dbcp.BasicDataSourceFactory;   
  108.   
  109. /**  
  110.  * 数据库连接池操作工具类  
  111.  *   
  112.  */  
  113. public class JDBCUtils {   
  114.     private static DataSource myDataSource = null;   
  115.     private JDBCUtils() {   
  116.     }   
  117.   
  118.     static {   
  119.         try {   
  120.             Properties prop = new Properties();   
  121. //采用了类的加载获取路径下数据库的配置信息   
  122.             InputStream is = JDBCUtils.class.getClassLoader()   
  123.                     .getResourceAsStream("dbcpconfig.properties");   
  124.             prop.load(is);   
  125.             myDataSource = BasicDataSourceFactory.createDataSource(prop);   
  126.         } catch (Exception e) {   
  127.             throw new ExceptionInInitializerError(e);   
  128.         }   
  129.     }   
  130.   
  131.     /**  
  132.      * 获取数据源  
  133.      *   
  134.      * @return  
  135.      */  
  136.     public static DataSource getDataSource() {   
  137.         return myDataSource;   
  138.     }   
  139.   
  140.     /**  
  141.      * 获取连接  
  142.      *   
  143.      * @return  
  144.      * @throws SQLException  
  145.      */  
  146.     public static Connection getConnection() throws SQLException {   
  147.         return myDataSource.getConnection();   
  148.     }   
  149.   
  150.     /**  
  151.      * 关闭资源  
  152.      * @param rs  
  153.      * @param st  
  154.      * @param conn  
  155.      * @throws SQLException  
  156.      */  
  157.     public static void free(ResultSet rs, Statement st, Connection conn)   
  158.             throws SQLException {   
  159.         try {   
  160.             if (rs != null)   
  161.                 rs.close();   
  162.         } catch (SQLException e) {   
  163.             throw new SQLException();   
  164.         } finally {   
  165.             try {   
  166.                 if (st != null)   
  167.                     st.close();   
  168.             } catch (SQLException e) {   
  169.                 throw new SQLException();   
  170.             } finally {   
  171.                 if (conn != null)   
  172.                     try {   
  173.                         conn.close();   
  174.                     } catch (Exception e) {   
  175.                         throw new SQLException();   
  176.                     }   
  177.             }   
  178.         }   
  179.     }   
  180. }   
  181.  数据库配置文件的信息如下dbcpconfig.properties   
  182.   
  183. Java代码    
  184. #连接设置      
  185. driverClassName=com.mysql.jdbc.Driver      
  186. url=jdbc:mysql://localhost:3306/test123      
  187. username=root      
  188. password=      
  189.      
  190. #<!-- 初始化连接 -->      
  191. initialSize=10     
  192.      
  193. #最大连接数量      
  194. maxActive=50     
  195.      
  196. #<!-- 最大空闲连接 -->      
  197. maxIdle=20     
  198.      
  199. #<!-- 最小空闲连接 -->      
  200. minIdle=5     
  201.      
  202. #<!-- 超时等待时间以毫秒为单位 6000毫秒/1000等于60秒 -->      
  203. maxWait=60000     
  204.      
  205.      
  206. #JDBC驱动建立连接时附带的连接属性属性的格式必须为这样:[属性名=property;]       
  207. #注意:"user" 与 "password" 两个属性会被明确地传递,因此这里不需要包含他们。      
  208. connectionProperties=useUnicode=true;characterEncoding=UTF-8     
  209.      
  210. #指定由连接池所创建的连接的自动提交(auto-commit)状态。      
  211. defaultAutoCommit=true     
  212.      
  213. #driver default 指定由连接池所创建的连接的只读(read-only)状态。      
  214. #如果没有设置该值,则“setReadOnly”方法将不被调用。(某些驱动并不支持只读模式,如:Informix)      
  215. defaultReadOnly=      
  216.      
  217. #driver default 指定由连接池所创建的连接的事务级别(TransactionIsolation)。      
  218. #可用值为下列之一:(详情可见javadoc。)NONE,READ_UNCOMMITTED, READ_COMMITTED, REPEATABLE_READ, SERIALIZABLE      
  219. defaultTransactionIsolation=READ_UNCOMMITTED     
  220.   
  221. #连接设置   
  222. driverClassName=com.mysql.jdbc.Driver   
  223. url=jdbc:mysql://localhost:3306/test123   
  224. username=root   
  225. password=   
  226.   
  227. #<!-- 初始化连接 -->   
  228. initialSize=10  
  229.   
  230. #最大连接数量   
  231. maxActive=50  
  232.   
  233. #<!-- 最大空闲连接 -->   
  234. maxIdle=20  
  235.   
  236. #<!-- 最小空闲连接 -->   
  237. minIdle=5  
  238.   
  239. #<!-- 超时等待时间以毫秒为单位 6000毫秒/1000等于60秒 -->   
  240. maxWait=60000  
  241.   
  242.   
  243. #JDBC驱动建立连接时附带的连接属性属性的格式必须为这样:[属性名=property;]    
  244. #注意:"user" 与 "password" 两个属性会被明确地传递,因此这里不需要包含他们。   
  245. connectionProperties=useUnicode=true;characterEncoding=UTF-8  
  246.   
  247. #指定由连接池所创建的连接的自动提交(auto-commit)状态。   
  248. defaultAutoCommit=true  
  249.   
  250. #driver default 指定由连接池所创建的连接的只读(read-only)状态。   
  251. #如果没有设置该值,则“setReadOnly”方法将不被调用。(某些驱动并不支持只读模式,如:Informix)   
  252. defaultReadOnly=   
  253.   
  254. #driver default 指定由连接池所创建的连接的事务级别(TransactionIsolation)。   
  255. #可用值为下列之一:(详情可见javadoc。)NONE,READ_UNCOMMITTED, READ_COMMITTED, REPEATABLE_READ, SERIALIZABLE   
  256. defaultTransactionIsolation=READ_UNCOMMITTED 2、异常定义,用于处理DAO层的异常类,因为异常最好要在业务层进行处理,个人认为这DAO层异常应该在业务层进行处理,所以DAO层的必要异常都抛出。   
  257.   
  258. Java代码    
  259. package com.cvicse.dao.exception;      
  260.      
  261. /**    
  262.  *    
  263.  * 定义DAO异常类    
  264.  *    
  265.  */     
  266. public class DaoException extends Exception {      
  267.     private static final long serialVersionUID = 1L;      
  268.     /**    
  269.      * @param message    
  270.      * @param cause    
  271.      */     
  272.     public DaoException(String message, Throwable cause) {      
  273.         super(message, cause);      
  274.     }      
  275.     /**    
  276.      * @param message    
  277.      */     
  278.     public DaoException(String message) {      
  279.         super(message);      
  280.     }      
  281. }      
  282.      
  283. package com.cvicse.dao.exception;      
  284.      
  285.      
  286. /**    
  287.  * 传入参数错误异常    
  288.  *    
  289.  */     
  290. public class DaoParameterException extends DaoException {      
  291.     private static final long serialVersionUID = 1L;      
  292.      
  293.     /**    
  294.      * @param message    
  295.      * @param cause    
  296.      */     
  297.     public DaoParameterException(String message, Throwable cause) {      
  298.         super(message, cause);      
  299.     }      
  300.      
  301.     /**    
  302.      * @param message    
  303.      */     
  304.     public DaoParameterException(String message) {      
  305.         super(message);      
  306.     }      
  307.      
  308. }     
  309.   
  310. package com.cvicse.dao.exception;   
  311.   
  312. /**  
  313.  *  
  314.  * 定义DAO异常类  
  315.  *  
  316.  */  
  317. public class DaoException extends Exception {   
  318.     private static final long serialVersionUID = 1L;   
  319.     /**  
  320.      * @param message  
  321.      * @param cause  
  322.      */  
  323.     public DaoException(String message, Throwable cause) {   
  324.         super(message, cause);   
  325.     }   
  326.     /**  
  327.      * @param message  
  328.      */  
  329.     public DaoException(String message) {   
  330.         super(message);   
  331.     }   
  332. }   
  333.   
  334. package com.cvicse.dao.exception;   
  335.   
  336.   
  337. /**  
  338.  * 传入参数错误异常  
  339.  *  
  340.  */  
  341. public class DaoParameterException extends DaoException {   
  342.     private static final long serialVersionUID = 1L;   
  343.   
  344.     /**  
  345.      * @param message  
  346.      * @param cause  
  347.      */  
  348.     public DaoParameterException(String message, Throwable cause) {   
  349.         super(message, cause);   
  350.     }   
  351.   
  352.     /**  
  353.      * @param message  
  354.      */  
  355.     public DaoParameterException(String message) {   
  356.         super(message);   
  357.     }   
  358.   
  359. }    
  360.   
  361. 3、定义要操作的pojo类,这里定义了2个pojo类   
  362.   
  363. Java代码    
  364. package com.cvicse.po;      
  365.      
  366. /**    
  367.  * 课程持久层对象    
  368.  *    
  369.  */     
  370. public class Course {      
  371.     private long id;      
  372.     private String name;      
  373.     /**    
  374.      * 构造函数类    
  375.      */     
  376.     public Course() {      
  377.         this.id = 0;      
  378.         this.name = null;      
  379.     }      
  380.     /**    
  381.      * @param id    
  382.      * @param name    
  383.      */     
  384.     public Course(long id, String name) {      
  385.         this.id = id;      
  386.         this.name = name;      
  387.     }      
  388.      
  389.     /**    
  390.      * @return    
  391.      */     
  392.     public long getId() {      
  393.         return id;      
  394.     }      
  395.      
  396.     /**    
  397.      * @param id    
  398.      */     
  399.     public void setId(long id) {      
  400.         this.id = id;      
  401.     }      
  402.      
  403.     /**    
  404.      * @return    
  405.      */     
  406.     public String getName() {      
  407.         return name;      
  408.     }      
  409.      
  410.     /**    
  411.      * @param name    
  412.      */     
  413.     public void setName(String name) {      
  414.         this.name = name;      
  415.     }      
  416. }      
  417.      
  418. package com.cvicse.po;      
  419.      
  420. /**    
  421.  * 学生持久层对象    
  422.  */     
  423. public class Student {      
  424.     private long id;      
  425.      
  426.     private String name;      
  427.      
  428.     public Student() {      
  429.         this.id = 0;      
  430.         this.name = null;      
  431.     }      
  432.      
  433.     public Student(long id, String name) {      
  434.         this.id = id;      
  435.         this.name = name;      
  436.     }      
  437.      
  438.     public long getId() {      
  439.         return id;      
  440.     }      
  441.      
  442.     public void setId(long id) {      
  443.         this.id = id;      
  444.     }      
  445.      
  446.     public String getName() {      
  447.         return name;      
  448.     }      
  449.      
  450.     public void setName(String name) {      
  451.         this.name = name;      
  452.     }      
  453. }     
  454.   
  455. package com.cvicse.po;   
  456.   
  457. /**  
  458.  * 课程持久层对象  
  459.  *  
  460.  */  
  461. public class Course {   
  462.     private long id;   
  463.     private String name;   
  464.     /**  
  465.      * 构造函数类  
  466.      */  
  467.     public Course() {   
  468.         this.id = 0;   
  469.         this.name = null;   
  470.     }   
  471.     /**  
  472.      * @param id  
  473.      * @param name  
  474.      */  
  475.     public Course(long id, String name) {   
  476.         this.id = id;   
  477.         this.name = name;   
  478.     }   
  479.   
  480.     /**  
  481.      * @return  
  482.      */  
  483.     public long getId() {   
  484.         return id;   
  485.     }   
  486.   
  487.     /**  
  488.      * @param id  
  489.      */  
  490.     public void setId(long id) {   
  491.         this.id = id;   
  492.     }   
  493.   
  494.     /**  
  495.      * @return  
  496.      */  
  497.     public String getName() {   
  498.         return name;   
  499.     }   
  500.   
  501.     /**  
  502.      * @param name  
  503.      */  
  504.     public void setName(String name) {   
  505.         this.name = name;   
  506.     }   
  507. }   
  508.   
  509. package com.cvicse.po;   
  510.   
  511. /**  
  512.  * 学生持久层对象  
  513.  */  
  514. public class Student {   
  515.     private long id;   
  516.   
  517.     private String name;   
  518.   
  519.     public Student() {   
  520.         this.id = 0;   
  521.         this.name = null;   
  522.     }   
  523.   
  524.     public Student(long id, String name) {   
  525.         this.id = id;   
  526.         this.name = name;   
  527.     }   
  528.   
  529.     public long getId() {   
  530.         return id;   
  531.     }   
  532.   
  533.     public void setId(long id) {   
  534.         this.id = id;   
  535.     }   
  536.   
  537.     public String getName() {   
  538.         return name;   
  539.     }   
  540.   
  541.     public void setName(String name) {   
  542.         this.name = name;   
  543.     }   
  544. }   
  545.     
  546.   
  547. 4、定义对象操作的DAO接口,因为面向接口编程,定义接口目的是DAO层的操作能和业务层解耦。   
  548.   
  549. Java代码    
  550. package com.cvicse.dao;      
  551.      
  552. import java.util.List;      
  553.      
  554. import com.cvicse.dao.exception.DaoException;      
  555. import com.cvicse.po.Course;      
  556.      
  557. /**    
  558.  * 课程DAO层接口    
  559.  *    
  560.  */     
  561. public interface CourseDAO {      
  562.          
  563.     /**    
  564.      * 获取列表    
  565.      * @return    
  566.      * @throws DaoException    
  567.      */     
  568.     public List<Course> selectCourses() throws DaoException;      
  569.      
  570.     /**    
  571.      * 插入记录    
  572.      * @param course    
  573.      * @throws DaoException    
  574.      */     
  575.     public void insertCourse(Course course) throws DaoException;      
  576. }      
  577.      
  578. package com.cvicse.dao;      
  579.      
  580. import java.util.List;      
  581.      
  582. import com.cvicse.dao.exception.DaoException;      
  583. import com.cvicse.po.Student;      
  584.      
  585. public interface StudentDAO {      
  586.      
  587.     /**    
  588.      * 查询方法    
  589.      * @return    
  590.      * @throws DaoException    
  591.      */     
  592.     public List selectStudents() throws DaoException;      
  593.      
  594.     /**    
  595.      * 添加方法    
  596.      * @param student    
  597.      * @throws DaoException    
  598.      */     
  599.     public void insertStudent(Student student) throws DaoException;      
  600.      
  601.     /**    
  602.      * 删除方法    
  603.      * @param student    
  604.      * @throws DaoException    
  605.      */     
  606.     public void deleteStudent(Student student) throws DaoException;      
  607.      
  608.     /**    
  609.      * 修改方法    
  610.      * @param student    
  611.      * @throws DaoException    
  612.      */     
  613.     public void modifyStudent(Student student) throws DaoException;      
  614. }     
  615.   
  616. package com.cvicse.dao;   
  617.   
  618. import java.util.List;   
  619.   
  620. import com.cvicse.dao.exception.DaoException;   
  621. import com.cvicse.po.Course;   
  622.   
  623. /**  
  624.  * 课程DAO层接口  
  625.  *  
  626.  */  
  627. public interface CourseDAO {   
  628.       
  629.     /**  
  630.      * 获取列表  
  631.      * @return  
  632.      * @throws DaoException  
  633.      */  
  634.     public List<Course> selectCourses() throws DaoException;   
  635.   
  636.     /**  
  637.      * 插入记录  
  638.      * @param course  
  639.      * @throws DaoException  
  640.      */  
  641.     public void insertCourse(Course course) throws DaoException;   
  642. }   
  643.   
  644. package com.cvicse.dao;   
  645.   
  646. import java.util.List;   
  647.   
  648. import com.cvicse.dao.exception.DaoException;   
  649. import com.cvicse.po.Student;   
  650.   
  651. public interface StudentDAO {   
  652.   
  653.     /**  
  654.      * 查询方法  
  655.      * @return  
  656.      * @throws DaoException  
  657.      */  
  658.     public List selectStudents() throws DaoException;   
  659.   
  660.     /**  
  661.      * 添加方法  
  662.      * @param student  
  663.      * @throws DaoException  
  664.      */  
  665.     public void insertStudent(Student student) throws DaoException;   
  666.   
  667.     /**  
  668.      * 删除方法  
  669.      * @param student  
  670.      * @throws DaoException  
  671.      */  
  672.     public void deleteStudent(Student student) throws DaoException;   
  673.   
  674.     /**  
  675.      * 修改方法  
  676.      * @param student  
  677.      * @throws DaoException  
  678.      */  
  679.     public void modifyStudent(Student student) throws DaoException;   
  680. }   
  681.     
  682.   
  683. 5、定义DAO操作的模板类,将DAO层的常用操作类进行提取。   
  684.   
  685. Java代码    
  686. package com.cvicse.util;      
  687.      
  688. import java.sql.Connection;      
  689. import java.sql.PreparedStatement;      
  690. import java.sql.ResultSet;      
  691. import java.sql.SQLException;      
  692. import java.sql.Statement;      
  693. import java.util.ArrayList;      
  694. import java.util.List;      
  695.      
  696. import com.cvicse.dao.exception.DaoException;      
  697. import com.cvicse.dao.exception.DaoParameterException;      
  698. import com.cvicse.dao.refactor.RowMapper;      
  699.      
  700. public class DaoOperateTemplate {      
  701.     /**    
  702.      * 查找单个记录对象    
  703.      *     
  704.      * @param sql    
  705.      * @param args    
  706.      * @param rowMapper    
  707.      * @return    
  708.      * @throws DaoException    
  709.      */     
  710.     public Object find(String sql, Object[] args, RowMapper rowMapper)      
  711.             throws DaoException {      
  712.         Connection conn = null;      
  713.         PreparedStatement ps = null;      
  714.         ResultSet rs = null;      
  715.         try {      
  716.             conn = JDBCUtils.getConnection();      
  717.             ps = conn.prepareStatement(sql);      
  718.             for (int i = 0; i < args.length; i++)      
  719.                 ps.setObject(i + 1, args[i]);      
  720.             rs = ps.executeQuery();      
  721.             Object obj = null;      
  722.             if (rs.next()) {      
  723.                 obj = rowMapper.mapRow(rs);      
  724.             }      
  725.             return obj;      
  726.         } catch (SQLException e) {      
  727.             throw new DaoException(e.getMessage(), e);      
  728.         } finally {      
  729.             try {      
  730.                 JDBCUtils.free(rs, ps, conn);      
  731.             } catch (SQLException e) {      
  732.                 throw new DaoParameterException(e.getMessage(), e);      
  733.             }      
  734.         }      
  735.     }      
  736.      
  737.     /**    
  738.      * 查找多条记录对象    
  739.      *     
  740.      * @param sql    
  741.      * @param args    
  742.      * @param rowMapper    
  743.      * @return    
  744.      * @throws DaoException    
  745.      */     
  746.     public List<Object> Query(String sql, Object[] args, RowMapper rowMapper)      
  747.             throws DaoException {      
  748.         Connection conn = null;      
  749.         PreparedStatement ps = null;      
  750.         ResultSet rs = null;      
  751.         List<Object> results = new ArrayList<Object>();      
  752.         try {      
  753.             conn = JDBCUtils.getConnection();      
  754.             ps = conn.prepareStatement(sql);      
  755.             for (int i = 0; i < args.length; i++)      
  756.                 ps.setObject(i + 1, args[i]);      
  757.             rs = ps.executeQuery();      
  758.             Object obj = null;      
  759.             while (rs.next()) {      
  760.                 obj = rowMapper.mapRow(rs);      
  761.                 results.add(obj);      
  762.             }      
  763.             return results;      
  764.         } catch (SQLException e) {      
  765.             throw new DaoException(e.getMessage(), e);      
  766.         } finally {      
  767.             try {      
  768.                 JDBCUtils.free(rs, ps, conn);      
  769.             } catch (SQLException e) {      
  770.                 throw new DaoParameterException(e.getMessage(), e);      
  771.             }      
  772.         }      
  773.     }      
  774.      
  775.     /**    
  776.      * 更新操作    
  777.      *     
  778.      * @param sql    
  779.      * @param args    
  780.      * @param isGeneralKey    
  781.      * @throws DaoException    
  782.      */     
  783.     public void update(String sql, Object[] args, boolean isGeneralKey)      
  784.             throws DaoException {      
  785.         Connection conn = null;      
  786.         PreparedStatement ps = null;      
  787.         ResultSet rs = null;      
  788.         try {      
  789.             conn = JDBCUtils.getConnection();      
  790.             ps = (isGeneralKey ? conn.prepareStatement(sql,      
  791.                     Statement.RETURN_GENERATED_KEYS) : conn      
  792.                     .prepareStatement(sql));      
  793.             for (int i = 0; i < args.length; i++)      
  794.                 ps.setObject(i + 1, args[i]);      
  795.             ps.executeUpdate();      
  796.         } catch (SQLException e) {      
  797.             throw new DaoException(e.getMessage(), e);      
  798.         } finally {      
  799.             try {      
  800.                 JDBCUtils.free(rs, ps, conn);      
  801.             } catch (SQLException e) {      
  802.                 throw new DaoParameterException(e.getMessage(), e);      
  803.             }      
  804.         }      
  805.     }      
  806. }     
  807.   
  808. package com.cvicse.util;   
  809.   
  810. import java.sql.Connection;   
  811. import java.sql.PreparedStatement;   
  812. import java.sql.ResultSet;   
  813. import java.sql.SQLException;   
  814. import java.sql.Statement;   
  815. import java.util.ArrayList;   
  816. import java.util.List;   
  817.   
  818. import com.cvicse.dao.exception.DaoException;   
  819. import com.cvicse.dao.exception.DaoParameterException;   
  820. import com.cvicse.dao.refactor.RowMapper;   
  821.   
  822. public class DaoOperateTemplate {   
  823.     /**  
  824.      * 查找单个记录对象  
  825.      *   
  826.      * @param sql  
  827.      * @param args  
  828.      * @param rowMapper  
  829.      * @return  
  830.      * @throws DaoException  
  831.      */  
  832.     public Object find(String sql, Object[] args, RowMapper rowMapper)   
  833.             throws DaoException {   
  834.         Connection conn = null;   
  835.         PreparedStatement ps = null;   
  836.         ResultSet rs = null;   
  837.         try {   
  838.             conn = JDBCUtils.getConnection();   
  839.             ps = conn.prepareStatement(sql);   
  840.             for (int i = 0; i < args.length; i++)   
  841.                 ps.setObject(i + 1, args[i]);   
  842.             rs = ps.executeQuery();   
  843.             Object obj = null;   
  844.             if (rs.next()) {   
  845.                 obj = rowMapper.mapRow(rs);   
  846.             }   
  847.             return obj;   
  848.         } catch (SQLException e) {   
  849.             throw new DaoException(e.getMessage(), e);   
  850.         } finally {   
  851.             try {   
  852.                 JDBCUtils.free(rs, ps, conn);   
  853.             } catch (SQLException e) {   
  854.                 throw new DaoParameterException(e.getMessage(), e);   
  855.             }   
  856.         }   
  857.     }   
  858.   
  859.     /**  
  860.      * 查找多条记录对象  
  861.      *   
  862.      * @param sql  
  863.      * @param args  
  864.      * @param rowMapper  
  865.      * @return  
  866.      * @throws DaoException  
  867.      */  
  868.     public List<Object> Query(String sql, Object[] args, RowMapper rowMapper)   
  869.             throws DaoException {   
  870.         Connection conn = null;   
  871.         PreparedStatement ps = null;   
  872.         ResultSet rs = null;   
  873.         List<Object> results = new ArrayList<Object>();   
  874.         try {   
  875.             conn = JDBCUtils.getConnection();   
  876.             ps = conn.prepareStatement(sql);   
  877.             for (int i = 0; i < args.length; i++)   
  878.                 ps.setObject(i + 1, args[i]);   
  879.             rs = ps.executeQuery();   
  880.             Object obj = null;   
  881.             while (rs.next()) {   
  882.                 obj = rowMapper.mapRow(rs);   
  883.                 results.add(obj);   
  884.             }   
  885.             return results;   
  886.         } catch (SQLException e) {   
  887.             throw new DaoException(e.getMessage(), e);   
  888.         } finally {   
  889.             try {   
  890.                 JDBCUtils.free(rs, ps, conn);   
  891.             } catch (SQLException e) {   
  892.                 throw new DaoParameterException(e.getMessage(), e);   
  893.             }   
  894.         }   
  895.     }   
  896.   
  897.     /**  
  898.      * 更新操作  
  899.      *   
  900.      * @param sql  
  901.      * @param args  
  902.      * @param isGeneralKey  
  903.      * @throws DaoException  
  904.      */  
  905.     public void update(String sql, Object[] args, boolean isGeneralKey)   
  906.             throws DaoException {   
  907.         Connection conn = null;   
  908.         PreparedStatement ps = null;   
  909.         ResultSet rs = null;   
  910.         try {   
  911.             conn = JDBCUtils.getConnection();   
  912.             ps = (isGeneralKey ? conn.prepareStatement(sql,   
  913.                     Statement.RETURN_GENERATED_KEYS) : conn   
  914.                     .prepareStatement(sql));   
  915.             for (int i = 0; i < args.length; i++)   
  916.                 ps.setObject(i + 1, args[i]);   
  917.             ps.executeUpdate();   
  918.         } catch (SQLException e) {   
  919.             throw new DaoException(e.getMessage(), e);   
  920.         } finally {   
  921.             try {   
  922.                 JDBCUtils.free(rs, ps, conn);   
  923.             } catch (SQLException e) {   
  924.                 throw new DaoParameterException(e.getMessage(), e);   
  925.             }   
  926.         }   
  927.     }   
  928. } 上面DAO通用操作类中定义接口,用于对象的转化。   
  929.   
  930. Java代码    
  931. package com.cvicse.dao.refactor;      
  932.      
  933. import java.sql.ResultSet;      
  934. import java.sql.SQLException;      
  935.      
  936. /**    
  937.  * @author Administrator    
  938.  *    
  939.  */     
  940. public interface RowMapper {      
  941.           
  942.     /**    
  943.      * 映射接口    
  944.      * @param rs    
  945.      * @return    
  946.      * @throws SQLException    
  947.      */     
  948.     public Object mapRow(ResultSet rs) throws SQLException;      
  949. }     
  950.   
  951. package com.cvicse.dao.refactor;   
  952.   
  953. import java.sql.ResultSet;   
  954. import java.sql.SQLException;   
  955.   
  956. /**  
  957.  * @author Administrator  
  958.  *  
  959.  */  
  960. public interface RowMapper {   
  961.        
  962.     /**  
  963.      * 映射接口  
  964.      * @param rs  
  965.      * @return  
  966.      * @throws SQLException  
  967.      */  
  968.     public Object mapRow(ResultSet rs) throws SQLException;   
  969. 6、定义具体DAO的实现,在DAO具体实现中,我们采用组合的方式引用通用类,正如设计原则中说的先考虑组合后考虑继承。所以我们在这里选择组合,而不用继承,同时继承对象的转换同样会存在问题。在每个具体DAO操作的实现类中,我们采用了策略模式。   
  970.   
  971. Java代码    
  972. package com.cvicse.dao.impl;      
  973.      
  974. import java.sql.ResultSet;      
  975. import java.sql.SQLException;      
  976. import java.util.List;      
  977.      
  978. import com.cvicse.dao.CourseDAO;      
  979. import com.cvicse.dao.exception.DaoException;      
  980. import com.cvicse.dao.refactor.RowMapper;      
  981. import com.cvicse.po.Course;      
  982. import com.cvicse.util.DaoOperateTemplate;      
  983.      
  984. public class CourseDAOImpl implements CourseDAO {      
  985.      
  986.     private DaoOperateTemplate daoTemplate = new DaoOperateTemplate();      
  987.      
  988.     public void insertCourse(Course course) throws DaoException {      
  989.         // TODO Auto-generated method stub      
  990.         String sql = "insert into course(id,name) values (?,?) ";      
  991.         Object[] args = new Object[] { course.getId(), course.getName() };      
  992.         daoTemplate.update(sql, args, false);      
  993.     }      
  994.      
  995.     public List<Course> selectCourses() throws DaoException {      
  996.         // TODO Auto-generated method stub      
  997.         String sql = "select * from course where id=? ";      
  998.         Object[] args = new Object[] { 1 };      
  999.         List courseList = daoTemplate.Query(sql, args, new courseRowMapper());      
  1000.         return courseList;      
  1001.     }      
  1002.      
  1003.     /**    
  1004.      * 内部匿名类    
  1005.      *     
  1006.      * @author Administrator    
  1007.      *     
  1008.      */     
  1009.     class courseRowMapper implements RowMapper {      
  1010.         public Object mapRow(ResultSet rs) throws SQLException {      
  1011.             Course course = new Course();      
  1012.             course.setId(rs.getLong("id"));      
  1013.             course.setName(rs.getString("name"));      
  1014.             return course;      
  1015.         }      
  1016.     }      
  1017. }      
  1018. package com.cvicse.dao.impl;      
  1019.      
  1020. import java.sql.ResultSet;      
  1021. import java.sql.SQLException;      
  1022. import java.util.List;      
  1023.      
  1024. import com.cvicse.dao.StudentDAO;      
  1025. import com.cvicse.dao.exception.DaoException;      
  1026. import com.cvicse.dao.refactor.RowMapper;      
  1027. import com.cvicse.po.Student;      
  1028. import com.cvicse.util.DaoOperateTemplate;      
  1029.      
  1030. public class StudentDAOImpl implements StudentDAO {      
  1031.      
  1032.     private DaoOperateTemplate daoTemplate = new DaoOperateTemplate();      
  1033.      
  1034.     /*    
  1035.      * (non-Javadoc)    
  1036.      *     
  1037.      * @see com.cvicse.dao.StudentDAO#deleteStudent(com.cvicse.po.Student)    
  1038.      */     
  1039.     public void deleteStudent(Student student) throws DaoException {      
  1040.         // TODO Auto-generated method stub      
  1041.         String sql = "delete from user where id=?";      
  1042.         Object[] args = new Object[] { student.getId() };      
  1043.         daoTemplate.update(sql, args, false);      
  1044.     }      
  1045.      
  1046.     /*    
  1047.      * (non-Javadoc)    
  1048.      *     
  1049.      * @see com.cvicse.dao.StudentDAO#insertStudent(com.cvicse.po.Student)    
  1050.      */     
  1051.     public void insertStudent(Student student) throws DaoException {      
  1052.         // TODO Auto-generated method stub      
  1053.         String sql = "insert into student(id,name) values (?,?) ";      
  1054.         Object[] args = new Object[] { student.getId(), student.getName() };      
  1055.         daoTemplate.update(sql, args, false);      
  1056.     }      
  1057.      
  1058.     public void modifyStudent(Student student) throws DaoException {      
  1059.         // TODO Auto-generated method stub      
  1060.         String sql = "update student set name=? where id=? ";      
  1061.         Object[] args = new Object[] { student.getName(), student.getId() };      
  1062.         daoTemplate.update(sql, args, false);      
  1063.     }      
  1064.      
  1065.     public List selectStudents() throws DaoException {      
  1066.         // TODO Auto-generated method stub      
  1067.         String sql = "select * from course where id=? ";      
  1068.         Object[] args = new Object[] { 1 };      
  1069.         List courseList = daoTemplate.Query(sql, args, new studentRowMapper());      
  1070.         return courseList;      
  1071.     }      
  1072.      
  1073.     /**    
  1074.      * 内部匿名类    
  1075.      *     
  1076.      * @author Administrator    
  1077.      *     
  1078.      */     
  1079.     class studentRowMapper implements RowMapper {      
  1080.         public Object mapRow(ResultSet rs) throws SQLException {      
  1081.             Student student = new Student();      
  1082.             student.setId(rs.getLong("id"));      
  1083.             student.setName(rs.getString("name"));      
  1084.             return student;      
  1085.         }      
  1086.     }      
  1087. }     
  1088.   
  1089. package com.cvicse.dao.impl;   
  1090.   
  1091. import java.sql.ResultSet;   
  1092. import java.sql.SQLException;   
  1093. import java.util.List;   
  1094.   
  1095. import com.cvicse.dao.CourseDAO;   
  1096. import com.cvicse.dao.exception.DaoException;   
  1097. import com.cvicse.dao.refactor.RowMapper;   
  1098. import com.cvicse.po.Course;   
  1099. import com.cvicse.util.DaoOperateTemplate;   
  1100.   
  1101. public class CourseDAOImpl implements CourseDAO {   
  1102.   
  1103.     private DaoOperateTemplate daoTemplate = new DaoOperateTemplate();   
  1104.   
  1105.     public void insertCourse(Course course) throws DaoException {   
  1106.         // TODO Auto-generated method stub   
  1107.         String sql = "insert into course(id,name) values (?,?) ";   
  1108.         Object[] args = new Object[] { course.getId(), course.getName() };   
  1109.         daoTemplate.update(sql, args, false);   
  1110.     }   
  1111.   
  1112.     public List<Course> selectCourses() throws DaoException {   
  1113.         // TODO Auto-generated method stub   
  1114.         String sql = "select * from course where id=? ";   
  1115.         Object[] args = new Object[] { 1 };   
  1116.         List courseList = daoTemplate.Query(sql, args, new courseRowMapper());   
  1117.         return courseList;   
  1118.     }   
  1119.   
  1120.     /**  
  1121.      * 内部匿名类  
  1122.      *   
  1123.      * @author Administrator  
  1124.      *   
  1125.      */  
  1126.     class courseRowMapper implements RowMapper {   
  1127.         public Object mapRow(ResultSet rs) throws SQLException {   
  1128.             Course course = new Course();   
  1129.             course.setId(rs.getLong("id"));   
  1130.             course.setName(rs.getString("name"));   
  1131.             return course;   
  1132.         }   
  1133.     }   
  1134. }   
  1135. package com.cvicse.dao.impl;   
  1136.   
  1137. import java.sql.ResultSet;   
  1138. import java.sql.SQLException;   
  1139. import java.util.List;   
  1140.   
  1141. import com.cvicse.dao.StudentDAO;   
  1142. import com.cvicse.dao.exception.DaoException;   
  1143. import com.cvicse.dao.refactor.RowMapper;   
  1144. import com.cvicse.po.Student;   
  1145. import com.cvicse.util.DaoOperateTemplate;   
  1146.   
  1147. public class StudentDAOImpl implements StudentDAO {   
  1148.   
  1149.     private DaoOperateTemplate daoTemplate = new DaoOperateTemplate();   
  1150.   
  1151.     /*  
  1152.      * (non-Javadoc)  
  1153.      *   
  1154.      * @see com.cvicse.dao.StudentDAO#deleteStudent(com.cvicse.po.Student)  
  1155.      */  
  1156.     public void deleteStudent(Student student) throws DaoException {   
  1157.         // TODO Auto-generated method stub   
  1158.         String sql = "delete from user where id=?";   
  1159.         Object[] args = new Object[] { student.getId() };   
  1160.         daoTemplate.update(sql, args, false);   
  1161.     }   
  1162.   
  1163.     /*  
  1164.      * (non-Javadoc)  
  1165.      *   
  1166.      * @see com.cvicse.dao.StudentDAO#insertStudent(com.cvicse.po.Student)  
  1167.      */  
  1168.     public void insertStudent(Student student) throws DaoException {   
  1169.         // TODO Auto-generated method stub   
  1170.         String sql = "insert into student(id,name) values (?,?) ";   
  1171.         Object[] args = new Object[] { student.getId(), student.getName() };   
  1172.         daoTemplate.update(sql, args, false);   
  1173.     }   
  1174.   
  1175.     public void modifyStudent(Student student) throws DaoException {   
  1176.         // TODO Auto-generated method stub   
  1177.         String sql = "update student set name=? where id=? ";   
  1178.         Object[] args = new Object[] { student.getName(), student.getId() };   
  1179.         daoTemplate.update(sql, args, false);   
  1180.     }   
  1181.   
  1182.     public List selectStudents() throws DaoException {   
  1183.         // TODO Auto-generated method stub   
  1184.         String sql = "select * from course where id=? ";   
  1185.         Object[] args = new Object[] { 1 };   
  1186.         List courseList = daoTemplate.Query(sql, args, new studentRowMapper());   
  1187.         return courseList;   
  1188.     }   
  1189.   
  1190.     /**  
  1191.      * 内部匿名类  
  1192.      *   
  1193.      * @author Administrator  
  1194.      *   
  1195.      */  
  1196.     class studentRowMapper implements RowMapper {   
  1197.         public Object mapRow(ResultSet rs) throws SQLException {   
  1198.             Student student = new Student();   
  1199.             student.setId(rs.getLong("id"));   
  1200.             student.setName(rs.getString("name"));   
  1201.             return student;   
  1202.         }   
  1203.     }   
  1204. }   
  1205.  7、我们定义工厂类,在定义工厂类,考虑到通用性,我们采用了反射机制加配置文件的形式来实现的。同时,在工厂模式中引入了饿汉式单例模式。   
  1206.   
  1207. Java代码    
  1208. /**    
  1209.  *     
  1210.  */     
  1211. package com.cvicse.daofactory;      
  1212.      
  1213. import java.io.IOException;      
  1214. import java.io.InputStream;      
  1215. import java.util.Properties;      
  1216.      
  1217. /**    
  1218.  * 工厂类方法    
  1219.  *     
  1220.  */     
  1221.      
  1222. public class DaoFactory {      
  1223.      
  1224.     private static DaoFactory instance = new DaoFactory();//懒汉法声明对象      
  1225.     private static Properties pro;// 配置文件对象      
  1226.      
  1227.     private DaoFactory() {      
  1228.         try {      
  1229.             // 初始化配置文件      
  1230.             pro = new Properties();      
  1231.             // 采用类加载器方法读取配置文件信息到字节流对象,采用类加载灵活,不用写死      
  1232.             InputStream inputStream = DaoFactory.class.getClassLoader()      
  1233.                     .getResourceAsStream("applicationContext.properties");      
  1234.             // 加载字节流对象      
  1235.             pro.load(inputStream);      
  1236.         } catch (IOException e) {      
  1237.             throw new ExceptionInInitializerError(e);      
  1238.         }      
  1239.     }      
  1240.      
  1241.     /**    
  1242.      * 单例模式获取唯一实例    
  1243.      *     
  1244.      * @return    
  1245.      */     
  1246.     public static DaoFactory getInstance() {      
  1247.         return instance;      
  1248.     }      
  1249.      
  1250.     /**    
  1251.      * 根据配置文件的名字获取类的名字,采用反射机制获取其对象    
  1252.      *     
  1253.      * @param Key    
  1254.      * @return    
  1255.      */     
  1256.     public Object getDAO(String Key) throws Exception {      
  1257.         String className = (String) pro.get(Key);      
  1258.         return (Class.forName(className).newInstance());      
  1259.     }      
  1260. }     
  1261.   
  1262. /**  
  1263.  *   
  1264.  */  
  1265. package com.cvicse.daofactory;   
  1266.   
  1267. import java.io.IOException;   
  1268. import java.io.InputStream;   
  1269. import java.util.Properties;   
  1270.   
  1271. /**  
  1272.  * 工厂类方法  
  1273.  *   
  1274.  */  
  1275.   
  1276. public class DaoFactory {   
  1277.   
  1278.     private static DaoFactory instance = new DaoFactory();//懒汉法声明对象   
  1279.     private static Properties pro;// 配置文件对象   
  1280.   
  1281.     private DaoFactory() {   
  1282.         try {   
  1283.             // 初始化配置文件   
  1284.             pro = new Properties();   
  1285.             // 采用类加载器方法读取配置文件信息到字节流对象,采用类加载灵活,不用写死   
  1286.             InputStream inputStream = DaoFactory.class.getClassLoader()   
  1287.                     .getResourceAsStream("applicationContext.properties");   
  1288.             // 加载字节流对象   
  1289.             pro.load(inputStream);   
  1290.         } catch (IOException e) {   
  1291.             throw new ExceptionInInitializerError(e);   
  1292.         }   
  1293.     }   
  1294.   
  1295.     /**  
  1296.      * 单例模式获取唯一实例  
  1297.      *   
  1298.      * @return  
  1299.      */  
  1300.     public static DaoFactory getInstance() {   
  1301.         return instance;   
  1302.     }   
  1303.   
  1304.     /**  
  1305.      * 根据配置文件的名字获取类的名字,采用反射机制获取其对象  
  1306.      *   
  1307.      * @param Key  
  1308.      * @return  
  1309.      */  
  1310.     public Object getDAO(String Key) throws Exception {   
  1311.         String className = (String) pro.get(Key);   
  1312.         return (Class.forName(className).newInstance());   
  1313.     }   
  1314. } 配置文件的内容如下:applicationContext.properties   
  1315.   
  1316. Java代码    
  1317. courseDao=com.cvicse.dao.impl.CourseDAOImpl      
  1318. entsDao=com.cvicse.dao.impl.StudentDAOImpl     
  1319.   
  1320.     courseDao=com.cvicse.dao.impl.CourseDAOImpl   
  1321. studentsDao=com.cvicse.dao.impl.StudentDAOImpl 8、业务层的调用方式,这里用客户端方式模拟的。在业务层通过接口的方式调用,使得DAO层和业务层能够解耦。   
  1322.   
  1323. Java代码    
  1324. package com.cvicse.Test;      
  1325.      
  1326. import com.cvicse.dao.CourseDAO;      
  1327. import com.cvicse.daofactory.DaoFactory;      
  1328.      
  1329. /**    
  1330.  * @author Administrator    
  1331.  *     
  1332.  */     
  1333. public class ServiceClient {      
  1334.      
  1335.     /**    
  1336.      * @param args    
  1337.      */     
  1338.     public static void main(String[] args) {      
  1339.         // TODO Auto-generated method stub      
  1340.         try {      
  1341.             CourseDAO courseDao = (CourseDAO) DaoFactory.getInstance().getDAO(      
  1342.                     "courseDao");      
  1343.         } catch (Exception e) {      
  1344.             // TODO Auto-generated catch block      
  1345.             e.printStackTrace();      
  1346.         }      
  1347.     }      
  1348. }     
  1349.   
  1350. package com.cvicse.Test;   
  1351.   
  1352. import com.cvicse.dao.CourseDAO;   
  1353. import com.cvicse.daofactory.DaoFactory;   
  1354.   
  1355. /**  
  1356.  * @author Administrator  
  1357.  *   
  1358.  */  
  1359. public class ServiceClient {   
  1360.   
  1361.     /**  
  1362.      * @param args  
  1363.      */  
  1364.     public static void main(String[] args) {   
  1365.         // TODO Auto-generated method stub   
  1366.         try {   
  1367.             CourseDAO courseDao = (CourseDAO) DaoFactory.getInstance().getDAO(   
  1368.                     "courseDao");   
  1369.         } catch (Exception e) {   
  1370.             // TODO Auto-generated catch block   
  1371.             e.printStackTrace();   
  1372.         }   
  1373.     }   
  1374. }    
  1375.   
  1376. 总结:在这个DAO设计模式中,涉及到很多java的基础知识,同时,也涉及太多的模式。只有灵活应用,才能体会的其中的灵活。关于DAO具体实现可以采用spring的simpetempate会更能简化其中的实现。   
  1377.   

虽然DAO模式已经有了好多的成熟的框架,但它仍然是一个比较重要的设计模式。要做一个比较合理的DAO模式,你需要对工厂模式、单例模式、模板模式、策略模式、代理模式、泛型、反射机制、输入输出、异常等知识比较熟悉。下面结合自己理解,设计一个DAO设计模式的例子,希望大家给与指正。

1、数据库连接池的工具类。

     在数据库连接池的工具类中,采用了开源的DBCP数据库连接池,调用了DataSource接口,DBCP中关于Datasource的Connection采用了动态代理的方式实现,在这里只是提出,感兴趣可以查看其源码,该工具类采用可配置的方式实现的,代码如下:

 

Java代码 复制代码
  1. package com.cvicse.utils;   
  2.   
  3. import java.io.InputStream;   
  4. import java.sql.Connection;   
  5. import java.sql.ResultSet;   
  6. import java.sql.SQLException;   
  7. import java.sql.Statement;   
  8. import java.util.Properties;   
  9.   
  10. import javax.sql.DataSource;   
  11.   
  12. import org.apache.commons.dbcp.BasicDataSourceFactory;   
  13.   
  14. /**  
  15.  * 数据库连接池操作工具类  
  16.  *   
  17.  */  
  18. public class JDBCUtils {   
  19.     private static DataSource myDataSource = null;   
  20.     private JDBCUtils() {   
  21.     }   
  22.   
  23.     static {   
  24.         try {   
  25.             Properties prop = new Properties();   
  26. //采用了类的加载获取路径下数据库的配置信息   
  27.             InputStream is = JDBCUtils.class.getClassLoader()   
  28.                     .getResourceAsStream("dbcpconfig.properties");   
  29.             prop.load(is);   
  30.             myDataSource = BasicDataSourceFactory.createDataSource(prop);   
  31.         } catch (Exception e) {   
  32.             throw new ExceptionInInitializerError(e);   
  33.         }   
  34.     }   
  35.   
  36.     /**  
  37.      * 获取数据源  
  38.      *   
  39.      * @return  
  40.      */  
  41.     public static DataSource getDataSource() {   
  42.         return myDataSource;   
  43.     }   
  44.   
  45.     /**  
  46.      * 获取连接  
  47.      *   
  48.      * @return  
  49.      * @throws SQLException  
  50.      */  
  51.     public static Connection getConnection() throws SQLException {   
  52.         return myDataSource.getConnection();   
  53.     }   
  54.   
  55.     /**  
  56.      * 关闭资源  
  57.      * @param rs  
  58.      * @param st  
  59.      * @param conn  
  60.      * @throws SQLException  
  61.      */  
  62.     public static void free(ResultSet rs, Statement st, Connection conn)   
  63.             throws SQLException {   
  64.         try {   
  65.             if (rs != null)   
  66.                 rs.close();   
  67.         } catch (SQLException e) {   
  68.             throw new SQLException();   
  69.         } finally {   
  70.             try {   
  71.                 if (st != null)   
  72.                     st.close();   
  73.             } catch (SQLException e) {   
  74.                 throw new SQLException();   
  75.             } finally {   
  76.                 if (conn != null)   
  77.                     try {   
  78.                         conn.close();   
  79.                     } catch (Exception e) {   
  80.                         throw new SQLException();   
  81.                     }   
  82.             }   
  83.         }   
  84.     }   
  85. }  

package com.cvicse.utils; import java.io.InputStream; import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.Properties; import javax.sql.DataSource; import org.apache.commons.dbcp.BasicDataSourceFactory; /** * 数据库连接池操作工具类 * */ public class JDBCUtils { private static DataSource myDataSource = null; private JDBCUtils() { } static { try { Properties prop = new Properties(); //采用了类的加载获取路径下数据库的配置信息 InputStream is = JDBCUtils.class.getClassLoader() .getResourceAsStream("dbcpconfig.properties"); prop.load(is); myDataSource = BasicDataSourceFactory.createDataSource(prop); } catch (Exception e) { throw new ExceptionInInitializerError(e); } } /** * 获取数据源 * * @return */ public static DataSource getDataSource() { return myDataSource; } /** * 获取连接 * * @return * @throws SQLException */ public static Connection getConnection() throws SQLException { return myDataSource.getConnection(); } /** * 关闭资源 * @param rs * @param st * @param conn * @throws SQLException */ public static void free(ResultSet rs, Statement st, Connection conn) throws SQLException { try { if (rs != null) rs.close(); } catch (SQLException e) { throw new SQLException(); } finally { try { if (st != null) st.close(); } catch (SQLException e) { throw new SQLException(); } finally { if (conn != null) try { conn.close(); } catch (Exception e) { throw new SQLException(); } } } } }

 数据库配置文件的信息如下dbcpconfig.properties

Java代码 复制代码
  1. #连接设置   
  2. driverClassName=com.mysql.jdbc.Driver   
  3. url=jdbc:mysql://localhost:3306/test123   
  4. username=root   
  5. password=   
  6.   
  7. #<!-- 初始化连接 -->   
  8. initialSize=10  
  9.   
  10. #最大连接数量   
  11. maxActive=50  
  12.   
  13. #<!-- 最大空闲连接 -->   
  14. maxIdle=20  
  15.   
  16. #<!-- 最小空闲连接 -->   
  17. minIdle=5  
  18.   
  19. #<!-- 超时等待时间以毫秒为单位 6000毫秒/1000等于60秒 -->   
  20. maxWait=60000  
  21.   
  22.   
  23. #JDBC驱动建立连接时附带的连接属性属性的格式必须为这样:[属性名=property;]    
  24. #注意:"user" 与 "password" 两个属性会被明确地传递,因此这里不需要包含他们。   
  25. connectionProperties=useUnicode=true;characterEncoding=UTF-8  
  26.   
  27. #指定由连接池所创建的连接的自动提交(auto-commit)状态。   
  28. defaultAutoCommit=true  
  29.   
  30. #driver default 指定由连接池所创建的连接的只读(read-only)状态。   
  31. #如果没有设置该值,则“setReadOnly”方法将不被调用。(某些驱动并不支持只读模式,如:Informix)   
  32. defaultReadOnly=   
  33.   
  34. #driver default 指定由连接池所创建的连接的事务级别(TransactionIsolation)。   
  35. #可用值为下列之一:(详情可见javadoc。)NONE,READ_UNCOMMITTED, READ_COMMITTED, REPEATABLE_READ, SERIALIZABLE   
  36. defaultTransactionIsolation=READ_UNCOMMITTED  

#连接设置 driverClassName=com.mysql.jdbc.Driver url=jdbc:mysql://localhost:3306/test123 username=root password= #<!-- 初始化连接 --> initialSize=10 #最大连接数量 maxActive=50 #<!-- 最大空闲连接 --> maxIdle=20 #<!-- 最小空闲连接 --> minIdle=5 #<!-- 超时等待时间以毫秒为单位 6000毫秒/1000等于60秒 --> maxWait=60000 #JDBC驱动建立连接时附带的连接属性属性的格式必须为这样:[属性名=property;] #注意:"user" 与 "password" 两个属性会被明确地传递,因此这里不需要包含他们。 connectionProperties=useUnicode=true;characterEncoding=UTF-8 #指定由连接池所创建的连接的自动提交(auto-commit)状态。 defaultAutoCommit=true #driver default 指定由连接池所创建的连接的只读(read-only)状态。 #如果没有设置该值,则“setReadOnly”方法将不被调用。(某些驱动并不支持只读模式,如:Informix) defaultReadOnly= #driver default 指定由连接池所创建的连接的事务级别(TransactionIsolation)。 #可用值为下列之一:(详情可见javadoc。)NONE,READ_UNCOMMITTED, READ_COMMITTED, REPEATABLE_READ, SERIALIZABLE defaultTransactionIsolation=READ_UNCOMMITTED

 2、异常定义,用于处理DAO层的异常类,因为异常最好要在业务层进行处理,个人认为这DAO层异常应该在业务层进行处理,所以DAO层的必要异常都抛出。

Java代码 复制代码
  1. package com.cvicse.dao.exception;   
  2.   
  3. /**  
  4.  *  
  5.  * 定义DAO异常类  
  6.  *  
  7.  */  
  8. public class DaoException extends Exception {   
  9.     private static final long serialVersionUID = 1L;   
  10.     /**  
  11.      * @param message  
  12.      * @param cause  
  13.      */  
  14.     public DaoException(String message, Throwable cause) {   
  15.         super(message, cause);   
  16.     }   
  17.     /**  
  18.      * @param message  
  19.      */  
  20.     public DaoException(String message) {   
  21.         super(message);   
  22.     }   
  23. }   
  24.   
  25. package com.cvicse.dao.exception;   
  26.   
  27.   
  28. /**  
  29.  * 传入参数错误异常  
  30.  *  
  31.  */  
  32. public class DaoParameterException extends DaoException {   
  33.     private static final long serialVersionUID = 1L;   
  34.   
  35.     /**  
  36.      * @param message  
  37.      * @param cause  
  38.      */  
  39.     public DaoParameterException(String message, Throwable cause) {   
  40.         super(message, cause);   
  41.     }   
  42.   
  43.     /**  
  44.      * @param message  
  45.      */  
  46.     public DaoParameterException(String message) {   
  47.         super(message);   
  48.     }   
  49.   
  50. }  

package com.cvicse.dao.exception; /** * * 定义DAO异常类 * */ public class DaoException extends Exception { private static final long serialVersionUID = 1L; /** * @param message * @param cause */ public DaoException(String message, Throwable cause) { super(message, cause); } /** * @param message */ public DaoException(String message) { super(message); } } package com.cvicse.dao.exception; /** * 传入参数错误异常 * */ public class DaoParameterException extends DaoException { private static final long serialVersionUID = 1L; /** * @param message * @param cause */ public DaoParameterException(String message, Throwable cause) { super(message, cause); } /** * @param message */ public DaoParameterException(String message) { super(message); } }

 

3、定义要操作的pojo类,这里定义了2个pojo类

Java代码 复制代码
  1. package com.cvicse.po;   
  2.   
  3. /**  
  4.  * 课程持久层对象  
  5.  *  
  6.  */  
  7. public class Course {   
  8.     private long id;   
  9.     private String name;   
  10.     /**  
  11.      * 构造函数类  
  12.      */  
  13.     public Course() {   
  14.         this.id = 0;   
  15.         this.name = null;   
  16.     }   
  17.     /**  
  18.      * @param id  
  19.      * @param name  
  20.      */  
  21.     public Course(long id, String name) {   
  22.         this.id = id;   
  23.         this.name = name;   
  24.     }   
  25.   
  26.     /**  
  27.      * @return  
  28.      */  
  29.     public long getId() {   
  30.         return id;   
  31.     }   
  32.   
  33.     /**  
  34.      * @param id  
  35.      */  
  36.     public void setId(long id) {   
  37.         this.id = id;   
  38.     }   
  39.   
  40.     /**  
  41.      * @return  
  42.      */  
  43.     public String getName() {   
  44.         return name;   
  45.     }   
  46.   
  47.     /**  
  48.      * @param name  
  49.      */  
  50.     public void setName(String name) {   
  51.         this.name = name;   
  52.     }   
  53. }   
  54.   
  55. package com.cvicse.po;   
  56.   
  57. /**  
  58.  * 学生持久层对象  
  59.  */  
  60. public class Student {   
  61.     private long id;   
  62.   
  63.     private String name;   
  64.   
  65.     public Student() {   
  66.         this.id = 0;   
  67.         this.name = null;   
  68.     }   
  69.   
  70.     public Student(long id, String name) {   
  71.         this.id = id;   
  72.         this.name = name;   
  73.     }   
  74.   
  75.     public long getId() {   
  76.         return id;   
  77.     }   
  78.   
  79.     public void setId(long id) {   
  80.         this.id = id;   
  81.     }   
  82.   
  83.     public String getName() {   
  84.         return name;   
  85.     }   
  86.   
  87.     public void setName(String name) {   
  88.         this.name = name;   
  89.     }   
  90. }  

package com.cvicse.po; /** * 课程持久层对象 * */ public class Course { private long id; private String name; /** * 构造函数类 */ public Course() { this.id = 0; this.name = null; } /** * @param id * @param name */ public Course(long id, String name) { this.id = id; this.name = name; } /** * @return */ public long getId() { return id; } /** * @param id */ public void setId(long id) { this.id = id; } /** * @return */ public String getName() { return name; } /** * @param name */ public void setName(String name) { this.name = name; } } package com.cvicse.po; /** * 学生持久层对象 */ public class Student { private long id; private String name; public Student() { this.id = 0; this.name = null; } public Student(long id, String name) { this.id = id; this.name = name; } public long getId() { return id; } public void setId(long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } }

 

4、定义对象操作的DAO接口,因为面向接口编程,定义接口目的是DAO层的操作能和业务层解耦。

Java代码 复制代码
  1. package com.cvicse.dao;   
  2.   
  3. import java.util.List;   
  4.   
  5. import com.cvicse.dao.exception.DaoException;   
  6. import com.cvicse.po.Course;   
  7.   
  8. /**  
  9.  * 课程DAO层接口  
  10.  *  
  11.  */  
  12. public interface CourseDAO {   
  13.       
  14.     /**  
  15.      * 获取列表  
  16.      * @return  
  17.      * @throws DaoException  
  18.      */  
  19.     public List<Course> selectCourses() throws DaoException;   
  20.   
  21.     /**  
  22.      * 插入记录  
  23.      * @param course  
  24.      * @throws DaoException  
  25.      */  
  26.     public void insertCourse(Course course) throws DaoException;   
  27. }   
  28.   
  29. package com.cvicse.dao;   
  30.   
  31. import java.util.List;   
  32.   
  33. import com.cvicse.dao.exception.DaoException;   
  34. import com.cvicse.po.Student;   
  35.   
  36. public interface StudentDAO {   
  37.   
  38.     /**  
  39.      * 查询方法  
  40.      * @return  
  41.      * @throws DaoException  
  42.      */  
  43.     public List selectStudents() throws DaoException;   
  44.   
  45.     /**  
  46.      * 添加方法  
  47.      * @param student  
  48.      * @throws DaoException  
  49.      */  
  50.     public void insertStudent(Student student) throws DaoException;   
  51.   
  52.     /**  
  53.      * 删除方法  
  54.      * @param student  
  55.      * @throws DaoException  
  56.      */  
  57.     public void deleteStudent(Student student) throws DaoException;   
  58.   
  59.     /**  
  60.      * 修改方法  
  61.      * @param student  
  62.      * @throws DaoException  
  63.      */  
  64.     public void modifyStudent(Student student) throws DaoException;   
  65. }  

package com.cvicse.dao; import java.util.List; import com.cvicse.dao.exception.DaoException; import com.cvicse.po.Course; /** * 课程DAO层接口 * */ public interface CourseDAO { /** * 获取列表 * @return * @throws DaoException */ public List<Course> selectCourses() throws DaoException; /** * 插入记录 * @param course * @throws DaoException */ public void insertCourse(Course course) throws DaoException; } package com.cvicse.dao; import java.util.List; import com.cvicse.dao.exception.DaoException; import com.cvicse.po.Student; public interface StudentDAO { /** * 查询方法 * @return * @throws DaoException */ public List selectStudents() throws DaoException; /** * 添加方法 * @param student * @throws DaoException */ public void insertStudent(Student student) throws DaoException; /** * 删除方法 * @param student * @throws DaoException */ public void deleteStudent(Student student) throws DaoException; /** * 修改方法 * @param student * @throws DaoException */ public void modifyStudent(Student student) throws DaoException; }

 

5、定义DAO操作的模板类,将DAO层的常用操作类进行提取。

Java代码 复制代码
  1. package com.cvicse.util;   
  2.   
  3. import java.sql.Connection;   
  4. import java.sql.PreparedStatement;   
  5. import java.sql.ResultSet;   
  6. import java.sql.SQLException;   
  7. import java.sql.Statement;   
  8. import java.util.ArrayList;   
  9. import java.util.List;   
  10.   
  11. import com.cvicse.dao.exception.DaoException;   
  12. import com.cvicse.dao.exception.DaoParameterException;   
  13. import com.cvicse.dao.refactor.RowMapper;   
  14.   
  15. public class DaoOperateTemplate {   
  16.     /**  
  17.      * 查找单个记录对象  
  18.      *   
  19.      * @param sql  
  20.      * @param args  
  21.      * @param rowMapper  
  22.      * @return  
  23.      * @throws DaoException  
  24.      */  
  25.     public Object find(String sql, Object[] args, RowMapper rowMapper)   
  26.             throws DaoException {   
  27.         Connection conn = null;   
  28.         PreparedStatement ps = null;   
  29.         ResultSet rs = null;   
  30.         try {   
  31.             conn = JDBCUtils.getConnection();   
  32.             ps = conn.prepareStatement(sql);   
  33.             for (int i = 0; i < args.length; i++)   
  34.                 ps.setObject(i + 1, args[i]);   
  35.             rs = ps.executeQuery();   
  36.             Object obj = null;   
  37.             if (rs.next()) {   
  38.                 obj = rowMapper.mapRow(rs);   
  39.             }   
  40.             return obj;   
  41.         } catch (SQLException e) {   
  42.             throw new DaoException(e.getMessage(), e);   
  43.         } finally {   
  44.             try {   
  45.                 JDBCUtils.free(rs, ps, conn);   
  46.             } catch (SQLException e) {   
  47.                 throw new DaoParameterException(e.getMessage(), e);   
  48.             }   
  49.         }   
  50.     }   
  51.   
  52.     /**  
  53.      * 查找多条记录对象  
  54.      *   
  55.      * @param sql  
  56.      * @param args  
  57.      * @param rowMapper  
  58.      * @return  
  59.      * @throws DaoException  
  60.      */  
  61.     public List<Object> Query(String sql, Object[] args, RowMapper rowMapper)   
  62.             throws DaoException {   
  63.         Connection conn = null;   
  64.         PreparedStatement ps = null;   
  65.         ResultSet rs = null;   
  66.         List<Object> results = new ArrayList<Object>();   
  67.         try {   
  68.             conn = JDBCUtils.getConnection();   
  69.             ps = conn.prepareStatement(sql);   
  70.             for (int i = 0; i < args.length; i++)   
  71.                 ps.setObject(i + 1, args[i]);   
  72.             rs = ps.executeQuery();   
  73.             Object obj = null;   
  74.             while (rs.next()) {   
  75.                 obj = rowMapper.mapRow(rs);   
  76.                 results.add(obj);   
  77.             }   
  78.             return results;   
  79.         } catch (SQLException e) {   
  80.             throw new DaoException(e.getMessage(), e);   
  81.         } finally {   
  82.             try {   
  83.                 JDBCUtils.free(rs, ps, conn);   
  84.             } catch (SQLException e) {   
  85.                 throw new DaoParameterException(e.getMessage(), e);   
  86.             }   
  87.         }   
  88.     }   
  89.   
  90.     /**  
  91.      * 更新操作  
  92.      *   
  93.      * @param sql  
  94.      * @param args  
  95.      * @param isGeneralKey  
  96.      * @throws DaoException  
  97.      */  
  98.     public void update(String sql, Object[] args, boolean isGeneralKey)   
  99.             throws DaoException {   
  100.         Connection conn = null;   
  101.         PreparedStatement ps = null;   
  102.         ResultSet rs = null;   
  103.         try {   
  104.             conn = JDBCUtils.getConnection();   
  105.             ps = (isGeneralKey ? conn.prepareStatement(sql,   
  106.                     Statement.RETURN_GENERATED_KEYS) : conn   
  107.                     .prepareStatement(sql));   
  108.             for (int i = 0; i < args.length; i++)   
  109.                 ps.setObject(i + 1, args[i]);   
  110.             ps.executeUpdate();   
  111.         } catch (SQLException e) {   
  112.             throw new DaoException(e.getMessage(), e);   
  113.         } finally {   
  114.             try {   
  115.                 JDBCUtils.free(rs, ps, conn);   
  116.             } catch (SQLException e) {   
  117.                 throw new DaoParameterException(e.getMessage(), e);   
  118.             }   
  119.         }   
  120.     }   
  121. }  

package com.cvicse.util; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.ArrayList; import java.util.List; import com.cvicse.dao.exception.DaoException; import com.cvicse.dao.exception.DaoParameterException; import com.cvicse.dao.refactor.RowMapper; public class DaoOperateTemplate { /** * 查找单个记录对象 * * @param sql * @param args * @param rowMapper * @return * @throws DaoException */ public Object find(String sql, Object[] args, RowMapper rowMapper) throws DaoException { Connection conn = null; PreparedStatement ps = null; ResultSet rs = null; try { conn = JDBCUtils.getConnection(); ps = conn.prepareStatement(sql); for (int i = 0; i < args.length; i++) ps.setObject(i + 1, args[i]); rs = ps.executeQuery(); Object obj = null; if (rs.next()) { obj = rowMapper.mapRow(rs); } return obj; } catch (SQLException e) { throw new DaoException(e.getMessage(), e); } finally { try { JDBCUtils.free(rs, ps, conn); } catch (SQLException e) { throw new DaoParameterException(e.getMessage(), e); } } } /** * 查找多条记录对象 * * @param sql * @param args * @param rowMapper * @return * @throws DaoException */ public List<Object> Query(String sql, Object[] args, RowMapper rowMapper) throws DaoException { Connection conn = null; PreparedStatement ps = null; ResultSet rs = null; List<Object> results = new ArrayList<Object>(); try { conn = JDBCUtils.getConnection(); ps = conn.prepareStatement(sql); for (int i = 0; i < args.length; i++) ps.setObject(i + 1, args[i]); rs = ps.executeQuery(); Object obj = null; while (rs.next()) { obj = rowMapper.mapRow(rs); results.add(obj); } return results; } catch (SQLException e) { throw new DaoException(e.getMessage(), e); } finally { try { JDBCUtils.free(rs, ps, conn); } catch (SQLException e) { throw new DaoParameterException(e.getMessage(), e); } } } /** * 更新操作 * * @param sql * @param args * @param isGeneralKey * @throws DaoException */ public void update(String sql, Object[] args, boolean isGeneralKey) throws DaoException { Connection conn = null; PreparedStatement ps = null; ResultSet rs = null; try { conn = JDBCUtils.getConnection(); ps = (isGeneralKey ? conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS) : conn .prepareStatement(sql)); for (int i = 0; i < args.length; i++) ps.setObject(i + 1, args[i]); ps.executeUpdate(); } catch (SQLException e) { throw new DaoException(e.getMessage(), e); } finally { try { JDBCUtils.free(rs, ps, conn); } catch (SQLException e) { throw new DaoParameterException(e.getMessage(), e); } } } }

 上面DAO通用操作类中定义接口,用于对象的转化。

Java代码 复制代码
  1. package com.cvicse.dao.refactor;   
  2.   
  3. import java.sql.ResultSet;   
  4. import java.sql.SQLException;   
  5.   
  6. /**  
  7.  * @author Administrator  
  8.  *  
  9.  */  
  10. public interface RowMapper {   
  11.        
  12.     /**  
  13.      * 映射接口  
  14.      * @param rs  
  15.      * @return  
  16.      * @throws SQLException  
  17.      */  
  18.     public Object mapRow(ResultSet rs) throws SQLException;   
  19. }  

package com.cvicse.dao.refactor; import java.sql.ResultSet; import java.sql.SQLException; /** * @author Administrator * */ public interface RowMapper { /** * 映射接口 * @param rs * @return * @throws SQLException */ public Object mapRow(ResultSet rs) throws SQLException; }

 6、定义具体DAO的实现,在DAO具体实现中,我们采用组合的方式引用通用类,正如设计原则中说的先考虑组合后考虑继承。所以我们在这里选择组合,而不用继承,同时继承对象的转换同样会存在问题。在每个具体DAO操作的实现类中,我们采用了策略模式。

Java代码 复制代码
  1. package com.cvicse.dao.impl;   
  2.   
  3. import java.sql.ResultSet;   
  4. import java.sql.SQLException;   
  5. import java.util.List;   
  6.   
  7. import com.cvicse.dao.CourseDAO;   
  8. import com.cvicse.dao.exception.DaoException;   
  9. import com.cvicse.dao.refactor.RowMapper;   
  10. import com.cvicse.po.Course;   
  11. import com.cvicse.util.DaoOperateTemplate;   
  12.   
  13. public class CourseDAOImpl implements CourseDAO {   
  14.   
  15.     private DaoOperateTemplate daoTemplate = new DaoOperateTemplate();   
  16.   
  17.     public void insertCourse(Course course) throws DaoException {   
  18.         // TODO Auto-generated method stub   
  19.         String sql = "insert into course(id,name) values (?,?) ";   
  20.         Object[] args = new Object[] { course.getId(), course.getName() };   
  21.         daoTemplate.update(sql, args, false);   
  22.     }   
  23.   
  24.     public List<Course> selectCourses() throws DaoException {   
  25.         // TODO Auto-generated method stub   
  26.         String sql = "select * from course where id=? ";   
  27.         Object[] args = new Object[] { 1 };   
  28.         List courseList = daoTemplate.Query(sql, args, new courseRowMapper());   
  29.         return courseList;   
  30.     }   
  31.   
  32.     /**  
  33.      * 内部匿名类  
  34.      *   
  35.      * @author Administrator  
  36.      *   
  37.      */  
  38.     class courseRowMapper implements RowMapper {   
  39.         public Object mapRow(ResultSet rs) throws SQLException {   
  40.             Course course = new Course();   
  41.             course.setId(rs.getLong("id"));   
  42.             course.setName(rs.getString("name"));   
  43.             return course;   
  44.         }   
  45.     }   
  46. }   
  47. package com.cvicse.dao.impl;   
  48.   
  49. import java.sql.ResultSet;   
  50. import java.sql.SQLException;   
  51. import java.util.List;   
  52.   
  53. import com.cvicse.dao.StudentDAO;   
  54. import com.cvicse.dao.exception.DaoException;   
  55. import com.cvicse.dao.refactor.RowMapper;   
  56. import com.cvicse.po.Student;   
  57. import com.cvicse.util.DaoOperateTemplate;   
  58.   
  59. public class StudentDAOImpl implements StudentDAO {   
  60.   
  61.     private DaoOperateTemplate daoTemplate = new DaoOperateTemplate();   
  62.   
  63.     /*  
  64.      * (non-Javadoc)  
  65.      *   
  66.      * @see com.cvicse.dao.StudentDAO#deleteStudent(com.cvicse.po.Student)  
  67.      */  
  68.     public void deleteStudent(Student student) throws DaoException {   
  69.         // TODO Auto-generated method stub   
  70.         String sql = "delete from user where id=?";   
  71.         Object[] args = new Object[] { student.getId() };   
  72.         daoTemplate.update(sql, args, false);   
  73.     }   
  74.   
  75.     /*  
  76.      * (non-Javadoc)  
  77.      *   
  78.      * @see com.cvicse.dao.StudentDAO#insertStudent(com.cvicse.po.Student)  
  79.      */  
  80.     public void insertStudent(Student student) throws DaoException {   
  81.         // TODO Auto-generated method stub   
  82.         String sql = "insert into student(id,name) values (?,?) ";   
  83.         Object[] args = new Object[] { student.getId(), student.getName() };   
  84.         daoTemplate.update(sql, args, false);   
  85.     }   
  86.   
  87.     public void modifyStudent(Student student) throws DaoException {   
  88.         // TODO Auto-generated method stub   
  89.         String sql = "update student set name=? where id=? ";   
  90.         Object[] args = new Object[] { student.getName(), student.getId() };   
  91.         daoTemplate.update(sql, args, false);   
  92.     }   
  93.   
  94.     public List selectStudents() throws DaoException {   
  95.         // TODO Auto-generated method stub   
  96.         String sql = "select * from course where id=? ";   
  97.         Object[] args = new Object[] { 1 };   
  98.         List courseList = daoTemplate.Query(sql, args, new studentRowMapper());   
  99.         return courseList;   
  100.     }   
  101.   
  102.     /**  
  103.      * 内部匿名类  
  104.      *   
  105.      * @author Administrator  
  106.      *   
  107.      */  
  108.     class studentRowMapper implements RowMapper {   
  109.         public Object mapRow(ResultSet rs) throws SQLException {   
  110.             Student student = new Student();   
  111.             student.setId(rs.getLong("id"));   
  112.             student.setName(rs.getString("name"));   
  113.             return student;   
  114.         }   
  115.     }   
  116. }  

package com.cvicse.dao.impl; import java.sql.ResultSet; import java.sql.SQLException; import java.util.List; import com.cvicse.dao.CourseDAO; import com.cvicse.dao.exception.DaoException; import com.cvicse.dao.refactor.RowMapper; import com.cvicse.po.Course; import com.cvicse.util.DaoOperateTemplate; public class CourseDAOImpl implements CourseDAO { private DaoOperateTemplate daoTemplate = new DaoOperateTemplate(); public void insertCourse(Course course) throws DaoException { // TODO Auto-generated method stub String sql = "insert into course(id,name) values (?,?) "; Object[] args = new Object[] { course.getId(), course.getName() }; daoTemplate.update(sql, args, false); } public List<Course> selectCourses() throws DaoException { // TODO Auto-generated method stub String sql = "select * from course where id=? "; Object[] args = new Object[] { 1 }; List courseList = daoTemplate.Query(sql, args, new courseRowMapper()); return courseList; } /** * 内部匿名类 * * @author Administrator * */ class courseRowMapper implements RowMapper { public Object mapRow(ResultSet rs) throws SQLException { Course course = new Course(); course.setId(rs.getLong("id")); course.setName(rs.getString("name")); return course; } } } package com.cvicse.dao.impl; import java.sql.ResultSet; import java.sql.SQLException; import java.util.List; import com.cvicse.dao.StudentDAO; import com.cvicse.dao.exception.DaoException; import com.cvicse.dao.refactor.RowMapper; import com.cvicse.po.Student; import com.cvicse.util.DaoOperateTemplate; public class StudentDAOImpl implements StudentDAO { private DaoOperateTemplate daoTemplate = new DaoOperateTemplate(); /* * (non-Javadoc) * * @see com.cvicse.dao.StudentDAO#deleteStudent(com.cvicse.po.Student) */ public void deleteStudent(Student student) throws DaoException { // TODO Auto-generated method stub String sql = "delete from user where id=?"; Object[] args = new Object[] { student.getId() }; daoTemplate.update(sql, args, false); } /* * (non-Javadoc) * * @see com.cvicse.dao.StudentDAO#insertStudent(com.cvicse.po.Student) */ public void insertStudent(Student student) throws DaoException { // TODO Auto-generated method stub String sql = "insert into student(id,name) values (?,?) "; Object[] args = new Object[] { student.getId(), student.getName() }; daoTemplate.update(sql, args, false); } public void modifyStudent(Student student) throws DaoException { // TODO Auto-generated method stub String sql = "update student set name=? where id=? "; Object[] args = new Object[] { student.getName(), student.getId() }; daoTemplate.update(sql, args, false); } public List selectStudents() throws DaoException { // TODO Auto-generated method stub String sql = "select * from course where id=? "; Object[] args = new Object[] { 1 }; List courseList = daoTemplate.Query(sql, args, new studentRowMapper()); return courseList; } /** * 内部匿名类 * * @author Administrator * */ class studentRowMapper implements RowMapper { public Object mapRow(ResultSet rs) throws SQLException { Student student = new Student(); student.setId(rs.getLong("id")); student.setName(rs.getString("name")); return student; } } }

 7、我们定义工厂类,在定义工厂类,考虑到通用性,我们采用了反射机制加配置文件的形式来实现的。同时,在工厂模式中引入了饿汉式单例模式。

Java代码 复制代码
  1. /**  
  2.  *   
  3.  */  
  4. package com.cvicse.daofactory;   
  5.   
  6. import java.io.IOException;   
  7. import java.io.InputStream;   
  8. import java.util.Properties;   
  9.   
  10. /**  
  11.  * 工厂类方法  
  12.  *   
  13.  */  
  14.   
  15. public class DaoFactory {   
  16.   
  17.     private static DaoFactory instance = new DaoFactory();//懒汉法声明对象   
  18.     private static Properties pro;// 配置文件对象   
  19.   
  20.     private DaoFactory() {   
  21.         try {   
  22.             // 初始化配置文件   
  23.             pro = new Properties();   
  24.             // 采用类加载器方法读取配置文件信息到字节流对象,采用类加载灵活,不用写死   
  25.             InputStream inputStream = DaoFactory.class.getClassLoader()   
  26.                     .getResourceAsStream("applicationContext.properties");   
  27.             // 加载字节流对象   
  28.             pro.load(inputStream);   
  29.         } catch (IOException e) {   
  30.             throw new ExceptionInInitializerError(e);   
  31.         }   
  32.     }   
  33.   
  34.     /**  
  35.      * 单例模式获取唯一实例  
  36.      *   
  37.      * @return  
  38.      */  
  39.     public static DaoFactory getInstance() {   
  40.         return instance;   
  41.     }   
  42.   
  43.     /**  
  44.      * 根据配置文件的名字获取类的名字,采用反射机制获取其对象  
  45.      *   
  46.      * @param Key  
  47.      * @return  
  48.      */  
  49.     public Object getDAO(String Key) throws Exception {   
  50.         String className = (String) pro.get(Key);   
  51.         return (Class.forName(className).newInstance());   
  52.     }   
  53. }  

/** * */ package com.cvicse.daofactory; import java.io.IOException; import java.io.InputStream; import java.util.Properties; /** * 工厂类方法 * */ public class DaoFactory { private static DaoFactory instance = new DaoFactory();//懒汉法声明对象 private static Properties pro;// 配置文件对象 private DaoFactory() { try { // 初始化配置文件 pro = new Properties(); // 采用类加载器方法读取配置文件信息到字节流对象,采用类加载灵活,不用写死 InputStream inputStream = DaoFactory.class.getClassLoader() .getResourceAsStream("applicationContext.properties"); // 加载字节流对象 pro.load(inputStream); } catch (IOException e) { throw new ExceptionInInitializerError(e); } } /** * 单例模式获取唯一实例 * * @return */ public static DaoFactory getInstance() { return instance; } /** * 根据配置文件的名字获取类的名字,采用反射机制获取其对象 * * @param Key * @return */ public Object getDAO(String Key) throws Exception { String className = (String) pro.get(Key); return (Class.forName(className).newInstance()); } }

 配置文件的内容如下:applicationContext.properties

Java代码 复制代码
  1. courseDao=com.cvicse.dao.impl.CourseDAOImpl   
  2. entsDao=com.cvicse.dao.impl.StudentDAOImpl  

courseDao=com.cvicse.dao.impl.CourseDAOImpl studentsDao=com.cvicse.dao.impl.StudentDAOImpl

 8、业务层的调用方式,这里用客户端方式模拟的。在业务层通过接口的方式调用,使得DAO层和业务层能够解耦。

Java代码 复制代码
  1. package com.cvicse.Test;   
  2.   
  3. import com.cvicse.dao.CourseDAO;   
  4. import com.cvicse.daofactory.DaoFactory;   
  5.   
  6. /**  
  7.  * @author Administrator  
  8.  *   
  9.  */  
  10. public class ServiceClient {   
  11.   
  12.     /**  
  13.      * @param args  
  14.      */  
  15.     public static void main(String[] args) {   
  16.         // TODO Auto-generated method stub   
  17.         try {   
  18.             CourseDAO courseDao = (CourseDAO) DaoFactory.getInstance().getDAO(   
  19.                     "courseDao");   
  20.         } catch (Exception e) {   
  21.             // TODO Auto-generated catch block   
  22.             e.printStackTrace();   
  23.         }   
  24.     }   
  25. }  

package com.cvicse.Test; import com.cvicse.dao.CourseDAO; import com.cvicse.daofactory.DaoFactory; /** * @author Administrator * */ public class ServiceClient { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub try { CourseDAO courseDao = (CourseDAO) DaoFactory.getInstance().getDAO( "courseDao"); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } }

 

总结:在这个DAO设计模式中,涉及到很多java的基础知识,同时,也涉及太多的模式。只有灵活应用,才能体会的其中的灵活。关于DAO具体实现可以采用spring的simpetempate会更能简化其中的实现。

 

链接网页:http://www.javaeye.com/topic/427289

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值