企业分层架构:
资源层:主要是数据库的操作层,里面可以进行各种数据存储,但是这些数据存储操作的时候肯定依靠SQL语句,如果在一个程序中出现过多的SQL语句,JSP页面非常复杂,不便于程序的可重用性
数据层:一个专门操作数据库的组件
业务层(Business Object):整个项目的核心
显示层:使用JSP/Servlet进行页面效果的显示
客户层:现在基本采用B/S开发架构,用浏览器访问
DAO组成:
1. VO:由属性,setter,getter方法组成,VO类中的属性和表中的字段相对应,每个VO类的对象都是表中的每一条数据
2. DBC(DatabaseConnection):专门负责数据库打开与关闭操作的类
3. DAO:主要定义操作的接口,定义一系列数据库的原子性操作,例如增加,删除,修改,按ID查询
包含4,5两个包
4. Impl:DAO接口的真实实现类,完成具体的数据库操作,不负责数据库的打开和关闭
5. Proxy:代理实现类,主要完成数据库的打开和关闭,并且调用真实实现类对象的操作
6. Factory: 工厂类,通过工厂类取得一个DAO的实例化对象
VO类 emp.java:cnmldnlxhvo
package cn.mldn.lxh.vo ; import java.util.Date ; public class Emp { private int empno ; private String ename ; private String job ; private Date hiredate ; private float sal ; public void setEmpno(int empno){ this.empno = empno ; } public void setEname(String ename){ this.ename = ename ; } public void setJob(String job){ this.job = job ; } public void setHiredate(Date hiredate){ this.hiredate = hiredate ; } public void setSal(float sal){ this.sal = sal ; } public int getEmpno(){ return this.empno ; } public String getEname(){ return this.ename ; } public String getJob(){ return this.job ; } public Date getHiredate(){ return this.hiredate ; } public float getSal(){ return this.sal ; } }
DBC类: DatabaseConnection.java:cnmldnlxhdbc
package cn.mldn.lxh.dbc ; import java.sql.Connection ; import java.sql.DriverManager ; public class DatabaseConnection { //private static final String DBDRIVER = "org.gjt.mm.mysql.Driver" ; private static final String DBDRIVER = "com.mysql.jdbc.Driver" ; private static final String DBURL = "jdbc:mysql://localhost:3306/mldn" ; private static final String DBUSER = "root" ; private static final String DBPASSWORD = "linda0213" ; private Connection conn ; public DatabaseConnection() throws Exception { Class.forName(DBDRIVER) ; this.conn = DriverManager.getConnection(DBURL,DBUSER,DBPASSWORD) ; } public Connection getConnection(){ return this.conn ; } public void close() throws Exception { if(this.conn != null){ try{ this.conn.close() ; }catch(Exception e){ throw e ; } } } }
接口IEmpDAO.java: cnmldnlxhdao
注意接口方法命名:
数据库更新:doXXX
查询:findXXX,getXXX
package cn.mldn.lxh.dao ; import java.util.* ; import cn.mldn.lxh.vo.* ; public interface IEmpDAO { public boolean doCreate(Emp emp) throws Exception ; public List<Emp> findAll(String keyWord) throws Exception ; public Emp findById(int empno) throws Exception ; }
有了接口,下面是具体的实现类:EmpDAOImpl.java: 放在DAO的子包里: cnmldnlxhdaoimpl
package cn.mldn.lxh.dao.impl ; import java.util.* ; import java.sql.* ; import cn.mldn.lxh.dao.* ; import cn.mldn.lxh.vo.* ; public class EmpDAOImpl implements IEmpDAO { private Connection conn = null ; private PreparedStatement pstmt = null ; public EmpDAOImpl(Connection conn){ this.conn = conn ; } public boolean doCreate(Emp emp) throws Exception{ boolean flag = false ; String sql = "INSERT INTO emp(empno,ename,job,hiredate,sal) VALUES (?,?,?,?,?)" ; this.pstmt = this.conn.prepareStatement(sql) ; this.pstmt.setInt(1,emp.getEmpno()) ; this.pstmt.setString(2,emp.getEname()) ; this.pstmt.setString(3,emp.getJob()) ; this.pstmt.setDate(4,new java.sql.Date(emp.getHiredate().getTime())) ; this.pstmt.setFloat(5,emp.getSal()) ; if(this.pstmt.executeUpdate() > 0){ flag = true ; } this.pstmt.close() ; return flag ; } public List<Emp> findAll(String keyWord) throws Exception{ List<Emp> all = new ArrayList<Emp>() ; String sql = "SELECT empno,ename,job,hiredate,sal FROM emp WHERE ename LIKE ? OR job LIKE ?" ; this.pstmt = this.conn.prepareStatement(sql) ; this.pstmt.setString(1,"%"+keyWord+"%") ; this.pstmt.setString(2,"%"+keyWord+"%") ; ResultSet rs = this.pstmt.executeQuery() ; Emp emp = null ; while(rs.next()){ emp = new Emp() ; emp.setEmpno(rs.getInt(1)) ; emp.setEname(rs.getString(2)) ; emp.setJob(rs.getString(3)) ; emp.setHiredate(rs.getDate(4)) ; emp.setSal(rs.getFloat(5)) ; all.add(emp) ; } this.pstmt.close() ; return all ; } public Emp findById(int empno) throws Exception{ Emp emp = null ; String sql = "SELECT empno,ename,job,hiredate,sal FROM emp WHERE empno=?" ; this.pstmt = this.conn.prepareStatement(sql) ; this.pstmt.setInt(1,empno) ; ResultSet rs = this.pstmt.executeQuery() ; if(rs.next()){ emp = new Emp() ; emp.setEmpno(rs.getInt(1)) ; emp.setEname(rs.getString(2)) ; emp.setJob(rs.getString(3)) ; emp.setHiredate(rs.getDate(4)) ; emp.setSal(rs.getFloat(5)) ; } this.pstmt.close() ; return emp ; } }
代理实现类,主要完成数据库的打开和关闭,并且调用真实实现类对象的操作cnmldnlxhdaoproxyEmpDAOProxy.java;
package cn.mldn.lxh.dao.proxy ; import java.util.* ; import java.sql.* ; import cn.mldn.lxh.dao.* ; import cn.mldn.lxh.dbc.* ; import cn.mldn.lxh.dao.impl.* ; import cn.mldn.lxh.vo.* ; public class EmpDAOProxy implements IEmpDAO { private DatabaseConnection dbc = null ; private IEmpDAO dao = null ; public EmpDAOProxy() throws Exception { this.dbc = new DatabaseConnection() ; this.dao = new EmpDAOImpl(this.dbc.getConnection()) ; } public boolean doCreate(Emp emp) throws Exception{ boolean flag = false ; try{ if(this.dao.findById(emp.getEmpno()) == null){ flag = this.dao.doCreate(emp) ; } }catch(Exception e){ throw e ; }finally{ this.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 empno) throws Exception{ Emp emp = null ; try{ emp = this.dao.findById(empno) ; }catch(Exception e){ throw e ; }finally{ this.dbc.close() ; } return emp ; } }
Factory: 工厂类 cnmldnlxhfactoryDAOFactory.java:
package cn.mldn.lxh.factory ; import cn.mldn.lxh.dao.IEmpDAO ; import cn.mldn.lxh.dao.proxy.EmpDAOProxy ; public class DAOFactory { public static IEmpDAO getIEmpDAOInstance() throws Exception{ return new EmpDAOProxy() ; } }
测试程序:TestDAOInsert.java:
package cn.mldn.lxh.dao.test ; import cn.mldn.lxh.factory.DAOFactory ; import cn.mldn.lxh.vo.* ; public class TestDAOInsert{ public static void main(String args[]) throws Exception{ Emp emp = null ; for(int x=0;x<5;x++){ emp = new Emp() ; emp.setEmpno(1000 + x) ; emp.setEname("李兴华 - " + x) ; emp.setJob("程序员 - " + x) ; emp.setHiredate(new java.util.Date()) ; emp.setSal(500 * x) ; DAOFactory.getIEmpDAOInstance().doCreate(emp) ; } } }
测试程序:TestDAOSelect.java:
package cn.mldn.lxh.dao.test ; import java.util.* ; import cn.mldn.lxh.factory.DAOFactory ; import cn.mldn.lxh.vo.* ; public class TestDAOSelect{ public static void main(String args[]) throws Exception{ List<Emp> all = DAOFactory.getIEmpDAOInstance().findAll("") ; Iterator<Emp> iter = all.iterator() ; while(iter.hasNext()){ Emp emp = iter.next() ; System.out.println(emp.getEmpno() + "、" + emp.getEname() + " --> " + emp.getJob()) ; } } }
当DAO开发完成之后,下面就利用JSP完成DAO程序的调用: emp_insert.jsp:
<%@ page contentType="text/html" pageEncoding="GBK"%> <html> <head><title>www.mldnjava.cn,MLDN高端Java培训</title></head> <body> <form action="emp_insert_do.jsp" method="post"> 雇员编号:<input type="text" name="empno"><br> 雇员姓名:<input type="text" name="ename"><br> 雇员职位:<input type="text" name="job"><br> 雇佣日期:<input type="text" name="hiredate"><br> 基本工资:<input type="text" name="sal"><br> <input type="submit" value="注册"> <input type="reset" value="重置"> </form> </body> </html>
处理emp_insert_do.jsp:
<%@ page contentType="text/html" pageEncoding="GBK"%> <%@ page import="cn.mldn.lxh.factory.*,cn.mldn.lxh.vo.*"%> <%@ page import="java.text.*"%> <html> <head><title>www.mldnjava.cn,MLDN高端Java培训</title></head> <% request.setCharacterEncoding("GBK"); %> <body> <% Emp emp = new Emp() ; emp.setEmpno(Integer.parseInt(request.getParameter("empno"))) ; emp.setEname(request.getParameter("ename")) ; emp.setJob(request.getParameter("job")) ; emp.setHiredate(new SimpleDateFormat("yyyy-MM-dd").parse(request.getParameter("hiredate"))) ; emp.setSal(Float.parseFloat(request.getParameter("sal"))) ; try{ if(DAOFactory.getIEmpDAOInstance().doCreate(emp)){ %> <h3>雇员信息添加成功!</h3> <% } else { %> <h3>雇员信息添加失败!</h3> <% } %> <% }catch(Exception e){ e.printStackTrace() ; } %> </body> </html>
显示信息emp_list.jsp:
<%@ page contentType="text/html" pageEncoding="GBK"%> <%@ page import="cn.mldn.lxh.factory.*,cn.mldn.lxh.vo.*"%> <%@ page import="java.util.*"%> <html> <head><title>www.mldnjava.cn,MLDN高端Java培训</title></head> <% request.setCharacterEncoding("GBK") ; %> <body> <% String keyWord = request.getParameter("kw") ; if(keyWord == null){ keyWord = "" ; // 如果没有查询关键字,则查询全部 } List<Emp> all = DAOFactory.getIEmpDAOInstance().findAll(keyWord) ; Iterator<Emp> iter = all.iterator() ; %> <center> <form action="emp_list.jsp" method="post"> 请输入查询关键字:<input type="text" name="kw"> <input type="submit" value="查询"> </form> <table border="1" width="80%"> <tr> <td>雇员编号</td> <td>雇员姓名</td> <td>雇员工作</td> <td>雇佣日期</td> <td>基本工资</td> </tr> <% while(iter.hasNext()){ Emp emp = iter.next() ; %> <tr> <td><%=emp.getEmpno()%></td> <td><%=emp.getEname()%></td> <td><%=emp.getJob()%></td> <td><%=emp.getHiredate()%></td> <td><%=emp.getSal()%></td> </tr> <% } %> </table> </center> </body> </html>
可以发现,一个JSP页面中不导入SQL包,如果有可能,一个包都不要导入。
总结:
可以发现,使用JSP+DAO的开发之后,程序更加清晰,而且以后所有的数据层操作可以任意移植,不一定非要在JSP上使用。
通过JSP+JavaBean的开发模式,也称为Model I, 通过JSP显示,通过JavaBean完成功能,达到显示和操作分离。