DAO设计模式简介

来源:互联网 发布:qq文件夹删除数据恢复 编辑:程序博客网 时间:2024/06/05 22:49

DAO,数据访问对象,主要的功能就是数据操作,在标准的程序开发架构中属于数据层的操作。其主要分为以下几层:

客户层:因为现在大多采用B/S架构,所以一般客户都是用浏览器进行访问,当然也可以使用其它的访问程序。

显示层:使用JSP/Servlet进行页面效果的显示。

业务层:会将多个原子性的DAO操作进行组合,组成一个完整的业务逻辑。

数据层(DAO):提供原子性的操作,例如增删改查等。

DAO设计流程:

1设计一个专门负责打开连接数据库和关闭数据库操作的类。命名规则:xxx.dbc.DatabaseConnection

2设计VO(值对象),其主要有属性和setter和getter方法构成,以数据库中的字段项对应。命名规则:xxx.vo.ttt;ttt要与数据库的表的名字一致

3.DAO设计:定义一系列的原子性操作,如增删改查等操作的接口。命名规则:xxx.dao.IXxx.DAO

4设计DAO接口的真正实现的类,完成具体的数据库操作。但是不再去负责数据库的打开和关闭。命名规则:xxx.dao.impl.xxxDAOImpl

5.proxy代理类的实现:主要将1,4结合起来,完成整个操作过程。命名规则:xxx.dao.proxy.XxxProxy

6.Factory类主要用来获得一个DAO类的实例对象。命名规则:xxx.factory.DAOFactory


实验实例:

1.数据库设计:

/*======================= 删除数据库 =======================*/DROP DATABASE IF EXISTS mldn ;/*======================= 创建数据库 =======================*/CREATE DATABASE mldn ;/*======================= 使用数据库 =======================*/USE mldn ;/*======================= 删除数据表 =======================*/DROP TABLE IF EXISTS emp ;/*======================= 创建数据表 =======================*/CREATE TABLE emp(   empnoINT(4)PRIMARY KEY,   enameVARCHAR(10),   jobVARCHAR(9),   hiredateDATE,   salFLOAT(7,2)) ;/*======================= 插入测试数据 =======================*/INSERT INTO emp (empno,ename,job,hiredate,sal) VALUES (6060,'李兴华','经理','2001-09-16',2000.30) ;INSERT INTO emp (empno,ename,job,hiredate,sal) VALUES (7369,'董鸣楠','销售','2003-10-09',1500.90) ;INSERT INTO emp (empno,ename,job,hiredate,sal) VALUES (8964,'李祺','分析员','2003-10-01',3000) ;INSERT INTO emp (empno,ename,job,hiredate,sal) VALUES (7698,'张惠','销售','2005-03-12',800) ;INSERT INTO emp (empno,ename,job,hiredate,sal) VALUES (7782,'杨军','分析员','2005-01-12',2500) ;INSERT INTO emp (empno,ename,job,hiredate,sal) VALUES (7762,'刘明','销售','2005-03-09',1000) ;INSERT INTO emp (empno,ename,job,hiredate,sal) VALUES (7839,'王月','经理','2006-09-01',2500) ;

 对应上述的数据库定义VO类:

package cn.mldn.lxh.vo ;import java.util.Date ;public class Emp {private int empno ;private String ename ;private String job ;private Date hiredate ;private float sal ;public void setEmpno(int empno){this.empno = empno ;}public void setEname(String ename){this.ename = ename ;}public void setJob(String job){this.job = job ;}public void setHiredate(Date hiredate){this.hiredate = hiredate ;}public void setSal(float sal){this.sal = sal ;}public int getEmpno(){return this.empno ;}public String getEname(){return this.ename ;}public String getJob(){return this.job ;}public Date getHiredate(){return this.hiredate ;}public float getSal(){return this.sal ;}}


   下面开始定义数据库连接类DatabaseConnection,为了方便我们将所有的异常向上抛出到调用方法,下面也使用同样的方式:

package cn.mldn.lxh.dbc ;import java.sql.Connection ;import java.sql.DriverManager ;public class DatabaseConnection {private static final String DBDRIVER = "org.gjt.mm.mysql.Driver" ; private static final String DBURL = "jdbc:mysql://localhost:3306/mldn" ;private static final String DBUSER = "root" ;private static final String DBPASSWORD = "mysqladmin" ;private Connection conn ;public DatabaseConnection() throws Exception {Class.forName(DBDRIVER) ;this.conn = DriverManager.getConnection(DBURL,DBUSER,DBPASSWORD) ;}public Connection getConnection(){return this.conn ;}public void close() throws Exception {if(this.conn != null){try{this.conn.close() ;}catch(Exception e){throw e ;}}}}

 对DAO操作标准进行定义:

package cn.mldn.lxh.dao ;import java.util.* ;import cn.mldn.lxh.vo.* ;public interface IEmpDAO {public boolean doCreate(Emp emp) throws Exception ;public List<Emp> findAll(String keyWord) throws Exception ;public Emp findById(int empno) throws Exception ;}


为了进行一下简单的测试,我们仅仅定义了增加和两种查询操作,这个实例主要验证增加和查询操作。

定义正式的DAO接口实现类:

package cn.mldn.lxh.dao.impl ;import java.util.* ;import java.sql.* ;import cn.mldn.lxh.dao.* ;import cn.mldn.lxh.vo.* ;public class EmpDAOImpl implements IEmpDAO {private Connection conn = null ;private PreparedStatement pstmt = null ;public EmpDAOImpl(Connection conn){this.conn = conn ;}public boolean doCreate(Emp emp) throws Exception{boolean flag = false ;String sql = "INSERT INTO emp(empno,ename,job,hiredate,sal) VALUES (?,?,?,?,?)" ;this.pstmt = this.conn.prepareStatement(sql) ;this.pstmt.setInt(1,emp.getEmpno()) ;this.pstmt.setString(2,emp.getEname()) ;this.pstmt.setString(3,emp.getJob()) ;this.pstmt.setDate(4,new java.sql.Date(emp.getHiredate().getTime())) ;this.pstmt.setFloat(5,emp.getSal()) ;if(this.pstmt.executeUpdate() > 0){flag = true ;}this.pstmt.close() ;return flag ;}public List<Emp> findAll(String keyWord) throws Exception{List<Emp> all = new ArrayList<Emp>() ;String sql = "SELECT empno,ename,job,hiredate,sal FROM emp WHERE ename LIKE ? OR job LIKE ?" ;this.pstmt = this.conn.prepareStatement(sql) ;this.pstmt.setString(1,"%"+keyWord+"%") ;this.pstmt.setString(2,"%"+keyWord+"%") ;ResultSet rs = this.pstmt.executeQuery() ;Emp emp = null ;while(rs.next()){emp = new Emp() ;emp.setEmpno(rs.getInt(1)) ;emp.setEname(rs.getString(2)) ;emp.setJob(rs.getString(3)) ;emp.setHiredate(rs.getDate(4)) ;emp.setSal(rs.getFloat(5)) ;all.add(emp) ;}this.pstmt.close() ;return all ;}public Emp findById(int empno) throws Exception{Emp emp = null ;String sql = "SELECT empno,ename,job,hiredate,sal FROM emp WHERE empno=?" ;this.pstmt = this.conn.prepareStatement(sql) ;this.pstmt.setInt(1,empno) ;ResultSet rs = this.pstmt.executeQuery() ;if(rs.next()){emp = new Emp() ;emp.setEmpno(rs.getInt(1)) ;emp.setEname(rs.getString(2)) ;emp.setJob(rs.getString(3)) ;emp.setHiredate(rs.getDate(4)) ;emp.setSal(rs.getFloat(5)) ;}this.pstmt.close() ;return emp ;}}

随后增加代理实现类,这个类可以为了以后的业务进行考虑,我们可以再这个类中进行复杂的任务的编写,比如可以在这个代理类中添加事务的控制,使得开发结构更加清晰。

上述的真实实现类和代理类主要是为了降低代码之间的耦合度。

最后设计一个DAO工厂类,这个主要用来获取DAO接口的实例化对象:

package cn.mldn.lxh.factory ;import cn.mldn.lxh.dao.IEmpDAO ;import cn.mldn.lxh.dao.proxy.EmpDAOProxy ;public class DAOFactory {public static IEmpDAO getIEmpDAOInstance() throws Exception{return new EmpDAOProxy() ;}}

下面编写测试类进行测试;测试Insert功能:

package cn.mldn.lxh.dao.test ;import cn.mldn.lxh.factory.DAOFactory ;import cn.mldn.lxh.vo.* ;public class TestDAOInsert{public static void main(String args[]) throws Exception{Emp emp = null ;for(int x=0;x<5;x++){emp = new Emp() ;emp.setEmpno(1000 + x) ;emp.setEname("李兴华 - " + x) ;emp.setJob("程序员 - " + x) ;emp.setHiredate(new java.util.Date()) ;emp.setSal(500 * x) ;DAOFactory.getIEmpDAOInstance().doCreate(emp) ;}}}


测试:select功能:

package cn.mldn.lxh.dao.test ;import java.util.* ;import cn.mldn.lxh.factory.DAOFactory ;import cn.mldn.lxh.vo.* ;public class TestDAOSelect{public static void main(String args[]) throws Exception{List<Emp> all = DAOFactory.getIEmpDAOInstance().findAll("") ;Iterator<Emp> iter = all.iterator() ;while(iter.hasNext()){Emp emp = iter.next() ;System.out.println(emp.getEmpno() + "、" + emp.getEname() + " --> " + emp.getJob()) ;}}}


下面使用jsp调用DAO:

增加雇员的表单页:

<%@ page contentType="text/html" pageEncoding="GBK"%><html><head><title>www.mldnjava.cn,MLDN高端Java培训</title></head><body><form action="emp_insert_do.jsp" method="post">雇员编号:<input type="text" name="empno"><br>雇员姓名:<input type="text" name="ename"><br>雇员职位:<input type="text" name="job"><br>雇佣日期:<input type="text" name="hiredate"><br>基本工资:<input type="text" name="sal"><br><input type="submit" value="注册"><input type="reset" value="重置"></form></body></html>


完成雇员增加的页面:

<%@ page contentType="text/html" pageEncoding="GBK"%><%@ page import="cn.mldn.lxh.factory.*,cn.mldn.lxh.vo.*"%><%@ page import="java.text.*"%><html><head><title>www.mldnjava.cn,MLDN高端Java培训</title></head><%request.setCharacterEncoding("GBK");%><body><%Emp emp = new Emp() ;emp.setEmpno(Integer.parseInt(request.getParameter("empno"))) ;emp.setEname(request.getParameter("ename")) ;emp.setJob(request.getParameter("job")) ;emp.setHiredate(new SimpleDateFormat("yyyy-MM-dd").parse(request.getParameter("hiredate"))) ;emp.setSal(Float.parseFloat(request.getParameter("sal"))) ;try{if(DAOFactory.getIEmpDAOInstance().doCreate(emp)){%><h3>雇员信息添加成功!</h3><%} else {%><h3>雇员信息添加失败!</h3><%}%><%}catch(Exception e){e.printStackTrace() ;}%></body></html>


数据查询页面:

<%@ page contentType="text/html" pageEncoding="GBK"%><%@ page import="cn.mldn.lxh.factory.*,cn.mldn.lxh.vo.*"%><%@ page import="java.util.*"%><html><head><title>www.mldnjava.cn,MLDN高端Java培训</title></head><%request.setCharacterEncoding("GBK") ;%><body><%String keyWord = request.getParameter("kw") ;if(keyWord == null){keyWord = "" ;// 如果没有查询关键字,则查询全部}List<Emp> all = DAOFactory.getIEmpDAOInstance().findAll(keyWord) ;Iterator<Emp> iter = all.iterator() ;%><center><form action="emp_list.jsp" method="post">请输入查询关键字:<input type="text" name="kw"><input type="submit" value="查询"></form><table border="1" width="80%"> <tr><td>雇员编号</td><td>雇员姓名</td><td>雇员工作</td><td>雇佣日期</td><td>基本工资</td></tr><%while(iter.hasNext()){Emp emp = iter.next() ;%><tr><td><%=emp.getEmpno()%></td><td><%=emp.getEname()%></td><td><%=emp.getJob()%></td><td><%=emp.getHiredate()%></td><td><%=emp.getSal()%></td></tr><%}%></table></center></body></html>





原创粉丝点击