DAO规划形式51CTO博客 - 千亿集团

DAO规划形式51CTO博客

2019年04月24日14时17分04秒 | 作者: 振宇 | 标签: 规划,衔接,方法 | 浏览: 2460

         尽管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();
         }
     }
    }
}
}

数据库装备文件的信息如下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
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);
}

}
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;
}
}

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;
}

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);
     }
    }
}
}
上面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;
}
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;
    }
}
}

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());
}
}
装备文件的内容如下:applicationContext.properties
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();
    }
}
}
总结:在这个DAO规划方法中,触及到许多java的基础常识,一起,也触及太多的方法。只要灵敏使用,才干领会的其间的灵敏。关于DAO详细完成能够选用spring的simpetempate会更能简化其间的完成。
版权声明
本文来源于网络,版权归原作者所有,其内容与观点不代表千亿集团立场。转载文章仅为传播更有价值的信息,如采编人员采编有误或者版权原因,请与我们联系,我们核实后立即修改或删除。

猜您喜欢的文章