一、DAO的设计思想
1.没有DAO的情况
当应用中没有DAO设计的时候,会出现什么问题.-->为了解决功能重复问题.
1.当只有一个客户端处理数据时,如下图,此时的设计,在客户端中编写了操作JDBC的代码.这从功能上分析,是没有问题的.
单客户端对DB的操作.png
2.但是上面的方法存在功能代码重复的问题。因为把功能代码编写在客户端中,此时若有3个客户端,则功能代码会重复3次.效果如下图:
多客户端对DB的操作.png
3.该问题的解决方案,我们从之前的开发经验入手去分析:
数组 :存储数据,把数据存储到内存中.
数据库:存储数据,把数据存储到磁盘中.
数组的相关操作:
1):把数据存储到数组.
2):取出数组中的数据.
3):修改数组中的数据.
4):删除数组中的数据.
此时,也是在每一个客户端中编写代码,如此一来,在每一个客户端中代码依然重复.编写一个数组的工具类:ArrayList.把所有和数组相关的CRUD操作封装在ArrayList类中.以后,客户端需要什么功能,就只需要创建ArrayList对象,并调用相应的方法即可(如下图).
数组的方式处理多客户端对DB的操作.png
2.DAO的介绍
DAO(Data Access Object)是一个数据访问接口,数据访问:顾名思义就是与数据库打交道。夹在业务逻辑与数据库资源中间。
在核心J2EE模式中是这样介绍DAO模式的:为了建立一个健壮的J2EE应用,应该将所有对数据源的访问操作抽象封装在一个公共API中。
用程序设计的语言来说,就是建立一个接口,接口中定义了此应用程序中将会用到的所有事务方法。在这个应用程序中,当需要和数据源进行交互的时候则使用这个接口,并且编写一个单独的类来实现这个接口在逻辑上对应这个特定的数据存储。
DAO中的主要操作:增删改查(CRUD).引入DAO之后,此时设计如下图:
DAO在逻辑上的关系.png
上面的设计图是使用了DAO思想之后的设计,
从功能的正确与否的角度分析没有问题,但是考虑设计save和get方法:
public void save(String name,Integer age){}
若参数过多,此时save方法的参数就会出现爆炸式增长.
public XXX get(Long id){}
此时查询指定ID的某一个学生信息,问题:XXX表示什么类型.
此时:若XXX表示String,就只能查询学生的名字.
若XXX表示Integer,就只能查询学生的名字.
那如果,我同时想得到学生的名字和年龄,怎么办?????
解决方案:把学生的信息封装成一个对象(Student).
数据对象的形式在DAO中处理.png
学生对象的DAO操作.png
二、DAO的规范
DAO其实是一个组件(可以重复使用),包括:
1.分包规范:
域名倒写.项目模块名.组件;
com.song.pss.domain; //装pss模块的domain类,模型对象.
com.song.pss.dao; //装pss模块的dao接口.
com.song.pss.dao.impl;//装pss模块的dao接口的实现类.
com.song.pss.test; //暂时存储DAO的测试类,以后的测试类不应该放这里.
包结构.png
2.声明类
dao对象的名字:xxxDAO,比如:employeeDAO/employeeDao,
Domain数据对象:以下的,Xxx都表示一个对象比如Employee,Department.
DAO 接口: IXxxDAO/IXxxDao, IEmployeeDAO/IEmployeeDao:仅仅是表示对Employee对象的CRUD的封装
DAO实现类: XxxDAOImpl/XxxDaoImpl,EmployeeDAOImpl/EmployeeDaoImpl:仅仅表示IEmployeeDAO的实现.
DAO测试类: XxxDAOTest:表名就是XxxDAO组件的测试类,应该测试DAO组件中的所有方法.
开发建议:面向接口编程,声明DAO对象:
(1) 传统的做法 :EmployeeDAOImpl dao = new EmployeeDAOImpl();
(2) 面向接口编程:IEmployeeDAO dao = new EmployeeDAOImpl();
把实现类赋给接口类型,体现多态的特性:可以屏蔽不同子类之间实现的差异.
public void show(List list){}
3.一般开发的顺序:
1):先建立模型对象:domain
2):编写DAO接口.
3):定义DAO实现类.
4):生产DAO测试类.
5):实现DAO实现类.
6):在DAO测试类中测试DAO方法.
4.调用:
show(new ArrayList()); //YES
show(new LinkedList()); //YES
三、DAO的实现
Student
public class Student {
private Long id;
private String name;
private int age;
public Long getId() {
return id;
}