詳解DAO模式(中)

詳解DAO模式(中)

  上一節我們講解了DAO模式的大概框架,現在回到我之前說的:



現在來一一剖析這個程序的各個類:
(一)vo包:

(1)Emp類:主要以數據庫表列名爲參考寫了類的屬性,以及各個屬性的setter和getter方法。代碼如下:

package vo;
import java.util.Date;
public class Emp {
	private int empID;
	private String empName;
	private String job;
	private Date hireDate;
	private float salary;

	public void setEmpID(int empID) {
		this.empID = empID;
	}
	public int getEmpID() {
		return empID;
	}

	public void setEmpName(String empName) {
		this.empName = empName;
	}
	public String getEmpName() {
		return this.empName;
	}

	public void setJob(String job) {
		this.job = job;
	}
	public String getJob() {
		return this.job;
	}

	public void setHireDate(Date hireDate) {
		this.hireDate = hireDate;
	}
	public Date getHireDate() {
		return this.hireDate;
	}

	public void setSalary(float salary) {
		this.salary = salary;
	}
	public float getSalary() {
		return this.salary;
	}
}

(二)dbc包:

(1)DatabaseConnection接口:它爲一個簡單的接口,在接口中抽象定義了getConnection()和close()兩個方法。代碼如下:

package dbc;
import java.sql.Connection;
public interface DatabaseConnection {
	public Connection getConnection();

	public void close();
}


(2)OracleDatabaseConnection類:根據用戶實際使用的數據庫Oracle,用oracle定義的連接方式實現了DatabaseConnection接口的兩個方法。代碼如下:

package dbc;
import java.sql.Connection;
import java.sql.DriverManager;
public class OracleDatabaseConnection implements DatabaseConnection {
	private static final String DRIVERCLASS = "oracle.jdbc.driver.OracleDriver";
	private static final String URL = "jdbc:oracle:thin:@localhost:1521:ORCL";
	private static final String USERNAME = "HYQ";
	private static final String PASSWORD = "123456";
	private Connection conn = null;

	public OracleDatabaseConnection() {
		try {
			Class.forName(DRIVERCLASS);
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}

		try {
			conn = DriverManager.getConnection(URL, USERNAME, PASSWORD);
			if (conn == null) {
				System.out.println("The \"conn\" is null !");
			} else {
				System.out.println("conn  --> " + conn);
				System.out.println(conn.hashCode());
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public Connection getConnection() {
		return this.conn;
	}

	public void close() {
		try {
			conn.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

(3)OracleDatabaseConnectionFactory類:使用靜態方法返回一個OracleDatabaseConnection類的實例化對象。代碼如下:

package dbc;
import dbc.OracleDatabaseConnection;
public class OracleDatabaseConnectionFactory {
	public static OracleDatabaseConnection getOracleDatabaseConnection() {
		return new OracleDatabaseConnection();
	}
}

(三)dao包:

(1)IEmpDAO接口:它是一個簡單的接口,該接口裏面仍舊是抽象的方法,以及附帶一些參數說明。接口定義了doCreat()、findAll()、findByID()三個抽象方法。代碼如下:

package dao;
import java.util.List;
import vo.Emp;

public interface IEmpDAO {
	/**
	 * 數據庫的增加操作,一般以doXxx形式命名
	 * 
	 * @param emp
	 *            要增加的數據對象
	 * @throws Exception
	 *             把異常交給調用類處理
	 * @return 是否增加成功的標識
	 */
	public boolean doCreat(Emp emp) throws Exception;

	/**
	 * 查詢全部數據,一般以findXxx形式命名
	 * 
	 * @param keyword
	 *            查詢的關鍵字
	 * @throws Exception
	 *             把異常交給調用類處理
	 * @return 返回全部查詢結果,一個Emp對象表示EMP表的一行記錄
	 */
	public List<Emp> findAll(String keyWord) throws Exception;

	/**
	 * 根據僱員的ID號查詢僱員,返回一個Emp對象
	 * 
	 * @param empID
	 *            僱員ID號
	 * @throws Exception
	 *             把異常交給調用類處理
	 * @return 返回僱員的vo對象
	 */

	public Emp findByID(int empID) throws Exception;
}

(2)EmpDAOImpl類:實現的是IEmpDAO接口,具體定義了接口的三個方法,不過沒有獲取數據庫連接。代碼如下:

package dao;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;
import vo.Emp;

public class EmpDAOImpl implements IEmpDAO {
	private Connection conn = null;
	private PreparedStatement ps = null;

	public EmpDAOImpl(Connection conn) {
		this.conn = conn;
	}

	public boolean doCreat(Emp emp) throws Exception {
		boolean flag = false;
		String sql = "INSERT INTO EMP(EMPID,EMPNAME,JOB,HIREDATE,SALARY)VALUES(?,?,?,?,?)";
		this.ps = this.conn.prepareStatement(sql);
		ps.setInt(1, emp.getEmpID());
		ps.setString(2, emp.getEmpName());
		ps.setString(3, emp.getJob());
		ps.setDate(4, new java.sql.Date(emp.getHireDate().getTime()));
		ps.setFloat(5, emp.getSalary());
		if (ps.executeUpdate() > 0) {
			flag = true;
		}
		this.ps.close();
		return flag;
	}

	public List<Emp> findAll(String keyWord) throws Exception {
		List<Emp> all = new ArrayList<Emp>();
		String sql = "SELECT EMPID,EMPNAME,JOB,HIREDATE,SALARY FROM EMP WHERE EMPNAME LIKE ? OR JOB LIKE ?";
		this.ps = this.conn.prepareStatement(sql);
		ps.setString(1, "%" + keyWord + "%");
		ps.setString(2, "%" + keyWord + "%");
		ResultSet rs = this.ps.executeQuery();
		Emp emp = null;
		while (rs.next()) {
			emp = new Emp();
			emp.setEmpID(rs.getInt(1));
			emp.setEmpName(rs.getString(2));
			emp.setJob(rs.getString(3));
			emp.setHireDate(rs.getDate(4));
			emp.setSalary(rs.getFloat(5));
			all.add(emp);
		}
		this.ps.close();
		return all;
	}

	public Emp findByID(int empID) throws Exception {
		Emp emp = null;
		String sql = "SELECT EMPID,EMPNAME,JOB,HIREDATE,SALARY FROM EMP WHERE EMPID = ?";
		this.ps = this.conn.prepareStatement(sql);
		ps.setInt(1, empID);
		ResultSet rs = ps.executeQuery();
		if (rs.next()) {
			emp = new Emp();
			emp.setEmpID(rs.getInt(1));
			emp.setEmpName(rs.getString(2));
			emp.setJob(rs.getString(3));
			emp.setHireDate(rs.getDate(4));
			emp.setSalary(rs.getFloat(5));
		}
		this.ps.close();
		return emp;
	}
}

(3)EmpDAOProxy類:負責獲取和關閉數據庫,同時通過調用EmpDAOImpl類中的方法實現了IEmpDAO接口。代碼如下:

package dao;
import java.util.List;
import vo.Emp;
import dbc.OracleDatabaseConnection;
import dbc.OracleDatabaseConnectionFactory;

public class EmpDAOProxy implements IEmpDAO {
	private OracleDatabaseConnection dbc = null;
	private IEmpDAO dao = null;

	public EmpDAOProxy() throws Exception {
		this.dbc = OracleDatabaseConnectionFactory
				.getOracleDatabaseConnection();
		this.dao = new EmpDAOImpl(this.dbc.getConnection());
	}

	public boolean doCreat(Emp emp) throws Exception {
		boolean flag = false;
		try {
			if (this.dao.findByID(emp.getEmpID()) == null) {
				flag = this.dao.doCreat(emp);
			}
		} catch (Exception e) {
			throw e;
		} finally {
			dbc.close();
		}
		return flag;
	}

	public List<Emp> findAll(String keyWord) throws Exception {
		List<Emp> all = null;
		try{
			all = this.dao.findAll(keyWord);
		}catch(Exception e){
			throw e;
		}finally{
			this.dbc.close();
		}
		return all;
	}

	public Emp findByID(int empID) throws Exception {
		Emp emp = null;
		try{
			emp = this.findByID(empID);
		}catch(Exception e){
			throw e;
		}finally{
			this.dbc.close();
		}
		return emp;
	}

}

(四)factory包:

(1)DAOFactory類:通過使用靜態方法返回EmpDAOProxy類的實例化對象。之所以使用靜態方法,是因爲不用new對象,大大節省了內存。在存在多個工廠類時效果更爲顯著。代碼如下:

package factory;
import dao.EmpDAOProxy;
import dao.IEmpDAO;

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

  最後,在Java類或JSP中需要進行數據庫的操作時,就可以使用DAOFactory類得到一個IEmpDAO實例化對象,使用對象內置的方法進行操作即可。


  好啦,那麼我們就來測試一下功能吧!
(1)添加功能,代碼如下:

package test;
import vo.Emp;
import factory.DAOFactory;

public class DAOTestInsert {
	public static void main(String[] args) throws Exception {
		Emp emp = null;
		for (int i = 1; i <= 10; i++) {
			emp = new Emp();
			emp.setEmpID(i);
			emp.setEmpName("HYQ--" + i);
			emp.setJob("Student");
			emp.setHireDate(new java.util.Date());
			emp.setSalary(i * 1000);
			DAOFactory.getIEmpDAOInstance().doCreat(emp);
		}
	}
}

效果測試圖:
在Myeclipse的console控制檯下執行成功的信息不斷的涌出來。



在Oracle的SQL developer的表中也出現了相關的數據,老夫數了一下,剛好10個。



(2)選擇功能,代碼如下:

package test;
import java.util.Iterator;
import java.util.List;
import vo.Emp;
import factory.DAOFactory;

public class DAOTestSelect {
	public static void main(String[] args) throws Exception {
		Emp emp = null;
		List<Emp> all = DAOFactory.getIEmpDAOInstance().findAll("");
		Iterator<Emp> iter = all.iterator();
		while (iter.hasNext()) {
			emp = iter.next();
			System.out.println(emp.getEmpID() + " 、 " + emp.getEmpName()
					+ " 、 " + emp.getJob() + " 、 " + emp.getHireDate() + " 、 "
					+ emp.getSalary());
		}
	}
}

效果測試圖:
因爲關鍵字爲空,使用檢索出全部信息。



下一節我們講解JSP中調用DAO實現數據的插入和查詢 —— 詳解DAO模式(下)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章