MVC+DAO设计模式下的设计流程详解

 更新时间:2017年11月02日 10:19:15   作者:晓风well  
这篇文章主要介绍了MVC+DAO设计模式下的设计流程详解,分别介绍了数据库设计、设计符合java bean标准的entity类、设计访问数据库的DAO接口等内容,具有一定参考价值,需要的朋友可以了解下。

DAO设计 :

     DAO层主要是做数据持久层的工作,负责与数据库进行联络的一些任务都封装在此,DAO层的设计首先是设计DAO的接口,然后在Spring的配置文件中定义此接口的实现类,然后就可在模块中调用此接口来进行数据业务的处理,而不用关心此接口的具体实现类是哪个类,显得结构非常清晰,DAO层的数据源配置,以及有关数据库连接的参数都在Spring的配置文件中进行配置。

    在该层主要完成对象-关系映射的建立,通过这个映射,再通过访问业务对象即可实现对数据库的访问,使得开发中不必再用SQL语句编写复杂的数据库访问程序,这样就简化了对数据库的访问,提高了开发效率。同时通过对象-关系映射的配置,可以建立业务对象之间的复杂关系,如一对多、多对一、一对一、多对多等关系。这样就不再需要在数据库中建立表之间的复杂联系,使得业务对象之间的关系和数据库相分离,简化了数据库的建立和维护。在这一层中主要使用Hibernate框架来实现。

       针对以上问题,产生了基于MVC模式Model层的DAO模式(Data Access Object),主要由工厂类(Factory)、代理类(Proxy)、实现类(DAOImpl)、DAO接口和值对象类(VO)以及数据库连接类组成。

这里总结一下MVC+DAO的设计流程。通过MVC+DAO的设计模式,可以使项目在设计过程中结构更为明晰,并且能够方便的进行修改。MVC是一个分层模型,即模型、视图、控制器。DAO是一个数据库访问模型,隔离数据库操作。

环境说明:

数据库:mysql

开发语言:JSP + Servlet + Java

服务器:tomcat 7.x

包规划:

entity 放置与数据库中的表相对应的实体类
dao 放置DAO设计模式下实现访问数据库的接口
dao.impl 放置DAO对应的接口实现类
servlet 放置Servlet

util 工具包

设计流程综述:

0.设计数据库以及视图页面(VIEW)
1.设计数据库的工具类
2.设计符合java bean标准的entity类 (MODEL)
3.设计访问数据库的DAO接口
4.设计实现DAO接口的实现类
5.创建Servlet响应请求(CONTROLLER)

例子:以一个简单的登录页面设计为例

0.设计数据库以及视图页面

数据库设计:

CREATE TABLE `NewTable` ( 
`id` int(10) UNSIGNED ZEROFILL NOT NULL AUTO_INCREMENT , 
`name` varchar(10) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL , 
`password` varchar(10) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL , 
PRIMARY KEY (`id`) 
) 

页面视图:

index.jsp的核心代码如下:

<form action="/iMath/servlet/AdminServlet?method=login" method="post"> 
  <table border='1' align="center"> 
    <caption>USER LOGIN</caption> 
    <tr> 
      <th>username</th> 
      <th><input type="text" name="username" /></th> 
    </tr> 
    <tr> 
      <th>password</th> 
      <th><input type="password" name="password" /></th> 
    </tr> 
    <tr> 
      <td colspan="2" align="center"><input type="submit" value="submit" /></td> 
    </tr> 
  </table> 
</form> 

核心代码就是一个form表单,用于提供视图,为用户提供输入的接口。核心是指定action和method属性。这应该是最简单的一步,下面的工作则进入真正的代码编写阶段。

转发页面:

message.jsp核心代码如下:其实就句话

<body> 
 ${message} 
</body> 

1.设计数据库的工具类

这步的操作应该是大同小异的,目的只是抽取公共代码,简化程序流程。

dbConfig.properties 文件存放数据库的配置文件,这么做的优点的是可以项目编译后也能方便的修改数据库配置的相关信息。

driver = com.mysql.jdbc.Driver 
url = jdbc:mysql://127.0.0.1:3306/imath?useUnicode=true&characterEncoding=utf-8 
user = root 
password =1234 

DBUtil类设计:该类用实现建立数据库连接和关闭数据库连接的公共操作。

代码如下:

package cn.imath.util; 
import java.io.InputStream; 
import java.sql.Connection; 
import java.sql.DriverManager; 
import java.sql.ResultSet; 
import java.sql.SQLException; 
import java.sql.Statement; 
import java.util.Properties; 
public final class DBUtil { 
  private static String driver;  
  private static String url;  
  private static String user;  
  private static String password;  
  /** 
   * load the property file 
   */ 
  static{ 
    Properties props = new Properties();  
    //get the class loader 
    InputStream is = DBUtil.class.getClassLoader().getResourceAsStream("cn/imath/util/dbConfig.properties");  
    try {  
      props.load(is);  
    } catch (Exception e) {  
      e.printStackTrace();  
    }  
    driver = props.getProperty("driver");  
    url = props.getProperty("url");  
    user = props.getProperty("user");  
    password = props.getProperty("password"); 
  } 
  /** 
   * register the driver 
   */ 
  static{ 
    try { 
      Class.forName(driver); 
    } catch (ClassNotFoundException e) { 
      e.printStackTrace(); 
    } 
  } 
  /** 
   * OPEN THE DATABASE CONNECTION 
   * @return 
   */ 
  public static Connection getConn(){ 
    Connection conn = null; 
    try { 
      conn = DriverManager.getConnection(url, user, password); 
    } catch (SQLException e) { 
      e.printStackTrace(); 
    } 
    return conn; 
  } 
  /** 
   * CLOSE THE DATABASE CONNECTION 
   * @param rs 
   */ 
  public static void closeAll(ResultSet rs,Statement stmt,Connection conn){ 
    close(rs); 
    close(stmt); 
    close(conn); 
  } 
  public static void close(ResultSet rs){ 
    if(rs!=null){ 
      try { 
        rs.close(); 
      } catch (SQLException e) { 
        e.printStackTrace(); 
      } 
    } 
  } 
  public static void close(Statement stmt){ 
    if(stmt!=null){ 
      try { 
        stmt.close(); 
      } catch (Exception e) { 
        e.printStackTrace(); 
      } 
    } 
  } 
  public static void close(Connection conn){ 
    if(conn!=null){ 
      try { 
        conn.close(); 
      } catch (Exception e) { 
        e.printStackTrace(); 
      } 
    } 
  } 
} 

这里要注意的是:导入的包均为java.sql包。这里建立了两个核心方法,后面会经常用到 getConn() 和 closeAll()方法,分别用于取得数据库连接和关闭数据库连接。

2.设计符合java bean标准的entity类

这里的entity类对应于上面的admin表。因此设计Admin类如下:

package cn.imath.entity; 
public class Admin { 
  private int id; 
  private String name; 
  private String password; 
  public int getId() { 
    return id; 
  } 
  public void setId(int 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; 
  } 
} 

entity类的设计是为了实现对数据的封装,只要对照数据库设计来就行,然后最好符合java bean的设计标准,用getter/setter实现访问。

3.设计访问数据库的DAO接口

dao接口的设计非常简单,目的是为后面的具体的业务方法提供一个模版。

AdminDao接口如下:

package cn.imath.dao; 
import cn.imath.entity.Admin; 
public interface AdminDao { 
  /** 
   * LOGIN METHOD 
   * @param username 
   * @param password 
   * @return INSTANCE OF Admin 
   */ 
  public Admin login(String username,String password); 
} 

4.设计实现DAO接口的实现类

接下来设计上面DAO接口的实现类,用于实现具体的业务。这里就能体现上面模版的作用。

package cn.imath.dao.impl; 
import java.sql.Connection; 
import java.sql.PreparedStatement; 
import java.sql.ResultSet; 
import java.sql.SQLException; 
import cn.imath.dao.AdminDao; 
import cn.imath.entity.Admin; 
import cn.imath.util.DBUtil; 
public class AdminDaoImpl implements AdminDao { 
  /** 
   * LOGIN METHOD 
   */ 
  public Admin login(String username, String password) { 
    String sql = "select * from admin where name=? and password=? "; 
    Connection conn = DBUtil.getConn(); 
    try { 
      PreparedStatement pstmt = conn.prepareStatement(sql); 
      //set the query parameters 
      pstmt.setString(1,username); 
      pstmt.setString(2, password); 
      ResultSet rs = pstmt.executeQuery(); 
      if(rs.next()){ 
        int id = rs.getInt(1); 
        Admin ad = new Admin(); 
        ad.setId(id); 
        ad.setPassword(password); 
        ad.setName(username); 
        return ad; 
      } 
    } catch (SQLException e) { 
      e.printStackTrace(); 
    } 
    return null; 
  } 
} 

dao的实现类实现了具体的业务方法,封装了sql的相关操作。

5.创建Servlet响应请求

Servlet负责处理请求。

package cn.imath.servlet; 
import java.io.IOException; 
import java.io.PrintWriter; 
import javax.servlet.ServletException; 
import javax.servlet.http.HttpServlet; 
import javax.servlet.http.HttpServletRequest; 
import javax.servlet.http.HttpServletResponse; 
import cn.imath.dao.AdminDao; 
import cn.imath.dao.impl.AdminDaoImpl; 
import cn.imath.entity.Admin; 
public class AdminServlet extends HttpServlet { 
  public void doPost(HttpServletRequest request, HttpServletResponse response) 
      throws ServletException, IOException { 
    request.setCharacterEncoding("utf-8"); 
    String method = request.getParameter("method"); 
    if(method!=null){ 
      if("login".equals(method)){ 
        this.login(request,response); 
      } 
    } 
  } 
  private void login(HttpServletRequest request, HttpServletResponse response) { 
    String username = request.getParameter("username"); 
    String password = request.getParameter("password"); 
    AdminDao dao = new AdminDaoImpl(); 
    Admin ad = dao.login(username, password);  
    if(ad!=null){ 
      request.setAttribute("message", "Login Success"); 
    }else{ 
      request.setAttribute("message", "Login Failed"); 
    } 
    try { 
      request.getRequestDispatcher("/message.jsp").forward(request, response); 
    } catch (ServletException e) { 
      e.printStackTrace(); 
    } catch (IOException e) { 
      e.printStackTrace(); 
    } 
  } 
} 

这里将login方法独立于doPost方法,这样有助于对功能的扩充。

这里介绍的只是MVC+DAO的设计流程,通过这种模式可以改进项目的设计,使项目结构更为清晰,有了合理的方法,具体的项目才不致太混乱。最后,说一下需要改进的地方:

1.数据库的连接控制,可以用连接池进行改进,如DBCP或C3P0
2.数据库操作可以用common dbutils进行改进

总结

以上就是本文关于MVC+DAO设计模式下的设计流程详解的全部内容,希望对大家有所帮助。欢迎参阅:Spring MVC实现的登录拦截器代码分享SpringMVC使用MultipartFile 实现异步上传方法介绍Spring SpringMVC在启动完成后执行方法源码解析等,有什么问题,可以随时留言指出。感谢大家!

相关文章

  • Java时区转换及Date类实现原理解析

    Java时区转换及Date类实现原理解析

    这篇文章主要介绍了Java时区转换及Date类实现原理解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-11-11
  • Java基于PDFbox实现读取处理PDF文件

    Java基于PDFbox实现读取处理PDF文件

    PDFbox是一个开源的、基于Java的、支持PDF文档生成的工具库,它可以用于创建新的PDF文档,修改现有的PDF文档,还可以从PDF文档中提取所需的内容。本文将具体介绍一下PDFbox读取处理PDF文件的示例代码,感兴趣的可以学习一下
    2022-02-02
  • MyBatis-Puls插入或修改时某些字段自动填充操作示例

    MyBatis-Puls插入或修改时某些字段自动填充操作示例

    这篇文章主要为大家介绍了MyBatis-Puls插入或修改时某些字段自动填充操作示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-12-12
  • Springboot整合GuavaCache缓存过程解析

    Springboot整合GuavaCache缓存过程解析

    这篇文章主要介绍了springboot整合GuavaCache缓存过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-02-02
  • MyBatis中的mapper.xml配置教程

    MyBatis中的mapper.xml配置教程

    这篇文章主要介绍了MyBatis中的mapper.xml配置,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧
    2024-01-01
  • 解决spring懒加载以及@PostConstruct结合的坑

    解决spring懒加载以及@PostConstruct结合的坑

    这篇文章主要介绍了解决spring懒加载以及@PostConstruct结合的坑,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-12-12
  • 你知道Java的这些骚操作吗?

    你知道Java的这些骚操作吗?

    今天在看python相关的东西,看到各种骚操作,回头想了下Java有没有什么骚操作,整理下面几种,一起看一下吧,需要的朋友可以参考下
    2021-05-05
  • SpringBoot集成swagger的实例代码

    SpringBoot集成swagger的实例代码

    Swagger 是一款RESTFUL接口的文档在线自动生成+功能测试功能软件,这篇文章主要介绍了SpringBoot集成swagger,需要的朋友可以参考下
    2017-12-12
  • Junit Mockito实现单元测试方法介绍

    Junit Mockito实现单元测试方法介绍

    JUnit是用于编写和运行可重复的自动化测试开源测试项目框架,这样可以保证我们的代码按与其工作。JUnit可广泛用于工业和作为支架(从命令行)或IDE(如IDE)内单独的java程序
    2022-09-09
  • mybatis一对一查询功能

    mybatis一对一查询功能

    所谓的一对一查询,就是说我们在查询一个表的数据的时候,需要关联查询其他表的数据。这篇文章主要介绍了mybatis一对一查询功能,需要的朋友可以参考下
    2017-02-02

最新评论