案例:MVC模式

是什么?

MVC是软件开发的一种设计规范 ,早在80年代的时候就被提出了。 它用一种业务逻辑、数据、界面显示分离的方法组织代码 , 极大的提高了我们在设计和开发上的效率
M  : Model【模型】
V   : View[【视图】
C     : Controller【控制】

有什么用?

MVC 实现了分层解耦, 将软件分成三个部分  M(模型层)  V(视图层)  C (控制层)  

V(视图层):负责对页面展示的处理, 在这一层上只针对 视图的展示

M(模型层):负责对C(控制层) 传输过来的数据,进行封装,打造成一个模型,交给视图层显示。 一般来说有可能是一个 JavaBean , 也有可能是EJB的来处理

C(控制层):控制层主要是 接收用户过来的请求, 然后去调用模型层处理数据,接着返回数据给客户端。

怎么用?

其实这是一种开发模式,并不是像我们平常写代码一样, 导入jar文件 然后 使用哪个类、哪个方法一样。 MVC 是针对我们的程序进行分层设计, 让我们在开发的时候,能够高效的去写代码。
以后如果相对程序进行扩展,那么只要按部就班的,在不同的层级下增删改代码即可。

以目前的阶段来开。 JSP + Servlet + JavaBean 就是一种MVC 的设计模式。 

控制层 :使用Servlet来接收 浏览器的请求, 并且对请求进行分析,然后调用对应的模型层来处理

模型层: 模型层的作用是 针对数据进行处理 然后返回给控制层。 那么在这里 Dao + Service + JavaBean 也可以算作是模型层的一部分
                当然未来大家学习到更深层次的知识,这部分就可以使用EJB来替代了。

视图层:视图层在这里将Jsp/html 归类到此层, 用于显示视图给用户看。 视图层只负责显示 , 从控制层那边拿过来模型数据显示

 学生管理系统案例

数据库准备:

CREATE DATABASE stus;
USE stus;
CREATE TABLE stu (
	sid INT PRIMARY KEY  AUTO_INCREMENT,
	sname VARCHAR (20),
	gender VARCHAR (5),
	phone VARCHAR (20),
	birthday DATE,
	hobby VARCHAR(50),
	info VARCHAR(200)
);

查询

1.    先写一个JSP 页面, 里面放一个超链接 。

<a href="StudentListServlet"> 学生列表显示</a>

2.    写Servlet, 接收请求, 去调用 Service  , 由service去调用dao

3.    先写Dao , 做Dao实现。

public interface StudentDao {
    /**
     *   查询所有学生
     * @return  List<Student>
     */
    List<Student> findAll()  throws SQLException ;
}
---------------------------------------------

public class StudentDaoImpl implements StudentDao {
    /**
     * 查询所有学生
     * @throws SQLException 
     */
	@Override
	public List<Student> findAll() throws SQLException {
		QueryRunner runner = new QueryRunner(JDBCUtil02.getDataSource());
		return runner.query("select * from stu", new BeanListHandler<Student>(Student.class));
	}
	
}

4.   再Service , 做Service的实现。

/**
 * 这是学生的业务处理规范
 * @author xiaomi
 *
 */
public interface StudentService {
    /**
	 * 查询所有学生
	 * @return  List<Student>
	 */
	List<Student> findAll()  throws SQLException ;
}
------------------------------------------
/**
 * 这是学生业务实现
 * @author xiaomi
 *
 */
public class StudentServiceImpl implements StudentService{
	@Override
	public List<Student> findAll() throws SQLException {
		StudentDao dao = new StudentDaoImpl();
		return dao.findAll();
	}
}

5. 在servlet 存储数据,并且做出页面响应。

protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
    try {
		//1、查询出所有学生
		StudentService service = new StudentServiceImpl();
		List<Student> list = service.finaAll();
		
		//2、将数据存到作用域中
		request.setAttribute("list", list);
		
		//3、跳转
		request.getRequestDispatcher("list.jsp").forward(request, response);
	} catch (SQLException e) {
		e.printStackTrace();
	}
}

6. 在list.jsp上显示数据

   EL + JSTL  + 表格

增加 

1. 先跳转到增加的页面 , 编写增加的页面

2. 点击添加,提交数据到AddServlet . 处理数据。

3. 调用service

4. 调用dao, 完成数据持久化。

5. 完成了这些存储工作后,需要跳转到列表页面。 这里不能直接跳转到列表页面,否则没有什么内容显示。 应该先跳转到查询所有学生信息的那个Servlet, 由那个Servlet再去跳转到列表页面

6. 爱好的value 值有多个。 

//String hobby = request.getParameter("hobby"); //篮球---->只显示一个参数

String[] hobbys = request.getParameterValues("hobby");//[篮球,足球,写字]
String hobby = Arrays.toString(hobbys);
hobby = hobby.substring(1, hobby.length()-1);

注意点:输入的生日是字符串,字符串转化为Date类型代码为
 

String birthday = request.getParameter("birthday");//"1980-8-9"
Date date = new SimpleDateFormat("yyyy-MM-dd").parse(birthday); 

删除

1. 点击超链接,弹出一个询问是否删除的对话框,如果点击了确定,那么就真的删除。

注意:删除的时候要将被删除学生的sid编号传过去,根据学生编号sid删除学生

<a href="#" onclick="doDelete(${stu.sid})">删除</a>

让超链接,执行一个js方法     

 <script type="text/javascript">
    function doDelete(sid) {
    /* 如果这里弹出的对话框,用户点击的是确定,就马上去请求Servlet。 
       如何知道用户点击的是确定。
       如何在js的方法中请求servlet。 */
    var flag = confirm("是否确定删除?");
    if(flag){
        //表明点了确定。 访问servlet。 在当前标签页上打开 超链接,
        //window.location.href="DeleteServlet?sid="+sid;
        location.href="DeleteServlet?sid="+sid;
        }
    }
</script>

2. 在js访问里面判断点击的选项,然后跳转到servlet。

3. servlet收到了请求,然后去调用service , service去调用dao

更新

1. 点击列表上的更新, 先跳转到一个EditServlet 

> 在这个Servlet里面,先根据ID 去查询这个学生的所有信息出来。

2. 跳转到更新的页面。 ,然后在页面上显示数据

其中部分jsp代码为:

<tr>
	<td>姓名</td>
	<td><input type="text" name="sname" value="${stu.sname }"></td>
</tr>

<tr>
    <!-- 如果性别是男的,  可以在男的性别 input标签里面, 出现checked ,
		 如果性别是女的,  可以在女的性别 input标签里面,出现checked -->
	<td>性别</td>
	<td><input type="radio" name="gender" value="男" <c:if test="${stu.gender=='男' }">checked</c:if>>男 
	<input type="radio" name="gender" value="女" <c:if test="${stu.gender=='女' }">checked</c:if>>女
	</td>
</tr>

<tr>
	<td>爱好</td>
	<!-- 爱好: 篮球 , 足球 , 看书 
       	因为爱好有很多个,  里面存在包含的关系 -->
	<td>
        <input type="checkbox" name="hobby" value="游泳" <c:if test="${fn:contains(stu.hobby,'游泳') }">checked</c:if>>游泳 
	    <input type="checkbox" name="hobby" value="篮球" <c:if test="${fn:contains(stu.hobby,'篮球') }">checked</c:if>>篮球 
		<input type="checkbox" name="hobby" value="足球" <c:if test="${fn:contains(stu.hobby,'足球') }">checked</c:if>>足球 
	    <input type="checkbox" name="hobby" value="看书" <c:if test="${fn:contains(stu.hobby,'看书') }">checked</c:if>>看书 
		<input type="checkbox" name="hobby" value="写字" <c:if test="${fn:contains(stu.hobby,'写字') }">checked</c:if>>写字
	</td>
</tr>

3. 修改完毕后,提交数据到UpdateServlet

> 提交上来的数据是没有带id的,所以我们要手动创建一个隐藏的输入框, 在这里面给定id的值, 以便提交表单,带上id。 

<form method="post" action="UpdateServlet">
	<input type="hidden" name="sid" value="${stu.sid }">
	...
</form>

4. 获取数据,调用service, 调用dao.

模糊查询

1、在列表页输入名字或者选择性别或按两者查询,点击查询按钮后,先跳转到SearchStudentServlet

>根据姓名或性别,或者两者都有 ,在这个Servlet里面,先根据  姓名/性别/二者 去查询学生的所有信息出来。Dao实现为:

/*
 * 这里要分析一下: 如果只有姓名,select * from stu where sname like ?; 如果只有性别,select * from
 * stu where gender = ?
 * 
 * 如果两个都有select * from stu where gender = ? and sname like ?
 * 
 * 如果两个都没有就查询所有。
 */
String sql = "select * from stu where 1=1";
List<String> list = new ArrayList<String>();

if (!TextUtil.isEmpty(sname)) {
	sql = sql + " and sname like ?";
	list.add("%" + sname + "%");
}
if (!TextUtil.isEmpty(gender)) {
	sql = sql + " and gender = ?";
	list.add(gender);
}
for (String str : list) {
	System.out.println("模糊查询:" + str);
}
return runner.query(sql, new BeanListHandler<Student>(Student.class), list.toArray());

2、跳转到列表页面,显示数据

分页显示

分页属于一个业务, 里面包含多个逻辑单元。
每一页的数据包含
:     
                class PageBean{
                    当前页        int currentPage
                    总页数       int totalPage
                    总记录数    int totalSize
                    每页记录数  int pageSize
                    该页的学生集合。 List<Student>
                }

1、在首页放置一个超链接

<a href="StudentListPageServlet?currentPage=1">分页列表显示</a>

2、Dao实现查询当前页的学生信息以及查询学生记录总数

/**
 * 查询当前页的学生
 * 
 * @throws SQLException
 */
@Override
public List<Student> findByPage(int currentPage) throws SQLException {
	// 第一个问号,代表一页返回多少条记录 , 第二个问号, 跳过前面的多少条记录。
	// 5 0 --- 第一页 (1-1)*5
	// 5 5 --- 第二页 (2-1)*5
	// 5 10 --- 第三页
	QueryRunner runner = new QueryRunner(JDBCUtil.getDataSource());
	return runner.query("select * from stu limit ? offset ?", new BeanListHandler<Student>(Student.class),
			PAGE_SIZE, (currentPage-1) * PAGE_SIZE);
}

@Override
public int count() throws SQLException {
	QueryRunner runner = new QueryRunner(JDBCUtil.getDataSource());
	//用于处理平均值、总的个数
	Long result = (Long)runner.query("select count(*) from stu",new ScalarHandler());
	return result.intValue();
}

ServiceImpl实现:将页面展示所需要的数据都封装到一个PageBean对象中

@Override
public PageBean finaByPage(int currentPage) throws SQLException {
	StuDao dao = new StuDaoImpl();
	
	//封装分页的该页数据
	PageBean<Student> pageBean = new PageBean<Student>();
		
	int pageSize = dao.PAGE_SIZE;
	pageBean.setList(dao.findByPage(currentPage)); //设置这一页的学生数据
	pageBean.setTotalSize(dao.count()); //总记录数
	pageBean.setCurrentPage(currentPage);//设置当前页
	pageBean.setPageSize(pageSize);//设置每页显示的记录数
		
	int count = dao.count();
	//200 , 10 ==20   201 , 10 = 21   201 % 10 == 0 ?201 / 10 :201 % 10 + 1
	pageBean.setTotalPage(count % pageSize == 0?count/pageSize:(count/pageSize)+1);//设置总页数
	return pageBean;
}

 3、写Servlet, 接收请求, 去调用 Service  , 由service去调用dao

4、list_page.jsp显示分页效果

<tr>
    <td colspan="8">
	第${pageBean.currentPage }页/共${pageBean.totalPage }页
	&nbsp;&nbsp;
	每页显示${pageBean.pageSize }条	&nbsp;&nbsp;&nbsp;
	总的记录数${pageBean.totalSize } &nbsp;&nbsp;&nbsp;
	<c:if test="${pageBean.currentPage !=1 }">
		<a href="StudentListPageServlet?currentPage=1">首页</a>
		<a href="StudentListPageServlet?currentPage=${pageBean.currentPage-1}">上一页</a>
	</c:if>
	<c:forEach begin="1" end="${pageBean.totalPage }" var="i">
		<c:if test="${pageBean.currentPage !=i }">
			<a href="StudentListPageServlet?currentPage=${i }">${i }</a>
		</c:if>
	</c:forEach>
				
	<c:if test="${pageBean.currentPage !=pageBean.totalPage }">
		<a href="StudentListPageServlet?currentPage=${pageBean.totalPage }">尾页</a>
		<a href="StudentListPageServlet?currentPage=${pageBean.currentPage+1}">下一页</a>
	</c:if>
    </td>
</tr>

 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值