JavaWeb.11.三层架构

三层架构
三层?哪三层?
显示层、业务逻辑层、数据访问层
1.表示层:位于最外层 ( 最上层 ),使用户能够直接访问,用于显示数据和接收用户输入的数据,为用户提供一种交互式操作界面。在 Web 应用程 序中,表示层一般以 JSP 文件、HTML文件为主;
2.业务逻辑层:其主要功能是提供对业务逻辑处理的封装,在业务逻辑层中,通常会定义些接口,表示层通过调用业务逻辑层的接口实现各种操作, 如数据有效性的检验. 业务辑描述等相关功能,业务逻辑层经常放在 service 包或 biz 包下,btz 是英文 buslness 的缩写,意思是 '业务逻 辑";
1.数据访问层:该层实现对数据的保存和读取操作。数据访问,可以访问关系数椐库、文件或 XML 文档等。数据访问层通常放在 dao 包下,DAO 是 英文 Data Access Object 的缩写,意思是 "数据访问对象 ";
为什么需要分层
业务处理的代码与JSP代码混在一起,不易于阅读,不易于代码维护,采用三层软件设计架构后,软件系统在可扩展性和可复用性方面得到极大提高。
软件设计中的分层模式
分层模式是最常见的一种架构模式;甚至可以说分层模式是很多架构模式的基础。
分层
1.分层模式是将解决方案的组件分隔不同的层中(分工合作,细化)
2.每一层的组件应保持内聚性(部门之间常联系)
3.每一层都应与其下面的各层保持松耦合
分层的实现
1.显示层:JSP HTML,css ,JS,do处理页面
2.业务逻辑层
services|biz 从数据访问层拿到数据后进行相关判断逻辑处理。
简单业务逻辑层:直接从数据访问层拿到数据进行操作即可。
复杂业务逻辑层:
从数据访问层拿到数据后,做筛选
比如:删除 从数据访问层拿到对应的数据进行判断,看删除的数据是否在表中存在 如果存在,再调用删除的方法删除即可。
oracle事务处理。 (当实现一个功能时,需要满足2个条件以上,事务处理的机制:要么一起成功,要么一起失败)
例如银行转账
3.数据访问层
dao(接口+实现类),utils
从DB中获取数据 增删改查
4.通过实体将三个层进行联系起来。
实体不属于三层
特点:
高内聚 低耦合
高内聚:功能内部的代码非常严谨
低耦合:功能与功能之间依赖性很小,一个功能出问题不会影响其它功能的运行,俗称:模块化。
简单案例:
dao—数据访问层:

package com.zking.news.dao.impl;
 
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;
 
import com.zking.news.dao.INewsDao;
import com.zking.news.entity.News;
import com.zking.news.entity.Theme;
import com.zking.news.utils.DBHelper;
 
public class NewsDaoImpl implements INewsDao {
 
	@Override
	public List<News> queryNewsAll() {
		Connection conn = null;
		PreparedStatement ps = null;
		ResultSet rs = null;
		List<News> list = new ArrayList<News>();
		try {
			conn = DBHelper.getConn();
			String sql = "select * from tb_news";
			ps = conn.prepareStatement(sql);
			rs = ps.executeQuery();
			while (rs.next()) {
				// 获取分类编号rs.getInt("ntid");
				Theme theme = new ThemeDaoImpl().getThemeByTid(rs.getInt("ntid"));
				list.add(new News(rs.getInt("nid"), theme, rs.getString("ntitle"), rs.getString("nauthor"),
						rs.getString("nsummary"), rs.getString("ncontent"), rs.getString("nimage"),
						rs.getString("ndate"), rs.getInt("ncount")));
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			DBHelper.myClose(conn, ps, rs);
		}
		return list;
	}
 
	@Override
	public List<News> queryNewsAll2() {
		Connection conn = null;
		PreparedStatement ps = null;
		ResultSet rs = null;
		List<News> list = new ArrayList<News>();
		try {
			conn = DBHelper.getConn();
			String sql = "select b.* from ( select a.*,rownum as rid from tb_news a ) b where b.rid between 1 and 5";
			ps = conn.prepareStatement(sql);
			rs = ps.executeQuery();
			while (rs.next()) {
				// 获取分类编号rs.getInt("ntid");
				Theme theme = new ThemeDaoImpl().getThemeByTid(rs.getInt("ntid"));
				list.add(new News(rs.getInt("nid"), theme, rs.getString("ntitle"), rs.getString("nauthor"),
						rs.getString("nsummary"), rs.getString("ncontent"), rs.getString("nimage"),
						rs.getString("ndate"), rs.getInt("ncount")));
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			DBHelper.myClose(conn, ps, rs);
		}
		return list;
	}
 
	@Override
	public List<News> queryNewsAll3(int pageIndex, int pageSize) {
		// 1 5 第一页 5条数据 start = 1 end = 5;
		// 2 5 第二页 5条数据 start = 6 end = 10
		// 根据参数pageIndex和pageSize来计算区间查询的规律
		int start = (pageIndex - 1) * pageSize + 1;
		int end = pageIndex * pageSize;
 
		Connection conn = null;
		PreparedStatement ps = null;
		ResultSet rs = null;
		List<News> list = new ArrayList<News>();
		try {
			conn = DBHelper.getConn();
			String sql = "select b.* from ( select a.*,rownum as rid from tb_news a ) b where b.rid between " + start
					+ " and " + end + "";
			ps = conn.prepareStatement(sql);
			rs = ps.executeQuery();
			while (rs.next()) {
				// 获取分类编号rs.getInt("ntid");
				Theme theme = new ThemeDaoImpl().getThemeByTid(rs.getInt("ntid"));
				list.add(new News(rs.getInt("nid"), theme, rs.getString("ntitle"), rs.getString("nauthor"),
						rs.getString("nsummary"), rs.getString("ncontent"), rs.getString("nimage"),
						rs.getString("ndate"), rs.getInt("ncount")));
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			DBHelper.myClose(conn, ps, rs);
		}
		return list;
	}
 
	@Override
	public List<News> queryNewsAll4(String strName) {
 
		Connection conn = null;
		PreparedStatement ps = null;
		ResultSet rs = null;
		List<News> list = new ArrayList<News>();
		try {
			conn = DBHelper.getConn();
			String sql = "select * from tb_news where ntitle like '%" + strName + "%'";
			ps = conn.prepareStatement(sql);
			rs = ps.executeQuery();
			while (rs.next()) {
				// 获取分类编号rs.getInt("ntid");
				Theme theme = new ThemeDaoImpl().getThemeByTid(rs.getInt("ntid"));
				list.add(new News(rs.getInt("nid"), theme, rs.getString("ntitle"), rs.getString("nauthor"),
						rs.getString("nsummary"), rs.getString("ncontent"), rs.getString("nimage"),
						rs.getString("ndate"), rs.getInt("ncount")));
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			DBHelper.myClose(conn, ps, rs);
		}
		return list;
	}
 
	@Override
	public List<News> queryNewsAll5(int pageIndex, int pageSize, String strName) {
		// 1 5 第一页 5条数据 start = 1 end = 5;
		// 2 5 第二页 5条数据 start = 6 end = 10
		// 根据参数pageIndex和pageSize来计算区间查询的规律
		int start = (pageIndex - 1) * pageSize + 1;
		int end = pageIndex * pageSize;
 
		Connection conn = null;
		PreparedStatement ps = null;
		ResultSet rs = null;
		List<News> list = new ArrayList<News>();
		try {
			conn = DBHelper.getConn();
			String sql = "select b.* from (\r\n" + "       select a.*,rownum as rid from (\r\n"
					+ "               select * from tb_news where ntitle like '%" + strName + "%'\r\n"
					+ "        )a\r\n" + ")b where b.rid between " + start + " and " + end + "";
			ps = conn.prepareStatement(sql);
			rs = ps.executeQuery();
			while (rs.next()) {
				// 获取分类编号rs.getInt("ntid");
				Theme theme = new ThemeDaoImpl().getThemeByTid(rs.getInt("ntid"));
				list.add(new News(rs.getInt("nid"), theme, rs.getString("ntitle"), rs.getString("nauthor"),
						rs.getString("nsummary"), rs.getString("ncontent"), rs.getString("nimage"),
						rs.getString("ndate"), rs.getInt("ncount")));
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			DBHelper.myClose(conn, ps, rs);
		}
		return list;
	}
 
	public List<News> queryNewsAll5(int pageIndex, int pageSize, String strName, int ntid) {
		int start = (pageIndex - 1) * pageSize + 1;
		int end = pageIndex * pageSize;
		Connection conn = null;
		PreparedStatement ps = null;
		ResultSet rs = null;
		List<News> list = new ArrayList<News>();
		try {
			conn = DBHelper.getConn();
			// 默认根据标题进行模糊查询 如果没有点击搜索 默认将strName = ""
			String sql = "select * from tb_news where ntitle like '%" + strName + "%' ";
			// 当点击了主题分类时 将点击的分类编号作为条件拼接到模糊查询的后面
			if (ntid != 0) {
				sql += " and ntid = " + ntid;
			}
			// System.out.println(sql);
			// 进行分页
			sql = " select b.* from ( select a.*,rownum as rid from ( " + sql + " ) a ) b where b.rid between " + start
					+ " and " + end + "";
			System.out.println(sql);
 
			ps = conn.prepareStatement(sql);
			rs = ps.executeQuery();
			while (rs.next()) {
				// 获取分类编号rs.getInt("ntid");
				Theme theme = new ThemeDaoImpl().getThemeByTid(rs.getInt("ntid"));
				list.add(new News(rs.getInt("nid"), theme, rs.getString("ntitle"), rs.getString("nauthor"),
						rs.getString("nsummary"), rs.getString("ncontent"), rs.getString("nimage"),
						rs.getString("ndate"), rs.getInt("ncount")));
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			DBHelper.myClose(conn, ps, rs);
		}
		return list;
	}
 
	public static void main(String[] args) {
//		List<News> queryNewsAll5 = new NewsDaoImpl().queryNewsAll5(1, 4, "1", 1);
//		for (News news : queryNewsAll5) {
//			System.out.println(news.getNtitle());
//		}
		
		//System.out.println(new NewsDaoImpl().queryNewsAll6(1, 5, 0).size());
//		List<News> list = new NewsDaoImpl().queryNewsAll6(1, 5, 6);
//		for (News news : list) {
//			System.out.println(news.getNtitle());
//		}
		
		
		System.out.println(new NewsDaoImpl().getNewsCountByNtid(6));
		
	}
 
	@Override
	public int getNewsCount() {
		Connection conn = null;
		PreparedStatement ps = null;
		ResultSet rs = null;
		int count = 0;// 保存表的总记录数
		try {
			conn = DBHelper.getConn();
			String sql = "select count(*) from tb_news";
			ps = conn.prepareStatement(sql);
			rs = ps.executeQuery();
			if (rs.next()) {
				count = rs.getInt(1);
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			DBHelper.myClose(conn, ps, rs);
		}
		return count;
 
	}
 
	@Override
	public int getNewsCount(String strName) {
		Connection conn = null;
		PreparedStatement ps = null;
		ResultSet rs = null;
		int count = 0;// 保存表的总记录数
		try {
			conn = DBHelper.getConn();
			String sql = "select count(*) from tb_news where ntitle like '%" + strName + "%'";
			ps = conn.prepareStatement(sql);
			rs = ps.executeQuery();
			if (rs.next()) {
				count = rs.getInt(1);
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			DBHelper.myClose(conn, ps, rs);
		}
		return count;
 
	}
 
	// }
	//
	// }
	
	
	@Override
	public List<News> queryNewsAll6(int pageIndex, int pageSize, int ntid) {
		int start = (pageIndex - 1) * pageSize + 1;
		int end = pageIndex * pageSize;
 
		Connection conn = null;
		PreparedStatement ps = null;
		ResultSet rs = null;
		List<News> list = new ArrayList<News>();
		String sql = "";
		String sqlNtid = "";
		try {
			
			conn = DBHelper.getConn();
			if(ntid!=0) {
				sqlNtid = " where ntid = "+ntid;
			}
			sql = "select c.* from ( select b.*,rownum as rid from (select * from tb_news  "+sqlNtid+")b)c where c.rid between "+start+" and "+end+"";
			/*
			if(ntid == 0) {
				sql = "select b.* from\r\n" + 
						"(\r\n" + 
						"select a.*,rownum as rid from tb_news a\r\n" + 
						") b where b.rid between "+start+" and "+end+"";
			}else {
				sql = "select c.* from \r\n" + 
						"(\r\n" + 
						"select b.*,rownum as rid from (\r\n" + 
						"       select * from tb_news where ntid = "+ntid+" \r\n" + 
						")b\r\n" + 
						"\r\n" + 
						")c where c.rid between "+start+" and "+end+"";
			}*/
			System.out.println(sql);
			ps = conn.prepareStatement(sql);
			rs = ps.executeQuery();
			while (rs.next()) {
				// 获取分类编号rs.getInt("ntid");
				Theme theme = new ThemeDaoImpl().getThemeByTid(rs.getInt("ntid"));
				list.add(new News(rs.getInt("nid"), theme, rs.getString("ntitle"), rs.getString("nauthor"),
						rs.getString("nsummary"), rs.getString("ncontent"), rs.getString("nimage"),
						rs.getString("ndate"), rs.getInt("ncount")));
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			DBHelper.myClose(conn, ps, rs);
		}
		return list;
	}
	
	
	@Override
	public int getNewsCountByNtid(int ntid) {
		Connection conn = null;
		PreparedStatement ps = null;
		ResultSet rs = null;
		int count = 0;// 保存表的总记录数
		try {
			conn = DBHelper.getConn();
			String sql = "select count(*) from tb_news ";
			if(ntid!=0) {
				sql+=" where ntid = "+ntid;
			}
			
			ps = conn.prepareStatement(sql);
			rs = ps.executeQuery();
			if (rs.next()) {
				count = rs.getInt(1);
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			DBHelper.myClose(conn, ps, rs);
		}
		return count;
	}
 
	@Override
	public List<News> queryNewsAll7(int pageIndex, int pageSize, String strName, int ntid) {
		int start = (pageIndex - 1) * pageSize + 1;
		int end = pageIndex * pageSize;
		Connection conn = null;
		PreparedStatement ps = null;
		ResultSet rs = null;
		List<News> list = new ArrayList<News>();
		try {
			conn = DBHelper.getConn();
			// 默认根据标题进行模糊查询 如果没有点击搜索 默认将strName = ""
			String sql = "select * from tb_news where ntitle like '%" + strName + "%' ";
			// 当点击了主题分类时 将点击的分类编号作为条件拼接到模糊查询的后面
			if (ntid != 0) {
				sql += " and ntid = " + ntid;
			}
			// System.out.println(sql);
			// 进行分页
			sql = " select b.* from ( select a.*,rownum as rid from ( " + sql + " ) a ) b where b.rid between " + start
					+ " and " + end + "";
			System.out.println(sql);
 
			ps = conn.prepareStatement(sql);
			rs = ps.executeQuery();
			while (rs.next()) {
				// 获取分类编号rs.getInt("ntid");
				Theme theme = new ThemeDaoImpl().getThemeByTid(rs.getInt("ntid"));
				list.add(new News(rs.getInt("nid"), theme, rs.getString("ntitle"), rs.getString("nauthor"),
						rs.getString("nsummary"), rs.getString("ncontent"), rs.getString("nimage"),
						rs.getString("ndate"), rs.getInt("ncount")));
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			DBHelper.myClose(conn, ps, rs);
		}
		return list;
	}
 
	@Override
	public int getNewsCountByMoHuTid(String strName, int ntid) {
		Connection conn = null;
		PreparedStatement ps = null;
		ResultSet rs = null;
		int count = 0;// 保存表的总记录数
		try {
			conn = DBHelper.getConn();
			String sql = "select count(*) from tb_news where ntitle like '%" + strName + "%' and ntid = "+ntid;
			ps = conn.prepareStatement(sql);
			rs = ps.executeQuery();
			if (rs.next()) {
				count = rs.getInt(1);
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			DBHelper.myClose(conn, ps, rs);
		}
		return count;
 
	}
}

biz—业务逻辑层:

package com.zking.news.biz.impl;
 
import java.util.List;
 
import com.zking.news.biz.INewsBiz;
import com.zking.news.dao.INewsDao;
import com.zking.news.dao.impl.NewsDaoImpl;
import com.zking.news.entity.News;
/**
 * 
 * @author Administrator
 * 实现新闻,(业务逻辑层)
 */
public class NewsBizImpl implements INewsBiz{
	INewsDao ind = new NewsDaoImpl();
	
 
	@Override
	public List<News> queryNewsAll5(int pageIndex, int pageSize, String strName, int ntid) {
		return ind.queryNewsAll7(pageIndex, pageSize, strName, ntid);
	}
 
	@Override
	public int getNewsCount(String strName, int ntid) {
		return ind.getNewsCountByMoHuTid(strName, ntid);
	}
}

显示页面—显示层

	<!-- 3.index.jsp用户首页的新闻分类显示(数据绑定) -->
				<ul class="class_date">
					<li id='class_month'><a href="index.jsp"><b>全部</b></a> <!-- 利用javabean模式进行封装数据并显示 -->
						<%
							//实例化分类DAO
							IThemeDao itd = new ThemeDaoImpl();
							//调用查询所有分类的dao方法
							List<Theme> listThemes = itd.queryThemeAll();
							for(Theme theme:listThemes){
						%> 
						<a href="index.jsp?tid=<%=theme.getTid()%>">
							<b><%=theme.getTname() %></b>
						</a> 
						<%		
							}
						%></li>
				</ul>
				<div style = "width:100%;height:40px;text-align: center;line-height:40px; ">
					<form action = "admin.jsp" method = "post">
						<label>新闻标题</label>
						<!-- autocomplete 关闭自动提示 -->
						<input type = "text" name = "strName" autocomplete="off"/>
						<input type = "submit" value = "搜索"/>
					</form>
				</div>
				<!-- 当进入index.jsp页面后,手动点击对应的主题名称  跳转到本页面  获取当前点击的主题名称 -->
				<!-- 新闻显示  start-->
				<ul class="classlist">
					<%
						//当点击了主题分类时  跳转本页面  获取tid
						//没有点击主题分类    不需要获取
						String id = request.getParameter("tid");//null
						int tid = 0;//保存最终的编号
						if(id!=null){
							tid = Integer.valueOf(id);
						}
						System.out.println("tid = "+tid);
						//手动点击了搜索提交按钮   获取到模糊查询的关键字  否则没有点击的情况下  null  转换
						String strName = request.getParameter("strName");
						if(strName==null){//没有手动点击搜索
							strName="";
						}
						//实例化DAO
						INewsBiz inb = new NewsBizImpl();
						//定义变量存储页码以及每一夜显示的数据
						int pageIndex = 1;
						int pageSize = 5;
						int pageMax = 0;//存储最大页码
						//当点击分页区域的下一页超链接时,获取这个参数
						String pIndex = request.getParameter("pageIndex");
						//判断,只有你点击了下一页  才将pIndex赋值给pageIndex
						if(null!=pIndex){//不为空  说明点击了
							pageIndex = Integer.valueOf(pIndex);
						}
						//根据dao求出总记录数
						int count = inb.getNewsCount(strName, tid);
						pageMax = count%pageSize==0?count/pageSize:count/pageSize+1;
						System.out.println("最大页码: "+pageMax);
					
						//调用查询所有新闻的方法
						List<News> listNews = inb.queryNewsAll5(pageIndex, pageSize, strName, tid);
						for(News news:listNews){
					%>
					<li><a href='#'><%=news.getNtitle() %> </a><span> <%=news.getNdate() %></span></li>
 
					<%		
						}
					%>
				</ul>
				<hr />
				<p style="text-align: center; font-size: 18px;"><%=pageIndex %>/<%=pageMax %><a>首页</a> <a>上一页</a> <a
						href="index.jsp?pageIndex=<%=pageIndex+1 >pageMax?pageMax:pageIndex+1%><%if(id!=null){out.println("&tid="+tid);}%>">下一页</a>
					<a>尾页</a>
 
				</p>
			</div>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值