虽然DAO模式已经有了好多的成熟的框架,但它仍然是一个比较重要的设计模式。要做一个比较合理的DAO模式,你需要对工厂模式、单例模式、模板模式、策略模式、代理模式、泛型、反射机制、输入输出、异常等知识比较熟悉。下面结合自己理解,设计一个DAO设计模式的例子,希望大家给与指正。
1、数据库连接池的工具类。
在数据库连接池的工具类中,采用了开源的DBCP数据库连接池,调用了DataSource接口,DBCP中关于Datasource的Connection采用了动态代理的方式实现,在这里只是提出,感兴趣可以查看其源码,该工具类采用可配置的方式实现的,代码如下:
- 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();
- }
- }
- }
- }
- }
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
- #连接设置
- 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
#连接设置
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层的必要异常都抛出。
- 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);
- }
- }
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类
- 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;
- }
- }
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层的操作能和业务层解耦。
- 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;
- }
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层的常用操作类进行提取。
- 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);
- }
- }
- }
- }
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通用操作类中定义接口,用于对象的转化。
- 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;
- }
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操作的实现类中,我们采用了策略模式。
- 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;
- }
- }
- }
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、我们定义工厂类,在定义工厂类,考虑到通用性,我们采用了反射机制加配置文件的形式来实现的。同时,在工厂模式中引入了饿汉式单例模式。
- /**
- *
- */
- 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());
- }
- }
/**
*
*/
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
- cousrsDao=com.cvicse.dao.impl.CourseDAOImpl
- studentsDao=com.cvicse.dao.impl.StudentDAOImpl
cousrsDao=com.cvicse.dao.impl.CourseDAOImpl
studentsDao=com.cvicse.dao.impl.StudentDAOImpl
8、业务层的调用方式,这里用客户端方式模拟的。在业务层通过接口的方式调用,使得DAO层和业务层能够解耦。
- 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();
- }
- }
- }
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会更能简化其中的实现。