DAO设计模式
1
: 为什么使用DAO
?
a: 在涉及数据库操作,以前一般使用jdbc,使用这种方法我们会发现代码和html标签同时使用,维护很困难。
b:jsp文件中不应该出现任何sql包,jsp文件侧重于显示界面的。
c:所有的数据库操作建议使用prepareStatement。好处重在避免sql注入漏洞。
2
:DAO是J2EE中的数据层操作。
3
:数据库创建脚本
--
删除表
DROP TABLE person;
--
创建表
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
);
--
事务提交
commit;
4
:如果在数据库修改后,我们怎么样才能做到前台页面不需要太多的改变?
我们必须规定出对PERSON中的全部操作。比如增删查改。
按照以上要求,制定出操作那张表的标准,之后只要针对不同的数据库实现这些标准就可以了。 在java中我们可以通过接口来实现
----
》DAO规定的就是这些接口。
package
com.nnu.djx.dao;
import
com.nnu.djx.vo.
*
;
import
java.util.
*
;
//
规定了在此项目中操作person表的全部方法

public
interface
PersonDao
...
{ 
/** *//**
* 插入对象
* @throws Exception
*/
public void insert(Person person)throws Exception; 
/** *//**
* 更新对象
* @throws Exception
*/
public void update(Person person)throws Exception; 
/** *//**
* 删除某一对象
* @param id
* @throws Exception
*
*/
public void delete(String id)throws Exception;

/** *//**
* 按照ID查询
* @param id
* @return
* @throws Exception
*
*/
public Person queryById(String id)throws Exception; 
/** *//**
* 查询全部结果
* @return
* @throws Exception
*/
public List queryAll()throws Exception; 
/** *//**
* 模糊查询
* @param code
* @return
* @throws Exception
*/
public List queryByLike(String code)throws Exception;
}
5
:在DAO中操作的是对象和数据库之间的关系。
不过此时的对象是(VO,POLO,TO)(值对象,最简单对象,传输对象)
即是只包括getter,setter方法的类。
通过VO操作DAO
Vo中的字段和表中一一对应。
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
: 对于定义好的接口,需要给出具体实现。对数据库表的一切具体操作。
可以定义一个数据库链接类,只负责连接。
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 自动生成方法存根
} 
public void insert(Person person) throws Exception ...{
// TODO 自动生成方法存根
} 
public List queryAll() throws Exception ...{
// TODO 自动生成方法存根
return null;
} 
public Person queryById(String id) throws Exception ...{
// TODO 自动生成方法存根
return null;
} 
public List queryByLike(String code) throws Exception ...{
// TODO 自动生成方法存根
return null;
} 
public void update(Person person) throws Exception ...{
// TODO 自动生成方法存根
}

public PersonDaoImpl() ...{
// TODO 自动生成构造函数存根
}
}
具体的数据库连接类如下:
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();
}
}
//取得数据库链接 
public Connection getConnection()...{
return this.conn;
} 
public void closeConnection()...{ 
try ...{
this.conn.close(); 
} catch (SQLException e) ...{
// TODO 自动生成 catch 块
e.printStackTrace();
}
}
}
然后对于上面的具体实现。用prepareStatement实现。。
5
:再设计一个jsp页面用来操作数据库,检验前面的代码是否正确。
<%
@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.factory.*
"
%>
<%
//
进行插入操作

/**/
/*
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();
//
删除一个用户

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使用后,我们发现前天的代码明显减少,而后台比如类都增多了。
同时可以发现这样的一个问题
PersonDao persondao
=
new
PersonDaoImpl();
操作时必须知道子类。
如果有一天我们改变了数据库(DB2)修改就不方便了。
应该考虑如何是前台代码不关后台的变化。。
此时可以考虑工厂模式:
新建一个类工厂类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();
}
}
以后调用的时候就可以用
PersonDaoFactory.getPersonDaoInstance().queryAll();
而不具体涉及到类。。。
后序:
程序经过验证完全正确,可以作为以后数据库学习的模板。。












































































































































































































































































































































