DAO设计模式

简介: DAO设计模式 1.认识DAO 2.DAO各部分的详解 3.DAO设计模式流程

 

DAO设计模式

1.认识DAO

DAO(Data Acess Object 数据库访问对象)的主要功能是操作数据库,所以DAO在标准开发架构中数据数据层,以下是标准开发的架构

    1. 客户层:目前使用B/S开发架构居多,客户可以通过浏览器访问
    2. 显示层:使用Vue框架、 React框架、 JSP/Servlet等进行页面展示
    3. 业务层:负责将DAO层的操作进行组合,形成一个完整的业务逻辑
    4. 数据层:提供原子性操作,比如增删查改

    2.DAO各部分的详解

    DAO的设计流程包括六个部分,如下:

    1.DataBaseConnection

    设计一个专门负责打开连接数据库和关闭数据库操作的类

    命名规则: xxx.dbc.DataBaseConnection

    2.VO

    设计VO(值对象),其主要由属性,setter和getter组成与数据库中的字段进行对应。

    命名规则:xxx.vo.ttt ; 其中ttt要和数据库中的表的名字一致

    3.DAO

    定义一系列原子性操作,比如增删查改,和实现业务的接口

    命名规则:xxx.dao.I.xxx.DAO

    4.Impl

    设计DAO接口真正的实现类,完成具体的操作,但是不负责数据库的开关

    命名规则:xxx.dao.imp.xxxDAOImpI

    5.Proxy

    Proxy代理类的实现,主要将以上四个部分组合起来,完成整个操作过程

    命名规则:xxx.dao.Proxy.xxx.Proxy

    6.Factory

    Factory类主要用于获得DAO类的实例对象

    命名规则:xxx.factory.DAOFactory


    3.DAO设计模式流程

    通过一个案例讲解DAO设计模式的流程

    现在需要实现一个能够注册和查询工作者的案例(JDBC与DAO结合)

    1.首先需要实现数据库的创建与表单的创建

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

    image.gif


    2.定义VO类

    package com.JavaWebDAO.vo;
    import java.util.Date ;
    //定义工人类
    public class Worker {
    //    设置工人属性
        private int empno ;
        private String ename ;
        private String job ;
        private Date hiredate ;
        private float sal ;
    //    配置setter函数
        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 ;
        }
    //    配置getter函数
        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 ;
        }
    }

    image.gif

    3.定义数据库连接类

    package com.JavaWebDAO.db;
    import java.sql.Connection ;
    import java.sql.DriverManager ;
    public class DatabaseConnection {
    //    配置相关信息
        private static final String DBDRIVER = "com.mysql.jdbc.Driver" ;
        private static final String DBURL = "jdbc:mysql://localhost:3306/smile" ;
        private static final String DBUSER = "root" ;
        private static final String DBPASSWORD = "357703" ;
        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 ;
                }
            }
        }
    }

    image.gif


    4.新建DAO接口

    package com.JavaWebDAO.dao;
    import java.util.* ;
    import com.JavaWebDAO.vo.Worker;
    public interface IWorkerDAO {
    //    业务需求--注册员工
        public boolean doCreate(Worker work) throws Exception ;
    //    业务需求--查询员工
        public List<Worker> findAll(String keyWord) throws Exception ;
    //    业务需求--通过id查询员工
        public Worker findById(int empno) throws Exception ;
    }

    image.gif


    5.定义完DAO接口后就需要写好具体的实现类,实现类分为两种。

    一种是真实实现类,一种是代理操作类。

    真实实现类

    package com.JavaWebDAO.dao.impI;
    import com.JavaWebDAO.dao.IWorkerDAO;
    import com.JavaWebDAO.vo.Worker;
    import java.sql.Connection;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    import java.util.ArrayList;
    import java.util.List;
    //真实实现类,实现IWorker中所有业务需求
    public class WorkerDAOImpl implements IWorkerDAO {
        private Connection conn = null ;
        private PreparedStatement pstmt = null ;
    //    通过构造函数获取连接对象
        public WorkerDAOImpl(Connection conn){
            this.conn = conn ;
        }
    //    实现注册员工功能
        public boolean doCreate(Worker work) throws Exception{
            boolean flag = false ;
            String sql = "INSERT INTO worker(empno,ename,job,hiredate,sal) VALUES (?,?,?,?,?)" ;
            this.pstmt = this.conn.prepareStatement(sql) ;
            this.pstmt.setInt(1,work.getEmpno()) ;
            this.pstmt.setString(2,work.getEname()) ;
            this.pstmt.setString(3,work.getJob()) ;
            this.pstmt.setDate(4,new java.sql.Date(work.getHiredate().getTime())) ;
            this.pstmt.setFloat(5,work.getSal()) ;
            if(this.pstmt.executeUpdate() > 0){
                flag = true ;
            }
            this.pstmt.close() ;
            return flag ;
        }
    //    实现查询员工的功能
        public List<Worker> findAll(String keyWord) throws Exception{
            List<Worker> all = new ArrayList<Worker>() ;
            String sql = "SELECT empno,ename,job,hiredate,sal FROM worker 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() ;
            Worker work = null ;
            while(rs.next()){
                work = new Worker() ;
                work.setEmpno(rs.getInt(1)) ;
                work.setEname(((ResultSet) rs).getString(2)) ;
                work.setJob(rs.getString(3)) ;
                work.setHiredate(rs.getDate(4)) ;
                work.setSal(rs.getFloat(5)) ;
                all.add(work) ;
            }
            this.pstmt.close() ;
            return all ;
        }
    //    实现通过id查询员工的功能
        public Worker findById(int empno) throws Exception{
            Worker emp = null ;
            String sql = "SELECT empno,ename,job,hiredate,sal FROM worker WHERE empno=?" ;
            this.pstmt = this.conn.prepareStatement(sql) ;
            this.pstmt.setInt(1,empno) ;
            ResultSet rs = this.pstmt.executeQuery() ;
            if(rs.next()){
                emp = new Worker() ;
                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 ;
        }
    }

    image.gif

    代理操作类

    package com.JavaWebDAO.dao.proxy;
    import com.JavaWebDAO.dao.IWorkerDAO;
    import com.JavaWebDAO.dao.impI.WorkerDAOImpl;
    import com.JavaWebDAO.db.DatabaseConnection;
    import com.JavaWebDAO.vo.Worker;
    import java.util.List;
    //代理操作IWorkerDAo中的业务需求
    public class WorkerDAOProxy implements IWorkerDAO {
        private DatabaseConnection db = null ;
        private IWorkerDAO dao = null ;
    //    代理建立连接数据库
        public WorkerDAOProxy() throws Exception {
            this.db = new DatabaseConnection() ;
            this.dao = new WorkerDAOImpl(this.db.getConnection()) ;
        }
    //    代理实现注册功能
        public boolean doCreate(Worker work) throws Exception{
            boolean flag = false ;
            try{
                if(this.dao.findById(work.getEmpno()) == null){
                    flag = this.dao.doCreate(work) ;
                }
            }catch(Exception e){
                throw e ;
            }finally{
                this.db.close() ;
            }
            return flag ;
        }
    //    代理实现查询用户功能
        public List<Worker> findAll(String keyWord) throws Exception{
            List<Worker> all = null ;
            try{
                all = this.dao.findAll(keyWord) ;
            }catch(Exception e){
                throw e ;
            }finally{
                this.db.close() ;
            }
            return all ;
        }
    //    代理通过id查询用户的功能
        public Worker findById(int empno) throws Exception {
            Worker emp = null;
            try {
                emp = this.dao.findById(empno);
            } catch (Exception e) {
                throw e;
            } finally {
                this.db.close();
            }
            return emp;
        }
    }

    image.gif

    代理类只是调用了真实类中的方法,但是代理类可以让代码开发的结构更加清晰


    6.定义工厂类

    package com.JavaWebDAO.factory;
    import com.JavaWebDAO.dao.IWorkerDAO;
    import com.JavaWebDAO.dao.proxy.WorkerDAOProxy;
    public class DAOFactory {
    //    通过工厂获取代理类的实例
        public static IWorkerDAO getIWorkerDAOInstance() throws Exception{
            return new WorkerDAOProxy() ;
        }
    }

    image.gif


    设计完所有类和接口后,为了保证定义后功能可用,则需要做一个测试类,来测试所有功能是否能够正常使用

    package com.lzl.dao.test ;
    import com.lzl.factory.DAOFactory ;
    import com.lzl.vo.* ;
    public class TestdoCreate{
      public static void main(String args[]) throws Exception{
        Worker work = null ;
          work = new Worker() ;
          work.setEmpno(1000) ;
          work.setEname("SMILE") ;
          work.setJob("程序员 " ) ;
          work.setHiredate(new java.util.Date()) ;
          work.setSal(10000) ;
          DAOFactory.getIWorkerDAOInstance().doCreate(work) ;
          }
      }

    image.gif

    package com.lzl.dao.test ;
    import java.util.* ;
    import com.lzl.factory.DAOFactory ;
    import com.lzl.vo.* ;
    public class TestfindAll{
      public static void main(String args[]) throws Exception{
        List<Worker> all = DAOFactory.getIWorkerDAOInstance().findAll("") ;
        Iterator<Worker> iter = all.iterator() ;
        while(iter.hasNext()){
          Worker work = iter.next() ;
          System.out.println(work.getEmpno() + "、" + work.getEname() + " 、 " + work.getJob()+ "、"+work.getHiredate() + " 、 "+work.getSal()) ;
        }
      }
    }

    image.gif


    整体项目结构

    image.gif编辑

    这样DAO层就开发完毕了


    目录
    相关文章
    |
    SQL Java 数据库连接
    DAO 设计模式
    介绍 DAO功能是数据操作.客户发送数据到显示层,显示层发送数据到业务层,业务发送数据到数据层,数据层进行持久化.即.保存进入databases 一些简称 BO 业务对象的简称 DAO 一个数据访问对象,增删查改 PO数据库一条记录,映射成javaBean对象,拥有getter/setter方法 ...
    8238 0
    |
    SQL
    DAO设计模式
    本文完全根据我对DAO设计模式的理解程度完成,在未来不断地学习中,我也会不断更新这篇文章,如果你对文章内容有建议欢迎评论! DAO(Data Access Object,数据访问接口)设计模...
    1396 0
    |
    关系型数据库 Java 数据库
    DAO设计模式---实现一个简单的注册(上)
    DAO设计模式是属于Java Web中对数据层的具体操作,使用DAO设计模式可以简化大量代码的编写和增加程序的可移植性,可以很方便在日后对代码的修改。 如果在JSP中使用JDBC操作数据库,那样在JSP中就会嵌入大量的Java代码,显示和逻辑功能的代码混在一起,可读性差,难以维护。
    1327 0
    |
    SQL 设计模式
    DAO设计模式---实现一个简单的注册(中)
    4、DAO接口实现类: package com.song.Impl; import java.sql.*; import com.song.DAO.RegisterDAO; import com.
    900 0
    |
    Java 设计模式
    DAO设计模式---实现一个简单的注册(下)
    6、DAO工厂类: package com.song.DAOFactory; import com.song.DAO.RegisterDAO; import com.song.Impl.RegisterImpl; public class RegisterFactory{ publ...
    913 0
    |
    19天前
    |
    设计模式 SQL 算法
    设计模式了解哪些,模版模式
    设计模式了解哪些,模版模式
    19 0
    |
    1月前
    |
    设计模式 Java uml
    C++设计模式之 依赖注入模式探索
    C++设计模式之 依赖注入模式探索
    37 0
    |
    2月前
    |
    设计模式 前端开发 JavaScript
    观察者模式 vs 发布-订阅模式:两种设计模式的对决!
    欢迎来到前端入门之旅!这个专栏是为那些对Web开发感兴趣、刚刚开始学习前端的读者们打造的。无论你是初学者还是有一些基础的开发者,我们都会在这里为你提供一个系统而又亲切的学习平台。我们以问答形式更新,为大家呈现精选的前端知识点和最佳实践。通过深入浅出的解释概念,并提供实际案例和练习,让你逐步建立起一个扎实的基础。无论是HTML、CSS、JavaScript还是最新的前端框架和工具,我们都将为你提供丰富的内容和实用技巧,帮助你更好地理解并运用前端开发中的各种技术。