Posted on 2008-08-02 00:48
freedoom 閱讀(3008)
評(píng)論(1) 編輯 收藏 所屬分類:
JAVA技術(shù)(好文保存)
DAO設(shè)計(jì)模式
1: 為什么使用DAO?
a: 在涉及數(shù)據(jù)庫(kù)操作,以前一般使用jdbc,使用這種方法我們會(huì)發(fā)現(xiàn)代碼和html標(biāo)簽同時(shí)使用,維
護(hù)很困難。
b:jsp文件中不應(yīng)該出現(xiàn)任何sql包,jsp文件側(cè)重于顯示界面的。
c:所有的數(shù)據(jù)庫(kù)操作建議使用prepareStatement。好處重在避免sql注入漏洞。
2:DAO是J2EE中的數(shù)據(jù)層操作。
3:數(shù)據(jù)庫(kù)創(chuàng)建腳本
--刪除表
DROP TABLE person;

--創(chuàng)建表
CREATE TABLE person
(
id varchar(20) not null primary key,
name varchar(20) not null,
password varchar(20) not null,
age varchar(20) not null,
email varchar(30) not null
);
--事務(wù)提交
commit;


4:如果在數(shù)據(jù)庫(kù)修改后,我們?cè)趺礃硬拍茏龅角芭_(tái)頁(yè)面不需要太多的改變?
我們必須規(guī)定出對(duì)PERSON中的全部操作。比如增刪查改。
按照以上要求,制定出操作那張表的標(biāo)準(zhǔn),之后只要針對(duì)不同的數(shù)據(jù)庫(kù)實(shí)現(xiàn)這些標(biāo)準(zhǔn)就可以了。 在java
中我們可以通過(guò)接口來(lái)實(shí)現(xiàn)----》DAO規(guī)定的就是這些接口。
package com.nnu.djx.dao;
import com.nnu.djx.vo.*;
import java.util.*;

//規(guī)定了在此項(xiàng)目中操作person表的全部方法

public interface PersonDao 
{

/** *//** *//** *//**
* 插入對(duì)象
* @throws Exception
*/
public void insert(Person person)throws Exception;

/** *//** *//** *//**
* 更新對(duì)象
* @throws Exception
*/
public void update(Person person)throws Exception;

/** *//** *//** *//**
* 刪除某一對(duì)象
* @param id
* @throws Exception
*
*/
public void delete(String id)throws Exception;

/** *//** *//** *//**
* 按照ID查詢
* @param id
* @return
* @throws Exception
*
*/
public Person queryById(String id)throws Exception;

/** *//** *//** *//**
* 查詢?nèi)拷Y(jié)果
* @return
* @throws Exception
*/
public List queryAll()throws Exception;

/** *//** *//** *//**
* 模糊查詢
* @param code
* @return
* @throws Exception
*/
public List queryByLike(String code)throws Exception;
}


5:在DAO中操作的是對(duì)象和數(shù)據(jù)庫(kù)之間的關(guān)系。
不過(guò)此時(shí)的對(duì)象是(VO,POLO,TO)(值對(duì)象,最簡(jiǎn)單對(duì)象,傳輸對(duì)象)
即是只包括getter,setter方法的類。
通過(guò)VO操作DAO
Vo中的字段和表中一一對(duì)應(yīng)。
package com.nnu.djx.vo;


public class Person 
{

private String id;
private String name;
private String password;
private int age;
private String email;
//生成getter,setter方法。

public int getAge() 
{
return age;
}

public void setAge(int age) 
{
this.age = age;
}

public String getEmail() 
{
return email;
}

public void setEmail(String email) 
{
this.email = email;
}

public String getId() 
{
return id;
}

public void setId(String id) 
{
this.id = id;
}

public String getName() 
{
return name;
}

public void setName(String name) 
{
this.name = name;
}

public String getPassword() 
{
return password;
}

public void setPassword(String password) 
{
this.password = password;
}
}


6: 對(duì)于定義好的接口,需要給出具體實(shí)現(xiàn)。對(duì)數(shù)據(jù)庫(kù)表的一切具體操作。
可以定義一個(gè)數(shù)據(jù)庫(kù)鏈接類,只負(fù)責(zé)連接。
package com.nnu.djx.dao.impl;

import java.util.List;
import com.nnu.djx.dao.*;
import com.nnu.djx.vo.Person;


public class PersonDaoImpl implements PersonDao 
{


public void delete(String id) throws Exception 
{
// TODO 自動(dòng)生成方法存根
}

public void insert(Person person) throws Exception 
{
// TODO 自動(dòng)生成方法存根
}

public List queryAll() throws Exception 
{
// TODO 自動(dòng)生成方法存根
return null;
}

public Person queryById(String id) throws Exception 
{
// TODO 自動(dòng)生成方法存根
return null;
}

public List queryByLike(String code) throws Exception 
{
// TODO 自動(dòng)生成方法存根
return null;
}

public void update(Person person) throws Exception 
{
// TODO 自動(dòng)生成方法存根
}


public PersonDaoImpl() 
{
// TODO 自動(dòng)生成構(gòu)造函數(shù)存根
}
}

具體的數(shù)據(jù)庫(kù)連接類如下:
package com.nnu.djx.dbc;
import java.sql.*;

public class DataBaseConnection 
{
private final String DBDRIVER ="oracle.jdbc.driver.OracleDriver";
private final String DBURL ="jdbc:oracle:thin:@localhost:1521:ora9djx";
private final String DBUSER ="system";
private final String DBPWD ="system";
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rst = null;

public DataBaseConnection()
{

try
{
Class.forName(DBDRIVER);
this.conn = DriverManager.getConnection(DBURL,DBUSER,DBPWD);

}catch(Exception e)
{
e.printStackTrace();
}
}
//取得數(shù)據(jù)庫(kù)鏈接

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

public void closeConnection()
{

try 
{
this.conn.close();

} catch (SQLException e) 
{
// TODO 自動(dòng)生成 catch 塊
e.printStackTrace();
}
}

}


5:再設(shè)計(jì)一個(gè)jsp頁(yè)面用來(lái)操作數(shù)據(jù)庫(kù),檢驗(yàn)前面的代碼是否正確。
<%@page contentType="text/html;charset=GB2312"%>
<%@page

import="com.nnu.djx.dao.*,com.nnu.djx.vo.*,com.nnu.djx.dao.impl.*,java.util.*,com.nnu.djx.fa

ctory.*"%>

<%
//進(jìn)行插入操作

/** *//**//*
Person person = new Person();
person.setId("001");
person.setName("why");
person.setPassword("123");
person.setAge(12);
person.setEmail("123j@163.com");
*/
PersonDao persondao = new PersonDaoImpl();
//PersonDaoFactory.getPersonDaoInstance().queryAll();
//刪除一個(gè)用戶

try
{
//persondao.insert(person);
//persondao.delete("001");
//persondao.update(person);
//全部查詢

/** *//**//*
List list = persondao.queryAll();
Iterator iterator = list.iterator();
while(iterator.hasNext())
{
Person person = (Person)iterator.next();
out.print(person.getName());
}
*/
//模糊查詢
List list = persondao.queryByLike("hy");
Iterator iterator = list.iterator();
while(iterator.hasNext())


{
Person person = (Person)iterator.next();
out.print(person.getName());
}

}catch(Exception e)
{
}
%>


DAO使用后,我們發(fā)現(xiàn)前天的代碼明顯減少,而后臺(tái)比如類都增多了。
同時(shí)可以發(fā)現(xiàn)這樣的一個(gè)問(wèn)題
PersonDao persondao = new PersonDaoImpl();
操作時(shí)必須知道子類。
如果有一天我們改變了數(shù)據(jù)庫(kù)(DB2)修改就不方便了。
應(yīng)該考慮如何是前臺(tái)代碼不關(guān)后臺(tái)的變化。。
此時(shí)可以考慮工廠模式:
新建一個(gè)類工廠類PersonDaoFactory
package com.nnu.djx.factory;

import com.nnu.djx.dao.PersonDao;
import com.nnu.djx.dao.impl.PersonDaoImpl;


public class PersonDaoFactory 
{

public static PersonDao getPersonDaoInstance()
{
return new PersonDaoImpl();
}
}


以后調(diào)用的時(shí)候就可以用
PersonDaoFactory.getPersonDaoInstance().queryAll();
而不具體涉及到類。。。
后序:
程序經(jīng)過(guò)驗(yàn)證完全正確,可以作為以后數(shù)據(jù)庫(kù)學(xué)習(xí)的模板。。