之前所学习的内容到昨天已经彻底告一段落(基本知识讲解完了),之后的内容将以代码的开发为主,如果在之前所学习的内容不是很透彻,你只要把今天所讲解的代码搞明白了,彻底会写了,写的很熟练了,那么一切就都不是问题。
4.1、关于设计分层的初步概念
在软件开发过程之中一定要存在有一个程序的层次概念,每一个程序层次都要完成某些具体的操作,而在一般情况下,分层的原则:不超过三层的原则,而常见的分层模式如下。
以上只是给出了一些层次的基本描述名称,但是严格来讲,每一层还会有更多的划分,如果是一个更加严格的划分,有可能划分成如下的形式。
对于业务层如果是一些简单的程序开发,以上的形式已经够使用了,但是很多时候还会遇见一些更为复杂的应用,那么业务层上还会继续进行划分。
今天的任务不是去研究控制层,也不是研究显示层,而专注于业务层与数据层,而且最为基本的操作是只存在一层业务。一直强调,业务层是整个项目的核心,而你们最大的特点是在业务层上表现。
那么下面就以刁雪冰后面站着听课为例,说明业务层和数据层的关联。
通过以上的分析就可以发现,一个业务层需要调用多个数据层,而数据层所提供的都是数据库的原子性操作(INSERT、UPDATE、DELETE、SELECT)。那么就可以给出概念:
· 数据层(数据访问层、持久层),一般会使用“Data Access Object”表示,简称为DAO,在DAO之中提供的是一系列的数据库操作标准(接口);
· 业务层(服务层),一般会使用“Service”表示,由于业务层最终也是要给控制层进行调用(今天给客户直接调用)、所以业务层也需要有一个自己的操作标准,而一个业务层就需要调用多个数据层。
4.2、实例分析
现在要求使用emp表(基本字段:empno、ename、job、hiredate、sal、comm)实现如下功能:
· 【业务层】实现新雇员的增加操作;
|- 〖数据层〗雇员的编号是由用户自己输入的,所以必须首先确定雇员编号是否存在,需要查询;
|- 〖数据层〗如果雇员编号不存在,则执行增加操作,更新;
· 【业务层】实现雇员的修改操作;
|- 〖数据层〗直接修改雇员数据;
· 【业务层】实现雇员的删除操作;
|- 〖数据层〗直接删除雇员数据;
· 【业务层】可以根据雇员编号查询出雇员的完整信息;
|- 〖数据层〗直接根据编号做限定查询;
· 【业务层】可以显示全部雇员记录;
|- 〖数据层〗查询雇员表的全部数据
· 【业务层】可以分页显示全部雇员记录,或者可以使用模糊查询进行关键字匹配,在返回全部记录的同时还需要返回本次查询的总数据量;
|- 〖数据层〗使用LIKE模糊查询查询满足条件的数据信息;
|- 〖数据层〗使用COUNT()函数统计满足条件的数据量。
通过以上的分析就可以清楚的发现,一个业务层还是调用了多个数据层,所以在日后用户所提出的全部要求的细分,基本上都是业务层分析,而只有确定了业务之后才可以确定出数据层。
4.3、代码的准备
首先需要打开Oracle的系统服务,而后建立一个新的项目 —— DAOProject,同时在项目之中配置好所需要的数据库驱动程序。
系统的开发之中需要有包的规范,现在假设父包名称为:cn.mldn.oracle。
4.3.1、数据库连接类:DatabaseConnection
在整个JDBC操作过程之中,数据库只有打开后才可以进行一系列的操作,而后数据库的连接又必须关闭。那么为了方便控制,可以直接将数据库的打开和关闭操作封装在一个类之中。
数据库的连接类保存包为“cn.mldn.oracle.dbc”,而且此数据库的连接只针对于Oracle定义。
范例:定义DatabaseConnection.java类
package cn.mldn.oracle.dbc;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
public class DatabaseConnection {
private static final String DBDRIVER = "oracle.jdbc.driver.OracleDriver" ;
private static final String DBURL = "jdbc:oracle:thin:@localhost:1521:MLDN" ;
private static final String DBUSER = "scott" ;
private static final String PASSWORD = "tiger" ;
private Connection conn ; // 准备出一个数据库连接对象
public DatabaseConnection() {
try {
Class.forName(DBDRIVER) ;
this.conn = DriverManager.getConnection(DBURL, DBUSER, PASSWORD) ;
} catch (Exception e) {
e.printStackTrace();
}
}
public Connection getConnection() {
return this.conn ;
}
public void close() {
if (this.conn != null) {
try {
this.conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
严格来讲以上的写法只是一个简便写法,因为日后是为了向框架开发靠拢,所有一些地方就需要做一些修改,而最早的时候,对于DAO设计模式的主要功能是为了解决掉数据库的可移植操作问题。
4.3.2、开发简单Java类
简单Java类指的就是类的结构比较单一,主要是由属性、setter/getter方法所组成,简单Java类的主要功能是作为一种数据的载体进行存放,而日后对于简单Java类也会出现如下的名称:POJO(简单Java类)、VO(值对象)、TO(DTO,数据传输对象,主要用于分布式)、PO(持久化对象)。可是对于简单Java类的组成结构在开发之中也有了明确要求:
· 简单Java类的最主要的设计思想来源于数据表,所以一定要和数据表的结构映射上;
· 简单Java类的名称要与数据表的名称保持一致,注意大小写,例如:member_info表,类:MemberInfo;
· 为了方便程序扩展,所有的简单Java类必须实现java.io.Serializable接口;
· 类之中的属性必须使用private封装,封装后的属性一定要编写setter、getter方法;
· 类之中一定要提供有无参构造方法;
· 类之中不允许使用基本数据类型,所有的基本类型要全部替换为包装类;
· 类之中不允许出现任何的输出语句,所有的输出必须交给被调用处执行;
· 类可以有选择性的覆写Object类的:equals()、hashCode()、toString()。
简单Java类要求保存在cn.mldn.oracle.vo包中。
范例:定义Member.java类
package cn.mldn.oracle.vo;
import java.io.Serializable;
import java.util.Date;
@SuppressWarnings("serial")
public class Emp implements Serializable {
private Integer empno ;
private String ename ;
private String job ;
private Date hiredate ;
private Double sal ;
private Double comm ;
// setter、getter略
}
此时类之中默认提供有一个无参构造方法,所以此时的类完全符合于简单Java类的开发标准。
4.4、开发数据层:DAO层
数据层又分称为持久层,指的是进行持久化数据操作的。持久层属于DAO层,所以在进行开发的时候首先要开发出操作的标准,而后进行子类的实现。
4.4.1、持久层标准
因为持久层最终要交给业务层进行调用,所以持久层必须有一个自己的操作接口,用于定义标准,但是此接口的命名是有要求的,如果当前操作的是emp表,那么这个接口应该命名为EmpDAO,但是为了区分接口还有类,所以现在要求在接口定义前增加一个字母I,所以emp表的持久层标准名称:IEmpDAO,而且此接口要保存在cn.mldn.oracle.dao下。
在数据层之中定义的方法严格来讲就只有两类:
· 数据更新操作:此类方法的命名以“doXxx()”的形式,例如:doCreate()、doUpdate()、doRemove();
· 数据查询操作:查询会分为两个小类:
|- 数据查询:此类方法以“findXxx()”命名,例如:findById()、findByJob()、findAll();
|- 统计查询:此类方法以“getXxx()”命名,例如:getAllCount()。
范例:定义IEmpDAO接口
package cn.mldn.oracle.dao;
import java.util.List;
import cn.mldn.oracle.vo.Emp;
public interface IEmpDAO {
public boolean doCreate(Emp vo) throws Exception ;
public boolean doUpdate(Emp vo) throws Exception ;
public boolean doRemove(Integer id) throws Exception ;
public Emp findById(Integer id) throws Exception ;
public List findAll() throws Exception ;
public List findAll(String column, String keyWord,
Integer currentPage, Integer lineSize) throws Exception;
public Integer getAllCount(String column,String keyWord) throws Exception ;
}
以后的工作之中一定要按照以上的要求编写注释信息,这才叫合格代码。
4.4.2、定义数据层实现类:EmpDAOImpl
接口标准定义完成之后,下面就可以进行实现类的编写,编写的实现类要保存在cn.mldn.oracle.dao.impl子包之中,而且名称后面一定要加上Impl。但是对于实现类,现在采用如下的方式编写。
范例:观察问题
@Override
public boolean doCreate(Emp vo) throws Exception {
String sql = "INSERT INTO emp(empno,ename,job,hiredate,sal,comm) VALUES (?,?,?,?,?,?)" ;
DatabaseConnection dbc = new DatabaseConnection() ;
Connection conn = dbc.getConnection() ;
PreparedStatement pstmt = conn.prepareStatement(sql) ;
pstmt.setInt(1, vo.getEmpno());
pstmt.setString(2, vo.getEname());
pstmt.setString(3, vo.getJob());
pstmt.setDate(4, new java.sql.Date(vo.getHiredate().getTime()));
pstmt.setDouble(5, vo.getSal());
pstmt.setDouble(6, vo.getComm());
if (pstmt.executeUpdate() > 0) {
return true ;
}
dbc.close();
return false;
}
如果此时的实现类按照如下的方式编写,可能存在有两个重要问题:
· 根据异常的处理来讲,如果在处理过程之中出现了数据库的更新异常,那么就再也关不上了,而且在本程序之中,如果更新成功直接返回了,也无法关闭;
· 一个业务层会调用多个数据层操作,现在把数据库的打开和关闭操作放在了数据层的每一个方法里面,这就意味着,一个业务操作的时候会打开和关闭数据库多次,那么可以将数据库的连接和关闭操作交给业务层处理;
范例:标准实现
package cn.mldn.oracle.dao.impl;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;
import cn.mldn.oracle.dao.IEmpDAO;
import cn.mldn.oracle.vo.Emp;
public class EmpDAOImpl implements IEmpDAO {
private Connection conn;
private PreparedStatement pstmt;
public EmpDAOImpl(Connection conn) {
this.conn = conn;
}
@Override
public boolean doCreate(Emp vo) throws Exception {
String sql = "INSERT INTO emp(empno,ename,job,hiredate,sal,comm) VALUES (?,?,?,?,?,?)";
this.pstmt = this.conn.prepareStatement(sql);
this.pstmt.setInt(1, vo.getEmpno());
this.pstmt.setString(2, vo.getEname());
this.pstmt.setString(3, vo.getJob());
this.pstmt.setDate(4, new java.sql.Date(vo.getHiredate().getTime()));
this.pstmt.setDouble(5, vo.getSal());
this.pstmt.setDouble(6, vo.getComm());
if (this.pstmt.executeUpdate() > 0) {
return true;
}
return false;
}
@Override
public boolean doUpdate(Emp vo) throws Exception {
String sql = "UPDATE emp SET ename=?,job=?,hiredate=?,sal=?,comm=? WHERE empno=?";
this.pstmt = this.conn.prepareStatement(sql);
this.pstmt.setString(1, vo.getEname());
this.pstmt.setString(2, vo.getJob());
this.pstmt.setDate(3, new java.sql.Date(vo.getHiredate().getTime()));
this.pstmt.setDouble(4, vo.getSal());
this.pstmt.setDouble(5, vo.getComm());
this.pstmt.setInt(6, vo.getEmpno());
if (this.pstmt.executeUpdate() > 0) {
return true;
}
return false;
}
@Override
public boolean doRemove(Integer id) throws Exception {
String sql = "DELETE FROM emp WHERE empno=?";
this.pstmt = this.conn.prepareStatement(sql);
this.pstmt.setInt(1, id);
if (this.pstmt.executeUpdate() > 0) {
return true;
}
return false;
}
@Override
public Emp findById(Integer id) throws Exception {
Emp vo = null;
String sql = "SELECT empno,ename,job,hiredate,sal,comm FROM emp WHERE empno=?";
this.pstmt = this.conn.prepareStatement(sql);
this.pstmt.setInt(1, id);
ResultSet rs = this.pstmt.executeQuery();
if (rs.next()) { // 有数据返回
vo = new Emp();
vo.setEmpno(rs.getInt(1));
vo.setEname(rs.getString(2));
vo.setJob(rs.getString(3));
vo.setHiredate(rs.getDate(4));
vo.setSal(rs.getDouble(5));
vo.setComm(rs.getDouble(6));
}
return vo;
}
@Override
public List findAll() throws Exception {
List all = new ArrayList();
String sql = "SELECT empno,ename,job,hiredate,sal,comm FROM emp";
this.pstmt = this.conn.prepareStatement(sql);
ResultSet rs = this.pstmt.executeQuery();
while (rs.next()) {
Emp vo = new Emp();
vo.setEmpno(rs.getInt(1));
vo.setEname(rs.getString(2));
vo.setJob(rs.getString(3));
vo.setHiredate(rs.getDate(4));
vo.setSal(rs.getDouble(5));
vo.setComm(rs.getDouble(6));
all.add(vo); // 向集合增加数据
}
return all;
}
@Override
public List findAll(String column, String keyWord,
Integer currentPage, Integer lineSize) throws Exception {
List all = new ArrayList();
String sql = "SELECT * FROM("
+ " SELECT empno,ename,job,hiredate,sal,comm,ROWNUM rn"
+ " FROM emp " + " WHERE " + column
+ " LIKE ? AND ROWNUM<=?) temp " + " WHERE temp.rn>? ";
this.pstmt = this.conn.prepareStatement(sql);
this.pstmt.setString(1, "%" + keyWord + "%");
this.pstmt.setInt(2, currentPage * lineSize);
this.pstmt.setInt(3, (currentPage - 1) * lineSize);
ResultSet rs = this.pstmt.executeQuery();
while (rs.next()) {
Emp vo = new Emp();
vo.setEmpno(rs.getInt(1));
vo.setEname(rs.getString(2));
vo.setJob(rs.getString(3));
vo.setHiredate(rs.getDate(4));
vo.setSal(rs.getDouble(5));
vo.setComm(rs.getDouble(6));
all.add(vo); // 向集合增加数据
}
return all;
}
@Override
public Integer getAllCount(String column, String keyWord) throws Exception {
String sql = "SELECT COUNT(empno) FROM emp WHERE " + column + " LIKE ?";
this.pstmt = this.conn.prepareStatement(sql);
this.pstmt.setString(1, "%" + keyWord + "%");
ResultSet rs = this.pstmt.executeQuery();
if (rs.next()) {
return rs.getInt(1);
}
return 0;
}
}
虽然代码较长,但是所有的代码都是标准的JDBC操作,而且每一个方法都只完成一个基本的原子性操作。
4.4.3、建立数据层工厂类
最终数据层是要交给业务层调用的,而业务层为了和数据层之间不产生耦合,所以不允许直接使用子类为数据层接口实例化,必须通过工厂类来完成,工厂应该保存在cn.mldn.oracle.factory包下。
范例:建立DAOFactory
package cn.mldn.oracle.factory;
import java.sql.Connection;
import cn.mldn.oracle.dao.IEmpDAO;
import cn.mldn.oracle.dao.impl.EmpDAOImpl;
public class DAOFactory {
public static IEmpDAO getIEmpDAOInstance(Connection conn) {
return new EmpDAOImpl(conn) ;
}
}
对于业务层在通过工厂类取得数据层接口实例的时候一定要传递连接对象。
4.5、开发业务层:Service层
数据层完成后最终一定要交给业务层进行调用,所以在业务层里面就需要通过工厂取得数据层接口对象,同时业务层由于最终也必须由控制层(本次不考虑控制层,只考虑客户端)调用,所以也需要制定业务层接口标准和相关的子类实现。
4.5.1、业务层操作标准
业务层的功能在之前已经建立完成了,而且现在的业务层依然是围绕emp表进行,所以业务层的接口名称就为IEmpService,保存在cn.mldn.oracle.service包之中。同时业务层的方法没有特别明确的标准,所以方法名称只要求有意义。
范例:定义IEmpService接口
package cn.mldn.oracle.service;
import java.util.List;
import java.util.Map;
import cn.mldn.oracle.vo.Emp;
public interface IEmpService {
public boolean insert(Emp vo) throws Exception ;
public boolean update(Emp vo) throws Exception ;
public boolean delete(int id) throws Exception ;
public Emp get(int id) throws Exception ;
public List list() throws Exception ;
public Map list(String column,String keyWord,int currentPage,int lineSize) throws Exception ;
}
在这个接口之中,关键性的问题在于list()方法上,此方法返回的是多种数据的集合,所以使用Map。
4.5.2、定义业务层实现类
如果要定义业务层实现类请一定要记住这个类要有两个功能:打开和关闭数据库(不管是否出异常, 数据库都要关闭)、调用数据层方法。
实现类保存在cn.mldn.oracle.service.impl子包之中。
范例:定义实现类
package cn.mldn.oracle.service.impl;
import java.sql.Connection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import cn.mldn.oracle.dao.IEmpDAO;
import cn.mldn.oracle.dbc.DatabaseConnection;
import cn.mldn.oracle.factory.DAOFactory;
import cn.mldn.oracle.service.IEmpService;
import cn.mldn.oracle.vo.Emp;
public class EmpServiceImpl implements IEmpService{
// 只要一实例化本类对象就自动取得了数据库连接
private DatabaseConnection dbc = new DatabaseConnection() ;
@Override
public boolean insert(Emp vo) throws Exception {
try {
Connection conn = this.dbc.getConnection() ;
IEmpDAO dao = DAOFactory.getIEmpDAOInstance(conn) ;
if (dao.findById(vo.getEmpno()) == null) { // 数据不存在
return dao.doCreate(vo); // 增加
}
return false;
} catch (Exception e) {
throw e;
} finally {
this.dbc.close();
}
}
@Override
public boolean update(Emp vo) throws Exception {
try {
return DAOFactory.getIEmpDAOInstance(this.dbc.getConnection())
.doUpdate(vo);
} catch (Exception e) {
throw e;
} finally {
this.dbc.close();
}
}
@Override
public boolean delete(int id) throws Exception {
try {
return DAOFactory.getIEmpDAOInstance(this.dbc.getConnection())
.doRemove(id);
} catch (Exception e) {
throw e;
} finally {
this.dbc.close();
}
}
@Override
public Emp get(int id) throws Exception {
try {
return DAOFactory.getIEmpDAOInstance(this.dbc.getConnection())
.findById(id);
} catch (Exception e) {
throw e;
} finally {
this.dbc.close();
}
}
@Override
public List list() throws Exception {
try {
return DAOFactory.getIEmpDAOInstance(this.dbc.getConnection())
.findAll();
} catch (Exception e) {
throw e;
} finally {
this.dbc.close();
}
}
@Override
public Map list(String column, String keyWord,
int currentPage, int lineSize) throws Exception {
try {
Map map = new HashMap() ;
map.put("allEmps",
DAOFactory.getIEmpDAOInstance(this.dbc.getConnection())
.findAll(column, keyWord, currentPage, lineSize));
map.put("empCount",
DAOFactory.getIEmpDAOInstance(this.dbc.getConnection())
.getAllCount(column, keyWord));
return map ;
} catch (Exception e) {
throw e;
} finally {
this.dbc.close();
}
}
}
现在的代码由于业务层的要求简单,所以服务层看起来也很容易,但是这些是日后的基础。
4.5.3、定义业务层工厂类
业务层最终也是需要交给其它层进行调用的,所以依然需要定义工厂类,以取得Service层接口对象。
范例:定义ServiceFactory
package cn.mldn.oracle.factory;
import cn.mldn.oracle.service.IEmpService;
import cn.mldn.oracle.service.impl.EmpServiceImpl;
public class ServiceFactory {
public static IEmpService getIEmpService() {
return new EmpServiceImpl() ;
}
}
这个时候一个最标准的后台代码就完成了。
4.6、程序测试
后台代码完成之后下面对于程序做一些测试,有两种测试方法:利用主方法编写、利用junit测试。
4.6.1、编写主方法测试
下面主要测试两个功能:一个增加、模糊查询。
范例:测试增加操作
package cn.mldn.oracle.test;
import java.util.Date;
import cn.mldn.oracle.factory.ServiceFactory;
import cn.mldn.oracle.vo.Emp;
public class TestEmpInsert {
public static void main(String[] args) throws Exception {
Emp vo = new Emp();
vo.setEmpno(8998);
vo.setEname("张吊三");
vo.setHiredate(new Date());
vo.setSal(8000.0);
vo.setJob("经理");
vo.setComm(1000.0);
System.out.println(ServiceFactory.getIEmpService().insert(vo));
}
}
范例:测试查询
package cn.mldn.oracle.test;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import cn.mldn.oracle.factory.ServiceFactory;
import cn.mldn.oracle.vo.Emp;
public class TestEmpList {
public static void main(String[] args) throws Exception {
Map map = ServiceFactory.getIEmpService().list("ename",
"", 2, 5);
List all = (List) map.get("allEmps");
Integer count = (Integer) map.get("empCount");
System.out.println("总数据量:" + count);
Iterator iter = all.iterator();
while (iter.hasNext()) {
System.out.println(iter.next());
}
}
}
这种的测试方式只是最原始的测试方式。
4.6.2、使用JUNIT测试
JUNIT测试最大的好处是可以返回GREEN BAR、RED BAR直观的视觉体验。
1、 选择要测试的接口:IEmpService;
2、 选择好接口后,选择新建。
3、 建立JUNIT中的Test Case。
4、 输入程序保存的包;
5、 选择要测试的方法
6、 在项目之中添加JUNIT的开发包
范例:编写junit测试程序
package cn.mldn.oracle.junit.test;
import java.util.Date;
import junit.framework.TestCase;
import org.junit.Test;
import cn.mldn.oracle.factory.ServiceFactory;
import cn.mldn.oracle.vo.Emp;
public class IEmpServiceTest {
@Test
public void testInsert() {
try {
Emp vo = new Emp();
vo.setEmpno(9999);
vo.setEname("张吊三");
vo.setHiredate(new Date());
vo.setSal(8000.0);
vo.setJob("经理");
vo.setComm(1000.0);
TestCase.assertTrue(ServiceFactory.getIEmpService().insert(vo));
} catch (Exception e) {
e.printStackTrace();
}
}
@Test
public void testUpdate() {
try {
Emp vo = new Emp();
vo.setEmpno(8998);
vo.setEname("小吊兵");
vo.setHiredate(new Date());
vo.setSal(1000.0);
vo.setJob("清洁工");
vo.setComm(-1000.0);
TestCase.assertTrue(ServiceFactory.getIEmpService().update(vo));
} catch (Exception e) {
e.printStackTrace();
}
}
@Test
public void testDelete() {
try {
TestCase.assertTrue(ServiceFactory.getIEmpService().delete(8887));
} catch (Exception e) {
e.printStackTrace();
}
}
@Test
public void testGet() {
try {
TestCase.assertNotNull(ServiceFactory.getIEmpService().get(7369));
} catch (Exception e) {
e.printStackTrace();
}
}
@Test
public void testList() {
try {
TestCase.assertTrue(ServiceFactory.getIEmpService().list().size() > 0);
} catch (Exception e) {
e.printStackTrace();
}
}
@Test
public void testListStringStringIntInt() {
try {
TestCase.assertTrue(ServiceFactory.getIEmpService()
.list("name", "", 1, 5).size() > 0);
} catch (Exception e) {
e.printStackTrace();
}
}
}
如果全部通过返回GREE BAR,表示测试通过。
4.7、开发部门操作
现在要求实现以下功能:
· 【业务层】增加部门数据:
|- 〖数据层〗先判断部门编号是否存在;
|- 〖数据层〗如果不存在执行部门增加
· 【业务层】修改部门数据:
|- 〖数据层〗执行部门修改
· 【业务层】删除部门数据:
|- 〖数据层〗删除部门数据
· 【业务层】根据编号查询部门数据:
|- 〖数据层〗根据编号查询
· 【业务层】查询全部部门数据:
|- 〖数据层〗查询全部
本操作从代码来讲要比emp简单。如果要想在之前的基础上开发本程序,则步骤如下:
1、 开发简单Java类;
package cn.mldn.oracle.vo;
import java.io.Serializable;
@SuppressWarnings("serial")
public class Dept implements Serializable {
private Integer deptno ;
private String dname ;
private String loc ;
}
2、 开发IDeptDAO接口,
package cn.mldn.oracle.dao;
import java.util.List;
import cn.mldn.oracle.vo.Dept;
public interface IDeptDAO {
public boolean doCreate(Dept vo) throws Exception ;
public boolean doUpdate(Dept vo) throws Exception ;
public boolean doRemove(Integer id) throws Exception ;
public List findAll() throws Exception ;
public Dept findById(Integer id) throws Exception ;
}
经过数据库的学习之后应该知道一点,数据库之中几乎每一张表都会存在这样的几个功能:增加、修改全部、删除数据、根据编号查询、查询全部、分页模糊查询。那么如果这些方法重复定义。
各个表的DAO实际上以上的公共操作只有VO不同、主键类型不同,基本操作方法都相同,那么重复定义,太麻烦了,所以此时可以针对于接口再次抽象。
此时的IDAO接口规定出了公共的方法标准,而各个表的DAO接口用于定义扩充方法。
package cn.mldn.oracle.dao;
import cn.mldn.oracle.vo.Dept;
public interface IDeptDAO extends IDAO{
}
3、 开发DeptDAOImpl子类
4、 修改DAOFactory类,增加新的接口对象取得;
5、 开发IDeptService接口;
6、 开发DeptServiceImpl子类;
7、 修改ServiceFactory类,增加新的接口对象取得;
8、 测试程序;
0 0