DAO 設計模式

介紹

DAO功能是數據操作.
客戶發送數據到顯示層,顯示層發送數據到業務層,業務發送數據到數據層,數據層進行持久化.即.保存進入databases

一些簡稱 BO 業務對象的簡稱 DAO 一個數據訪問對象,增刪查改 PO數據庫一條記錄,映射成javaBean對象,擁有getter/setter方法

爲什麼使用

把jdbc的操作進行分離,即數據庫的操作和業務進行分離,javabean是把視圖和業務進行分離,dao是把數據庫的操作和業務邏輯進行分離.

DAO組成

VO

屬性,get set 方法組成.VO是數據庫中記錄的映射.

DAO

定義操作的接口
用於定義數據庫的原子化操作,增刪查改

Impl

對接口的實現

Proxy

代理實現類,通過代理類,用來調用真實的對象的操作

Factory

工廠類,通過工廠,產生DAO實例化對象

DAO栗子

一個僱員表如下

NO 列名稱 描述
1 empno 僱員編號 數字表示 長度4位
2 ename 僱員姓名 字符串表示 長度10位字符串
3 job 僱員工作
4 hiredate 僱傭日期
5 sal 基本工資 小數表示 小數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 = "";
    private static final String DBUSER = "test";
    private static final String DBPASSWORD = "";
    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>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章