非常详细的JSP DAO设计模式

时间:2021-01-12 20:49:07

原文地址:http://just-do-myself.iteye.com/blog/655227


DAO(Data Access Objects)设计模式是属于J2EE体系架构中的数据层的操作。

一、为什么要用DAO?

     比较在JSP页面中使用JDBC来连接数据库,这样导致了JSP页面中包含了大量的HTML代码和JSP代码,将显示和功能代码混在一起,难以维护。并且在JSP页面中使用JDBC代码,必须导入相应的"java.sql.*"包。基于使得JSP页面专注于数据的表现的思想,我们只是希望JSP主要负责数据的显示,而不需要关注数据的来源和途径。同时在JSP进行JDBC操作,重复编码太多。如,不同的页面连接同一个数据库时需要在每个页面中都进行JDBC编码。

  DAO设计模式提供了一种通用的模式,来简化大量的代码,增强程序的可移植性。

 

二、DAO组成

  DAO由5个重要部分组成:数据库连接类、VO、DAO接口、DAO实现类和DAO工厂类。

 


非常详细的JSP DAO设计模式

1、数据库连接类(DBConn):一个Java类。负责与后台数据库进行连接。提供了至少三个方法:

   构造方法 public DBConn():进行数据库连接,得到一个Connection对象。

   返回数据库连接Connection的public Connection getConnection():提供一个外部获取连接的方法,返回一个Connection对象。

   关闭数据库连接public void close():关闭数据库连接,Connection对象调用close方法。。

 

在JDBC中,进行数据库连接需要四个参数:数据库驱动类DBDriver、数据库连接URL、用户名、密码。注意需要在项目的构建路径下放入相应的数据库连接驱动软件包。

 

例:连接MySQL数据库下的JavaWeb数据库,用户名为root、密码为admin。

 DataBaseConnection.java

 

 

Java代码  非常详细的JSP DAO设计模式
  1. package db;  
  2.   
  3. import java.sql.* ;  
  4.   
  5. // 主要功能就是连接数据库、关闭数据库  
  6. public class DataBaseConnection{  
  7.     //定义数据库驱动类  
  8.     private final String DBDRIVER = "com.mysql.jdbc.Driver" ;  
  9.     //定义数据库连接URL  
  10.     private final String DBURL = "jdbc:mysql://localhost:3306/javaweb" ;  
  11.     //定义数据库连接用户名  
  12.     private final String DBUSER = "root" ;  
  13.     //定义数据库连接密码  
  14.     private final String DBPASSWORD = "admin" ;  
  15.     //定义数据库连接对象  
  16.     private Connection conn = null ;  
  17.     //构造方法,加载驱动  
  18.     public DataBaseConnection(){  
  19.         try{  
  20.             Class.forName(DBDRIVER) ;  
  21.             this.conn = DriverManager.getConnection(DBURL,DBUSER,DBPASSWORD) ;    
  22.         }  
  23.         catch (Exception e){  
  24.             System.out.println("加载驱动失败");  
  25.         }  
  26.     }  
  27.     // 取得数据库连接  
  28.     public Connection getConnection(){  
  29.         return conn ;  
  30.     }  
  31.     // 关闭数据库连接  
  32.     public void close(){  
  33.         try{  
  34.             conn.close() ;  
  35.         }catch (Exception e){  
  36.             System.out.println("数据库连接关闭失败");  
  37.         }         
  38.     }  
  39. }  

 

 

 同样,需要在项目的构建路径下放入Mysql的JDBC数据库驱动包:mysql-connector-java.jar.在附件中已上传了相应Jar包。

 

 

 

 

 

 

 

 

 

 

 

 

 

2、VO(Value Objects)值对象:与数据库表一一对应的Java类。含有与数据库表字段一一对应的属性,相应属性的getter和setter方法。甚至还有一些验证方法。VO提供了一个面向对象的方法来操作数据库。以后我们的DAO接口就是通过调用VO来进行数据库操作的。

例:对应于数据库表T_User:三个字段,id、username、password。相应的VO类

User.java

Java代码  非常详细的JSP DAO设计模式
  1. package db;  
  2.   
  3. public class User {  
  4.     //用户id  
  5.     private int userid;  
  6.     //用户姓名  
  7.     private String username;  
  8.     //用户密码  
  9.     private String password;  
  10.     //获得用户id  
  11.     public int getUserid(){  
  12.         return userid;  
  13.     }  
  14.     //设置用户id  
  15.     public void setUserid(int userid){  
  16.         this.userid = userid;  
  17.     }  
  18.     //获得用户名  
  19.     public String getUsername() {  
  20.         return username;  
  21.     }  
  22.     //设置用户名  
  23.     public void setUsername(String username) {  
  24.         this.username = username;  
  25.     }  
  26.     //获得用户密码  
  27.     public String getPassword() {  
  28.         return password;  
  29.     }  
  30.     //设置用户密码  
  31.     public void setPassword(String password) {  
  32.         this.password = password;  
  33.     }  
  34. }  

 

 

3、DAO接口:定义了所有的用户的操作,如添加记录、删除记录和查询记录等。这不是一个具体的实现类,而是一个接口,仅仅定义了相应的操作(方法),这是给后来的具体实现提供一种灵活性和易维护性。具体的实现需要具体实现类实现这个接口的方法来实现。

例:对上面的T_User表进行CRUD操作。

UserDAO.java

Java代码  非常详细的JSP DAO设计模式
  1. package db ;  
  2.   
  3. import java.util.* ;  
  4.   
  5. // 定义数据库操作方法  
  6. public interface UserDAO{  
  7.     // 增加操作  
  8.     public void insert(User user) throws Exception ;  
  9.     // 修改操作  
  10.     public void update(User user) throws Exception ;  
  11.     // 删除操作  
  12.     public void delete(int userid) throws Exception ;  
  13.     // 按ID查询操作  
  14.     public User queryById(int userid) throws Exception ;  
  15.     // 查询全部  
  16.     public List queryAll() throws Exception ;  
  17. }  

  

 

4、DAO实现类:这里才是具体的操作的实现。需要实现DAO接口以及相应的方法。

同样,一个DAO接口可以由多个实现。例如,上例中的可以有Mysql数据库来实现,也可以使用oracle数据库来实现。

同理,也可以是对同一数据库的不同实现。

例:DAO的Mysql实现。

UserDAOImpl.java

Java代码  非常详细的JSP DAO设计模式
  1. package db;  
  2.   
  3. import java.sql.PreparedStatement;  
  4. import java.sql.ResultSet;  
  5. import java.util.ArrayList;  
  6. import java.util.List;  
  7.   
  8. import com.javaweb.ch08.Person;  
  9.   
  10. public class UserDAOImpl implements UserDAO {  
  11.     //添加操作  
  12.     public void insert(User user) throws Exception {  
  13.         String sql = "INSERT INTO user(username,password) VALUES(?,?)" ;  
  14.         PreparedStatement pstmt = null ;  
  15.         DataBaseConnection dbc = null ;  
  16.         // 下面是针对数据库的具体操作  
  17.         try{  
  18.             // 连接数据库  
  19.             dbc = new DataBaseConnection() ;  
  20.             pstmt = dbc.getConnection().prepareStatement(sql) ;  
  21.             pstmt.setString(1, user.getUsername());  
  22.             pstmt.setString(2, user.getPassword());  
  23.             // 进行数据库更新操作  
  24.             pstmt.executeUpdate() ;  
  25.             pstmt.close() ;  
  26.         }catch (Exception e){  
  27.             throw new Exception("操作出现异常") ;  
  28.         }  
  29.         finally{  
  30.             // 关闭数据库连接  
  31.             dbc.close() ;  
  32.         }  
  33.     }  
  34.     //修改操作  
  35.     public void update(User user) throws Exception {  
  36.         String sql = "UPDATE user SET username=?,password=? WHERE userid=?" ;  
  37.         PreparedStatement pstmt = null ;  
  38.         DataBaseConnection dbc = null ;  
  39.         // 下面是针对数据库的具体操作  
  40.         try{  
  41.             // 连接数据库  
  42.             dbc = new DataBaseConnection() ;  
  43.             pstmt = dbc.getConnection().prepareStatement(sql) ;           
  44.             pstmt.setString(1, user.getUsername());  
  45.             pstmt.setString(2, user.getPassword());  
  46.             pstmt.setInt(3,user.getUserid());  
  47.             // 进行数据库更新操作  
  48.             pstmt.executeUpdate() ;  
  49.             pstmt.close() ;  
  50.         }  
  51.         catch (Exception e){  
  52.             throw new Exception("操作出现异常") ;  
  53.         }  
  54.         finally{  
  55.             // 关闭数据库连接  
  56.             dbc.close() ;  
  57.         }  
  58.     }  
  59.     //删除操作  
  60.     public void delete(int userid) throws Exception {  
  61.         String sql = "DELETE FROM user WHERE userid=?" ;  
  62.         PreparedStatement pstmt = null ;  
  63.         DataBaseConnection dbc = null ;  
  64.         // 下面是针对数据库的具体操作  
  65.         try{  
  66.             // 连接数据库  
  67.             dbc = new DataBaseConnection() ;  
  68.             pstmt = dbc.getConnection().prepareStatement(sql) ;           
  69.             pstmt.setInt(1,userid) ;  
  70.             // 进行数据库更新操作  
  71.             pstmt.executeUpdate() ;  
  72.             pstmt.close() ;  
  73.         }catch (Exception e){  
  74.             throw new Exception("操作出现异常") ;  
  75.         }  
  76.         finally{  
  77.             // 关闭数据库连接  
  78.             dbc.close() ;  
  79.         }  
  80.     }  
  81.     //按ID查询  
  82.     public User queryById(int userid) throws Exception {  
  83.         User user = null ;  
  84.         String sql = "SELECT * FROM user WHERE userid=?" ;  
  85.         PreparedStatement pstmt = null ;  
  86.         DataBaseConnection dbc = null ;  
  87.         // 下面是针对数据库的具体操作  
  88.         try{  
  89.             // 连接数据库  
  90.             dbc = new DataBaseConnection() ;  
  91.             pstmt = dbc.getConnection().prepareStatement(sql) ;           
  92.             pstmt.setInt(1, userid);  
  93.             // 进行数据库查询操作  
  94.             ResultSet rs = pstmt.executeQuery() ;  
  95.             if(rs.next())  
  96.             {  
  97.                 // 查询出内容,之后将查询出的内容赋值给user对象  
  98.                 user = new User() ;  
  99.                 user.setUserid(rs.getInt(1));  
  100.                 user.setUsername(rs.getString(2));  
  101.                 user.setPassword(rs.getString(3));  
  102.             }  
  103.             rs.close() ;  
  104.             pstmt.close() ;  
  105.         }catch (Exception e){  
  106.             throw new Exception("操作出现异常") ;  
  107.         }  
  108.         finally{  
  109.             // 关闭数据库连接  
  110.             dbc.close() ;  
  111.         }  
  112.         return user ;  
  113.     }  
  114.     public List<User> queryAll() throws Exception {  
  115.         List<User> all = new ArrayList<User>() ;  
  116.         String sql = "SELECT * FROM user " ;  
  117.         PreparedStatement pstmt = null ;  
  118.         DataBaseConnection dbc = null ;  
  119.   
  120.         // 下面是针对数据库的具体操作  
  121.         try{  
  122.             // 连接数据库  
  123.             dbc = new DataBaseConnection() ;  
  124.             pstmt = dbc.getConnection().prepareStatement(sql) ;   
  125.             // 进行数据库查询操作  
  126.             ResultSet rs = pstmt.executeQuery() ;  
  127.             while(rs.next()){  
  128.                 // 查询出内容,之后将查询出的内容赋值给user对象  
  129.                 User user = new User() ;  
  130.                 user.setUserid(rs.getInt(1));  
  131.                 user.setUsername(rs.getString(2));  
  132.                 user.setPassword(rs.getString(3));  
  133.   
  134.                 // 将查询出来的数据加入到List对象之中  
  135.                 all.add(user) ;  
  136.             }  
  137.             rs.close() ;  
  138.             pstmt.close() ;  
  139.         }  
  140.         catch (Exception e){  
  141.             throw new Exception("操作出现异常") ;  
  142.         }  
  143.         finally{  
  144.             // 关闭数据库连接  
  145.             dbc.close() ;  
  146.         }  
  147.         return all ;  
  148.     }  
  149. }  

  

5、DAO工厂类:在没有DAO工厂类的情况下,必须通过创建DAO实现类的实例才能完成数据库的操作。这时要求必须知道具体的实现子类,对于后期的修改十分不便。如后期需要创建一个该DAO接口的Oracle实现类。这时就必须修改所有使用DAO实现类的代码。如果使用DAO工厂类的一个静态方法(不需要创建对象即可调用)来获取DAO实现类实例,这时替换DAO实现类,只需修改DAO工厂类中的方法代码,而不需要修改所有的调用DAO实现的代码。

DAO工厂类是一个单例模式,这样避免的数据库的不一致。

例:通过DAO工厂类来获取具体的DAO实现类。

DAOFactory.java

Java代码  非常详细的JSP DAO设计模式
  1. package db;  
  2.   
  3. public class DAOFactory{  
  4.     public static UserDAO getUserDAOInstance(){  
  5.         return new UserDAOImpl() ;  
  6.     }  
  7. }  

  

这里若改变为Oracle实现类UserDAOOracleImpl来实现DAO,只需在DAOFactory中修改

Java代码  非常详细的JSP DAO设计模式
  1. package db;  
  2.   
  3. public class DAOFactory{  
  4.     public static UserDAO getUserDAOInstance(){  
  5.         <span style="background-color: #ff0000;">return new UserDAOOracleImpl()</span> ;  
  6.     }  
  7. }  

 

 有了上面五个部分,就可以通过DAO工厂类获取DAO实现类实例。通过调用DAO实现类实例中的方法就可以完成相应的数据库的CRUD操作。

 

三、表示层调用通过DAO工厂类获取DAO实现类实例的方法完成相应的操作。

1、添加记录:AddUserDemo.jsp

Jsp代码  非常详细的JSP DAO设计模式
  1. <%@ page language="java" contentType="text/html;charset=gb2312"%>  
  2. <%@ page import="db.*"%>  
  3. <html>  
  4. <head>  
  5.     <title>添加用户记录</title>  
  6. </head>  
  7. <body>  
  8.     <%  
  9.         //通过DAO工厂获得DAO实现类实例  
  10.         UserDAO userDAO = DAOFactory.getUserDAOInstance();  
  11.         //设置需要添加的用户  
  12.         User user = new User();  
  13.         user.setUsername("dao");  
  14.         user.setPassword("123");  
  15.         userDAO.insert(user);  
  16.     %>  
  17. </body>  
  18. </html>  

 

2、更新记录:UpdateUserDemo.jsp

 

Jsp代码  非常详细的JSP DAO设计模式
  1. <%@ page language="java" contentType="text/html;charset=gb2312"%>  
  2. <%@ page import="db.*"%>  
  3. <html>  
  4. <head>  
  5.     <title>更新用户记录</title>  
  6. </head>  
  7. <body>  
  8.     <%  
  9.         //通过DAO工厂获得DAO实现类实例  
  10.         UserDAO userDAO = DAOFactory.getUserDAOInstance();  
  11.         //设置需要更新的用户  
  12.         User user = new User();  
  13.         user.setUserid(10);  
  14.         user.setUsername("dao");  
  15.         user.setPassword("123456");  
  16.         //执行更新操作  
  17.         userDAO.update(user);  
  18.     %>  
  19. </body>  
  20. </html>  

 

3、删除记录:DeleteUserDemo.jsp

Jsp代码  非常详细的JSP DAO设计模式
  1. <%@ page language="java" contentType="text/html;charset=gb2312"%>  
  2. <%@ page import="db.*"%>  
  3. <html>  
  4. <head>  
  5.     <title>删除用户记录</title>  
  6. </head>  
  7. <body>  
  8.     <%  
  9.         //通过DAO工厂获得DAO实现类实例  
  10.         UserDAO userDAO = DAOFactory.getUserDAOInstance();  
  11.         //执行删除操作  
  12.         userDAO.delete(10);  
  13.     %>  
  14. </body>  
  15. </html>  

 

4、按ID查询记录:QueryByIdDemo.jsp

Jsp代码  非常详细的JSP DAO设计模式
  1. <%@ page language="java" contentType="text/html;charset=gb2312"%>  
  2. <%@ page import="db.*"%>  
  3. <html>  
  4. <head>  
  5.     <title>按ID查询记录</title>  
  6. </head>  
  7. <body>  
  8.     <%  
  9.         //通过DAO工厂获得DAO实现类实例  
  10.         UserDAO userDAO = DAOFactory.getUserDAOInstance();  
  11.         //指定按ID查询  
  12.         User user = userDAO.queryById(2);  
  13.         out.println("用户名:" + user.getUsername() + "<br>");  
  14.         out.println("密码:" + user.getPassword());  
  15.     %>  
  16. </body>  
  17. </html>  

 

5、查询所有记录:QueryAllUserDemo.jsp

Jsp代码  非常详细的JSP DAO设计模式
  1. <%@ page language="java" contentType="text/html;charset=gb2312"%>  
  2. <%@ page import="db.*"%>  
  3. <%@ page import="java.util.*"%>  
  4. <html>  
  5. <head>  
  6.     <title>查询所有记录</title>  
  7. </head>  
  8. <body>  
  9.     <%  
  10.         //通过DAO工厂获得DAO实现类实例  
  11.         UserDAO userDAO = DAOFactory.getUserDAOInstance();  
  12.         //查询所有用户  
  13.         List<User> all = userDAO.queryAll();  
  14.         Iterator<User> iter = all.iterator();  
  15.         //遍历输出所有用户信息  
  16.         while(iter.hasNext()) {  
  17.             User user = iter.next();  
  18.             out.println("用户名:" + user.getUsername());  
  19.             out.println(",密码:" + user.getPassword() + "<br>");  
  20.         }  
  21.     %>  
  22. </body>  
  23. </html>