dao 设计模式

介绍

DAO功能是数据操作.
客户发送数据到显示层,显示层发送数据到业务层,业务发送数据到数据层,数据层进行持久化.即.保存进入databases

一些简称 BO 业务对象的简称 DAO 一个数据访问对象,增删查改 PO数据库一条记录,映射成javaBean对象,拥有getter/setter方法

为什么使用

把jdbc的操作进行分离,即数据库的操作和业务进行分离,javabean是把视图和业务进行分离,dao是把数据库的操作和业务逻辑进行分离.

DAO组成

VO

属性,get set 方法组成.VO是数据库中记录的映射.

DAO

定义操作的接口
用于定义数据库的原子化操作,增删查改

Impl

对接口的实现

Proxy

代理实现类,通过代理类,用来调用真实的对象的操作

Factory

工厂类,通过工厂,产生DAO实例化对象

DAO栗子

一个雇员表如下

NO列名称描述
1empno雇员编号 数字表示 长度4位
2ename雇员姓名 字符串表示 长度10位字符串
3job雇员工作
4hiredate雇佣日期
5sal基本工资 小数表示 小数2位 整数 5位

VO

数据库关系映射如下

package com.ming.vo;

import java.util.Date;
// 对数据库记录的映射
public class Emp {
    // 雇员编号
    private int empno;
    // 姓名
    private String ename;
    // 职位
    private String job;
    // 日期
    private Date hiredate;
    // 基本工资
    private float sal;

    public int getEmpno() {
        return empno;
    }

    public String getEname() {
        return ename;
    }

    public String getJob() {
        return job;
    }

    public Date getHiredate() {
        return hiredate;
    }

    public float getSal() {
        return 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;
    }
}

数据库连接

定义接口

package com.ming.dbc;

import java.sql.Connection;
// 数据库连接
public interface DataBaseConnection {
    public Connection getConnection();
    public void close() throws Exception;
}

实现该接口

package com.ming.dbc;

import java.sql.*;

// mysql数据库连接实栗
public class MysqlDatabaseConnection implements DataBaseConnection{
    private static final String DBDRIVER  = "com.mysql.cj.jdbc.Driver";
    private static final String DBURL = "jdbc:mysql://47.94.95.84:32786/test";
    private static final String DBUSER = "test";
    private static final String DBPASSWORD = "ABCcba20170607";
    private Connection connection = null;
    public MysqlDatabaseConnection() throws Exception {
        try{
            Class.forName(DBDRIVER);
            this.connection = DriverManager.getConnection(DBURL, DBUSER, DBPASSWORD);
        }catch (Exception e){
            throw e;
        }
    }
    // 获得连接
    @Override
    public Connection getConnection(){
        return this.connection;
    }
    // 关闭连接
    @Override
    public void close() throws Exception{
        if(this.connection != null){
            try{
                this.connection.close();
            }catch (Exception e){
                throw e;
            }
        }
    }
}

设置工厂

package com.ming.dbc;

// 数据库连接工厂
public class DatabaseConnectionFactory {
    // 获得实栗
    public static DataBaseConnection getDataBaseConnection() throws Exception{
        return new MysqlDatabaseConnection();
    }
}

dao

定义dao接口

package com.ming.dao;

import com.ming.vo.Emp;

import java.util.List;

// 定义dao接口
public interface IEmpDAO {
    /**
     * 数据库增加操作 以doXXX方式命名
     * @param emp 增加数据的对象
     * @return 成功标记
     * @throws Exception 异常继续向上抛出
    **/
    public boolean doCreate(Emp emp) throws Exception;

    /**
     *
     * 查询全部数据 一般以findXXXX命名
     * @param keyWord 查询关键字
     * @return 返回查询结果 一个Emp对象表示一行记录
     * @throws Exception 异常继续抛出
     */
    public List<Emp> findAll(String keyWorld) throws Exception;

    /**
     * 根据雇员编号查询雇员信息
     * @param empno 雇员编号
     * @return 雇员vo对象
     * @throws Exception 异常向上抛出
     */
    public Emp findByid(int empno) throws Exception;
}

实现接口

package com.ming.dao;

import com.ming.vo.Emp;
import com.mysql.cj.protocol.Resultset;

import javax.xml.transform.Result;
import java.sql.Connection;
import java.sql.Date;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;

// DAO实栗
public class EmpDAOImpl implements IEmpDAO {
    // 数据库连接对象
    private Connection connection = null;
    // 数据库操作方法
    private PreparedStatement preparedStatement = null;

    // 构造方法注入数据库连接
    public EmpDAOImpl(Connection _connection){
        this.connection = _connection;
    }

    /**
     * 数据库增加操作 以doXXX方式命名
     *  实现数据库增加操作
     * @param emp 增加数据的对象
     * @return 成功标记
     * @throws Exception 异常继续向上抛出
     **/
    @Override
    public boolean doCreate(Emp emp) throws Exception {
        // 定义标志位
        boolean flag = false;
        // sql
        String sql = "INSERT INTO emp(empno, ename, job, hiredate, sal) VALUES (?, ?, ?, ?, ?);";
        // 实例化操作对象
        this.preparedStatement = this.connection.prepareStatement(sql);
        // 赋值操作
        this.preparedStatement.setInt(1, emp.getEmpno());
        this.preparedStatement.setString(2, emp.getEname());
        this.preparedStatement.setString(3, emp.getJob());
        this.preparedStatement.setDate(4, new Date(emp.getHiredate().getTime()));
        this.preparedStatement.setFloat(5, emp.getSal());
        // 更新行数大于0
        if(this.preparedStatement.executeUpdate() > 0){
            flag = true;
        }
        this.preparedStatement.close();
        return flag;
    }

    /**
     * 查询全部数据 一般以findXXXX命名
     *
     * @param keyWorld@return 返回查询结果 一个Emp对象表示一行记录
     * @throws Exception 异常继续抛出
     */
    @Override
    public List<Emp> findAll(String keyWorld) 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.preparedStatement = this.connection.prepareStatement(sql);
        this.preparedStatement.setString(1, "%" + keyWorld + "%");
        this.preparedStatement.setString(2, "%" + keyWorld + "%");
        ResultSet resultSet = this.preparedStatement.executeQuery();
        Emp emp = null;
        while(resultSet.next()){
            emp = new Emp();
            emp.setEmpno(resultSet.getInt(1));
            emp.setEname(resultSet.getString(2));
            emp.setJob(resultSet.getString(3));
            emp.setHiredate(resultSet.getDate(4));
            emp.setSal(resultSet.getFloat(5));
            all.add(emp);
        }
        this.preparedStatement.close();
        return all;
    }

    /**
     * 根据雇员编号查询雇员信息
     *
     * @param empno 雇员编号
     * @return 雇员vo对象
     * @throws Exception 异常向上抛出
     */
    @Override
    public Emp findByid(int empno) throws Exception {
        // 声明Emp对象
        Emp emp = null;
        String sql = "SELECT empno, ename, job, hiredate, sal FROM emp WHERE empno = ?";
        this.preparedStatement = this.connection.prepareStatement(sql);
        this.preparedStatement.setInt(1, empno);
        ResultSet resultset = this.preparedStatement.executeQuery();
        if(resultset.next()){
            emp = new Emp();
            emp.setEmpno(resultset.getInt(1));
            emp.setEname(resultset.getString(2));
            emp.setJob(resultset.getString(3));
            emp.setHiredate(resultset.getDate(4));
            emp.setSal(resultset.getFloat(5));
        }
        this.preparedStatement.close();
        return emp;
    }
}

定义代理类

package com.ming.dao;

import com.ming.dbc.DataBaseConnection;
import com.ming.dbc.DatabaseConnectionFactory;
import com.ming.vo.Emp;

import java.util.List;

// 数据库连接代理类
public class EmpDAOProxy implements IEmpDAO{
    private DataBaseConnection dataBaseConnection = null;
    private IEmpDAO dao = null;
    // 实例化连接
    public EmpDAOProxy() throws Exception{
        // 获得连接对象
        dataBaseConnection = DatabaseConnectionFactory.getDataBaseConnection();
        // 实例化主题类
        this.dao = new EmpDAOImpl(dataBaseConnection.getConnection());
    }
    /**
     * 数据库增加操作 以doXXX方式命名
     *
     * @param emp 增加数据的对象
     * @return 成功标记
     * @throws Exception 异常继续向上抛出
     **/
    @Override
    public boolean doCreate(Emp emp) throws Exception {
        boolean flag = false;
        try{
            // 插入雇员编号不存在
            if(this.dao.findByid(emp.getEmpno()) == null){
                // 调用主题直接创建
                flag = this.dao.doCreate(emp);
            }
        }catch (Exception e){
            throw e;
        }finally {
            this.dataBaseConnection.close();
        }
        return flag;
    }

    /**
     * 查询全部数据 一般以findXXXX命名
     *
     * @param keyWorld@return 返回查询结果 一个Emp对象表示一行记录
     * @throws Exception 异常继续抛出
     */
    @Override
    public List<Emp> findAll(String keyWorld) throws Exception {
        List<Emp> all = null;
        try{
            all = this.dao.findAll(keyWorld);
        }catch (Exception e){
            throw e;
        }finally {
            this.dataBaseConnection.close();
        }
        return all;
    }

    /**
     * 根据雇员编号查询雇员信息
     *
     * @param empno 雇员编号
     * @return 雇员vo对象
     * @throws Exception 异常向上抛出
     */
    @Override
    public Emp findByid(int empno) throws Exception {
        Emp emp = null;
        try{
            emp = this.dao.findByid(empno);
        }catch (Exception e){
            throw  e;
        }finally {
            this.dataBaseConnection.close();
        }
        return emp;
    }
}

编写测试类

package com.ming.dao;

import com.ming.vo.Emp;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import javax.swing.text.html.HTMLDocument;
import javax.xml.crypto.Data;

import java.util.Date;
import java.util.Iterator;
import java.util.List;

import static org.junit.Assert.*;

public class EmpDAOProxyTest {
    EmpDAOProxy empDAOProxy = null;
    Emp emp = null;
    String keyWords = null;
    @Before
    public void setUp() throws Exception {
        empDAOProxy = new EmpDAOProxy();
        emp = new Emp();
        emp.setEname("ae3365eaa");
        emp.setEmpno(2223453);
        emp.setSal(23.2325624f);
        emp.setHiredate(new Date());
        emp.setJob("ming4654");
        keyWords = new String("ming4654");
    }

    @After
    public void tearDown() throws Exception {
    }

    @Test
    public void doCreate() throws Exception {
        if(empDAOProxy.doCreate(emp)){
            System.out.println("增加一条记录成功");
        }else{
            System.out.println("增加一条记录失败");
        }
    }

    @Test
    public void findAll() throws Exception {
        List<Emp> result = empDAOProxy.findAll(this.keyWords);
        // 迭代器遍历对象
        Iterator iterator = result.iterator();
        // 循环迭代
        while(iterator.hasNext()){
            Emp tmp = (Emp)iterator.next();
            System.out.println(emp.getEname() + emp.getJob() + emp.getEmpno() + emp.getHiredate() + emp.getSal());
        }
    }

    @Test
    public void findByid() throws Exception{
        int emp = 2223453;
        Emp tmp = empDAOProxy.findByid(emp);
        System.out.println(tmp.getEname());
    }
}

设置工厂

package com.ming.dao;

public class DAOFactory {
    public static IEmpDAO getIEmpDAOInstance() throws Exception{
        return new EmpDAOProxy();
    }
}

设置插入界面jsp

<%--
  Created by IntelliJ IDEA.
  User: ming
  Date: 19-3-16
  Time: 上午3:10
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>增加雇员</title>
</head>
<body>
<form action="./emp_insert_do.jsp" method="post">
    雇员编号 <input type="text" name="empno"/>
    雇员姓名 <input type="text" name="ename"/>
    职位 <input type="text" name="job"/>
    日期 <input type="text" name="hiredate"/>
    工资 <input type="text" name="sal"/>
    <input type="submit" value="注册"/>
    <input type="reset" value="恢复"/>
</form>
</body>
</html>

设置插入成功jsp

<%@ page import="com.ming.vo.Emp" %>
<%@ page import="com.ming.dao.DAOFactory" %>
<%@ page import="java.util.Date" %>
<%--
  Created by IntelliJ IDEA.
  User: ming
  Date: 19-3-16
  Time: 上午3:12
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<%
    Emp emp = new Emp();
    emp.setJob(request.getParameter("job"));
    emp.setEmpno(Integer.parseInt(request.getParameter("empno")));
    emp.setHiredate(new Date());
    emp.setEname("eee");
    emp.setSal(34.45f);
    try{
        if(DAOFactory.getIEmpDAOInstance().doCreate(emp)){
%>
    <h3>添加成功</h3>
<%
%>
<%
        }
    }catch (Exception e){
        e.printStackTrace();
    }
%>
</body>
</html>

dao 设计模式

相关推荐