MVC架构 项目实践
MVC
MVC指:Model模型、View视图、Controller控件器。
其中,各自的功能为:
View视图:为用户提供使用界面,与用户直接进行交互。
Model模型:承载数据,并对用户提交请求进行计算的模块。其分为两类,一类称为数据承载Bean,一类称为业务处理Bean。所谓数据承载Bean是指实体类,专门承载业务数据的,如Student、User等。而业务处理Bean则是指Service或Dao对象,专门用于处理用户提交请求的。
Controller控制器:用于将yoghurt请求转发给相应的Model进行处理,并处理Model的计算结果向用户提供相应响应。
MVC架构程序的工作流程:
(1)用户通过View页面向服务器端提出请求,可以是表单请求、超链接请求、AJAX请求等。
(2)服务端Controller控制器接收到请求后对请求进行解析,找到相应的Model对用户请求进行处理。
(3)Model处理后,将处理结果再交给Controller。
(4)Controller在接到处理结果后,根据处理结构找到要作为向客户端发回的View页面。页面经渲染(数据填充)后,再发送给客户端。
springmvc 中dao层和service层的区别
这个知识点转载自:
http://blog.csdn.net/dopamy_busymonkey/article/details/51422392
service是业务层,dao是数据访问层。
小白:在service里直接调用dao,service里面就new一个dao类对象,调用。
标准主流现在的编程方式都是采用MVC综合设计模式,MVC本身不属于设计模式的一种,它描述的是一种结构,最终目的达到解耦,解耦说的意思是你更改某一层代码,不会影响我其他层代码,如果你会像spring这样的框架,你会了解面向接口编程,表示层调用控制层,控制层调用业务层,业务层调用数据访问层。初期也许都是new对象去调用下一层,比如你在业务层new一个DAO类的对象,调用DAO类方法访问数据库,这样写是不对的,因为在业务层中是不应该含有具体对象,最多只能有引用,如果有具体对象存在,就耦合了。当那个对象不存在,我还要修改业务的代码,这不符合逻辑。好比主板上内存坏了,我换内存,没必要连主板一起换。我不用知道内存是哪家生产,不用知道多大容量,只要是内存都可以插上这个接口使用。这就是MVC的意义。
关于MVC与三层架构的解析学习参照之前转的博客:
项目实践
以下就是实战,利用MVC设计模式场景,实现一个小的登录功能。
项目目录:
项目实现流程:
1:首先进入登录页面,输入用户名和密码。
2:将用户名和密码通过form表单提交给Controller进行操作,调研Javabean将数据传至接口LoginServiceImpl中。
3:在LoginServiceImpl中,该类实现接口LoginDaoImpl中的login方法。并将数据传至UserDaoImpl接口。
4:在UserDaoImpl接口实现对数据的相关操作,根据数据结果进行相关判断及使用。其中UserDaoImpl实现接口UserDao。
5:UserDao接口定义查询方法,查询数据库中是否存在该用户。
Login.jsp——>LoginServelet—–>LoginServiceImpl—–>UserDao—–>UserDaoImp。
JSP登录页面(View层)
JSP登录页面:
在登录页面填写用户名和密码,通过form表单提交请求给Login.action。
<body>
<form action="login.action">
用户名:<input type="text" name="uname" value="${param.uname }"><br/>
密码:<input type="password" name="pwd" value="${param.pwd }"><br/>
<input type="submit" value="登录"><br/>
<span style="color: red;">${requestScope.error }</span>
</form>
<a href="register.jsp">没有账号,立即注册</a>
</body>
LoginServlet.java(Controller控制层)
通过登录页面将数据传至LoginServlet,java。
通过注解配置LoginServlet.java。
@WebServlet(value="/login.action")
LoginServlet.java实现代码:
@WebServlet(value="/login.action")
public class LoginServlet extends HttpServlet {
private LoginService service;
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doPost(request, response);
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String uname=request.getParameter("uname");
String pwd=request.getParameter("pwd");
//调用javabean
service=new LoginServiceImpl();
User user=service.login(uname, pwd);
//跳转jsp
if(user!=null) {
request.getSession().setAttribute("user", user);
response.sendRedirect("welcome.jsp");
} else {
request.setAttribute("error", "登录失败请重新输入");
request.getRequestDispatcher("login.jsp").forward(request, response);
}
}
}
LoginServiceImpl.java(实现接口LoginService)
LoginServiceImpl.java实现代码:
public class LoginServiceImpl implements LoginService {
private UserDao dao=new UserDaoImpl();
@Override
public User login(String uname, String pwd) {
// TODO Auto-generated method stub
//业务处理
User user=new User(uname,pwd);
return dao.findUser(user);
}
}
UserDao.java
接口UserDao,java中实现关于用户的数据访问的相关方法。
实现代码:
public interface UserDao {
//查询
User findUser(User user);
//删除
}
UserDaoImp.java(继承自Oracle数据库连接池,实现接口UserDao)
UserDaoImpl,java继承了JNDIBaseDao,实现从数据库中查找是否存在该数据,实现方法为UserDao中的查询方法。
public class UserDaoImpl extends JNDIBaseDao implements UserDao
实现代码:
public class UserDaoImpl extends JNDIBaseDao implements UserDao {
@Override
public User findUser(User user) {
// TODO Auto-generated method stub
//3.执行sql语句
//4.获取结果集
String sql = "select * from user where 1=1";
ArrayList list = new ArrayList();
if(user.getUname()!=null&&!user.getUname().equals("")){
sql+=" and uname=? ";
list.add(user.getUname());
}
ResultSet rs=executeQuery(sql, list.toArray());
//访问数据库查询是否存在该用户
try {
//登录成功
if(rs.next()) {
//把结果集转换成实体类
user.setUname(rs.getString("uname"));
user.setPwd(rs.getString("pwd"));
user.setId(rs.getInt("id"));
user.setSex(rs.getString("sex"));
user.setEmail(rs.getString("email"));
return user;
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//不存在该用户
return null;
}
}
JNDIBaseDao.java
在JNDIBaseDao中,通过连接池方法实现与Oracle数据库的交互,并实现对数据库之中的相关操作,如增删改查等。
实现代码:
public class JNDIBaseDao {
private DataSource source;
private Connection connection;
private PreparedStatement ps;
private ResultSet rs;
{
try {
Context ic = new InitialContext();
source = (DataSource)ic.lookup("java:comp/env/jdbc/test");
} catch (NamingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void getConnection() {
try {
connection=source.getConnection();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* 增删改操作
* @param sql
* @param objs
* @return 影响行数
*/
public int executeUpdate(String sql,Object... objs) {
if(connection==null) {
getConnection();
}
int res=-1;
try {
//设置手动提交事务
connection.setAutoCommit(false);
connection.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED);
ps=connection.prepareStatement(sql);
if(objs!=null) {
for(int i=0;i<objs.length;i++) {
ps.setObject(i+1, objs[i]);
}
}
res=ps.executeUpdate();
//手动提交事务
connection.commit();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
try {
connection.rollback();
} catch (SQLException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
} finally {
if(ps!=null) {
try {
ps.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
return res;
}
/**
* 查询操作
* @param sql
* @param objs
* @return
*/
public ResultSet executeQuery(String sql,Object... objs) {
if(connection==null) {
getConnection();
}
try {
ps=connection.prepareStatement(sql);
if(objs!=null) {
for(int i=0;i<objs.length;i++) {
ps.setObject(i+1, objs[i]);
}
}
rs=ps.executeQuery();
return rs;
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
public void closeAll() {
try {
if(rs!=null) {
rs.close();
}
if(ps!=null) {
ps.close();
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
BaseDao(JDBC交互数据库)
JDBC方式连接数据库与数据库实现相关交互操作。
public class BaseDao {
private String driver="oracle.jdbc.driver.OracleDriver";
private String url="jdbc:oracle:thin:@localhost:1521:jredu";
private String username="test";
private String password="Jredu12345";
private Connection connection;
private PreparedStatement ps;
private ResultSet rs;
public void getConnection() {
try {
Class.forName(driver);
connection=DriverManager.getConnection(url,username,password);
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* 增删改操作
* @param sql
* @param objs
* @return 影响行数
*/
public int executeUpdate(String sql,Object... objs) {
if(connection==null) {
getConnection();
}
try {
ps=connection.prepareStatement(sql);
if(objs!=null) {
for(int i=0;i<objs.length;i++) {
ps.setObject(i+1, objs[i]);
}
}
return ps.executeUpdate();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
closeStatement();
}
return 0;
}
/**
* 查询操作
* @param sql
* @param objs
* @return
*/
public ResultSet executeQuery(String sql,Object... objs) {
if(connection==null) {
getConnection();
}
try {
ps=connection.prepareStatement(sql);
if(objs!=null) {
for(int i=0;i<objs.length;i++) {
ps.setObject(i+1, objs[i]);
}
}
rs=ps.executeQuery();
return rs;
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
/**
* 关闭声明
*/
public void closeStatement() {
try {
if (ps != null) {
ps.close();
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* 把结果集和声明同时关闭
*/
public void closeAll() {
try {
if(rs!=null) {
rs.close();
}
if(ps!=null) {
ps.close();
}
if(connection!=null) {
connection.close();
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
至此,一个完整的MVC开发流程描述完毕,具体相关代码及操作,如有疑问可留言讨论,新手小白学习,还望大佬们赐教。如有雷同,纯属巧合。
MVC架构 项目实践的更多相关文章
- 使用Asp.Net Core MVC 开发项目实践[第一篇:项目结构说明]
先从下图看整体项目结构: Mango.Manager: 为后台管理项目 Mango.Web: 为前台项目 Mango.Framework.Core: 为常用的基础操作类项目 Mango.Framewo ...
- 使用Asp.Net Core MVC 开发项目实践[第五篇:缓存的使用]
项目中我们常常会碰到一些数据,需要高频率用到但是又不会频繁变动的这类,我们就可以使用缓存把这些数据缓存起来(比如说本项目的导航数据,帖子频道数据). 我们项目中常用到有Asp.Net Core 本身提 ...
- Asp.Net MVC大型项目实践整合 NHibernate与Json序列化
通过NHibernate我们多表查询是实现了 但由于查询出来的集合中的对象“不是平的”,如何在送到UI绑定成了问题.ExtJs UI组件的数据绑定支持多种格式,如简单数组,Json,Xml.在本项目中 ...
- 使用Asp.Net Core MVC 开发项目实践[第三篇:基于EF Core的扩展]
上篇我们说到了EFCore的基础使用,这篇我们将讲解下基于EFCore的扩展. 我们在Mango.Framework.EFCore类库项目中创建一个类名EFExtended的扩展类,并且引入相关的命名 ...
- 使用Asp.Net Core MVC 开发项目实践[第二篇:EF Core]
在项目中使用EF Core还是比较容易的,在这里我们使用的版本是EF Core 2.2. 1.使用nuget获取EF Core包 这个示例项目使用的是SQLSERVER,所以还需要下载Microsof ...
- 使用Asp.Net Core MVC 开发项目实践[第四篇:基于EF Core的扩展2]
上篇我们说到了基于EFCore的基础扩展,这篇我们讲解下基于实体结合拉姆达表达式的自定义更新以及删除数据. 先说下原理:其实通过实体以及拉姆达表达式生成SQL语句去执行 第一种更新扩展: 自定义更新字 ...
- MVC项目实践,在三层架构下实现SportsStore,从类图看三层架构
在"MVC项目实践,在三层架构下实现SportsStore-02,DbSession层.BLL层"一文的评论中,博友浪花一朵朵建议用类图来理解本项目的三层架构.于是就有了本篇: I ...
- MVC项目实践,在三层架构下实现SportsStore-02,DbSession层、BLL层
SportsStore是<精通ASP.NET MVC3框架(第三版)>中演示的MVC项目,在该项目中涵盖了MVC的众多方面,包括:使用DI容器.URL优化.导航.分页.购物车.订单.产品管 ...
- MVC项目实践,在三层架构下实现SportsStore-01,EF Code First建模、DAL层等
SportsStore是<精通ASP.NET MVC3框架(第三版)>中演示的MVC项目,在该项目中涵盖了MVC的众多方面,包括:使用DI容器.URL优化.导航.分页.购物车.订单.产品管 ...
随机推荐
- MySQL查询区分大小写敏感问题
由于mysql是不区分大小写的,所以当你查询的时候,例如数据库里有条数据用户名为UpYou(用户名唯一),当你输入:upyou时发现也可以查询,在某些需求下这样是不允许的,可以在查询语句中加入bina ...
- 设计模式之SOLID原则
介绍 设计模式中的SOLID原则,分别是单一原则.开闭原则.里氏替换原则.接口隔离原则.依赖倒置原则.前辈们总结出来的,遵循五大原则可以使程序解决紧耦合,更加健壮. SRP 单一责任原则 OCP 开放 ...
- mysql数据库限制多次登录失败,限定用户重试时间
前言 最近的项目开始进行安全测试,其中有一个安全问题是这样的. 应该增加用户登录失败处理功能,限制非法登录次数. 建议是增加mysql数据库的登陆失败的锁定功能. 相信大家也都会遇到这样的问题,在这里 ...
- MySQL中Exists和In的使用
Exists关键字: exists表示存在,是对外表做loop循环,每次loop循环再对内表(子查询)进行查询,那么因为对内表的查询使用的索引(内表效率高,故可用大表),而外表有多大都需要遍历,不可避 ...
- TypeLoadException: 未能从程序集“ECS.GUI.Define, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null”中加载类型“ECS.GUI.Define.ArmgAimPos”,因为它在 4 偏移位置处包含一个对象字段,该字段已由一个非对象字段不正确地对齐或重叠
TypeLoadException: 未能从程序集"ECS.GUI.Define, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null ...
- ssh升级以及ssh: symbol lookup error: ssh: undefined symbol: EVP_aes_128_ctr错误处理
1.解压安装openssl包:(不能卸载openssl,否则会影响系统的ssl加密库文件,除非你可以做两个软连接libcryto和libssl) # tar -zxvf openssl-1.0.1.t ...
- JVM 源码分析(四):深入理解 park / unpark
前言 Parker 源码调试与分析 park/unpark 原理总结 补充:jstack 命令和 kill 命令 前言 熟悉 Java 并发包的人一定对 LockSupport 的 park/unpa ...
- selenium自动化 | 通过获取cookies登录
>>>登录百度<<<#获取登录成功后的cookies def get_cookies(): driver.get(bd_url) driver.implicitly ...
- (二)数据源处理2-xlrd操作excel
import xlrd3workbook = xlrd3.open_workbook('test_data.xlsx')sheet =workbook.sheet_by_name('Sheet1')p ...
- DG主备切换遇到not allwod或者RESOLVABLE GAP解决办法
今天做switchover,环境是11.2.0.3+OEL5.7,开始时主备库状态都是正常的,符合直接切换条件: 主库: SQL> select open_mode,database_role, ...