目錄
DAO設計模式
1.認識DAO
2.DAO各部分的詳解
3.DAO設計模式流程
DAO設計模式
1.認識DAO
DAO(Data Acess Object 數據庫訪問對象)的主要功能是操作數據庫,所以DAO在標準開發架構中數據數據層,以下是標準開發的架構
- 客戶層:目前使用B/S開發架構居多,客戶可以通過瀏覽器訪問
- 顯示層:使用Vue框架、 React框架、 JSP/Servlet等進行頁面展示
- 業務層:負責將DAO層的操作進行組合,形成一個完整的業務邏輯
- 數據層:提供原子性操作,比如增刪查改
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) ;
?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 ;}
}
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 ;}}}
}
?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 ;
}
?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 ;}
}
代理操作類
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;}
}
代理類只是調用了真實類中的方法,但是代理類可以讓代碼開發的結構更加清晰
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() ;}
}
?設計完所有類和接口后,為了保證定義后功能可用,則需要做一個測試類,來測試所有功能是否能夠正常使用
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) ;}}
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()) ;}}
}
?整體項目結構
這樣DAO層就開發完畢了