MVC+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和Scala中的Future