三层架构
简介
与MVC设计模式的目标一致,都是为了解耦合、提高代码复用
区别:二者对项目理解的角度不同
三层组成
表示层(USL,User Show Layer;经常称作视图层)
–前台:对应于MVC中的View,用于和用户交互、界面的显示(jsp、js、html、css、jquery等web前端技术),代码位置:Web
–后台:对应于MVC中Controller,用于控制跳转、调用业务逻辑层(Servlet(SpringMVC Structs2))代码位置:xxx.servlet包中
业务逻辑层(BLL,Business Logic Layer;Service层),代码位置:xxx.service包(xxx.manager,xxx.bll)
–接收表示层的请求调用
–组装数据访问层,逻辑性的操作(增删改查,删:查+删)
数据访问层(DAL,Data Access Layer;Dao层)
–直接访问数据库,原子性的操作(增删改查),代码位置:xxx.dao包
三层间的关系
上层将请求传递给下层,下层处理后返回给上层
上层依赖于下层,依赖:代码的理解就是持有成员变量,或者理解为:有A的前提是必须先有B(eg:先有数据库,才可能有DAO层,Dao依赖于数据库)
JSP的对象在Servlet中调用:
out:PrintWriter out = response.getWriter()
session:request.getSession()
application:request.getServletContext()
解决乱码的方法:在Servlet中
response.setContentType("text/html; charset=UTF-8");
response.setCharacterEncoding("utf-8");//设置响应编码
PrintWriter out = response.getWriter();//响应对象
Servlet:一个Servlet对应于一个功能,因此,如果有增删改查(查询单个、查询多个)5个功能,则需要创建5个Servlet
三层优化
加入接口:建议面向接口开发:先接口再实现类
> service、dao加入接口
接口与实现类的命名规范 接口(interface):IXxxService/dao... 实现类(implements):XxxServiceImpl
包:接口:xxx.service(xx.dao) 实现类:xxx.service.impl(xx.dao.impl)
具体使用时 采用多态形式 接口 x = new 实现类();
DBUtil(数据库帮助类)
简化Dao层代码量
帮助类:一般写在xxx.util包
写通用的增删改查
/**
* Copyright (C), 2015-2019, XXX有限公司
* FileName: DBUtil
* Author: zephon
* Date: 19-3-24 下午1:35
* Description:
* History:
* <author> <time> <version> <desc>
* 作者姓名 修改时间 版本号 描述
*/
package util;
import java.sql.*;
/**
* 〈一句话功能简述〉<br>
* 〈〉
*
* @author zephon
* @create 19-3-24
* @since 1.0.0
*/
public class DBUtil {
private static final String URL = "jdbc:mysql://localhost:3306/JavaMysql0";
private static final String USERNAME = "root";
private static final String PWD = "";
public static PreparedStatement pstmt = null;
public static Connection connection = null;
public static ResultSet rs = null;
/**
* @Description: 通用的增删改
* @Param: sql:带?的sql语句 params:?参数数组
* @return:
* @Author: Zephon
* @Date:
*/
public static boolean executeUpdate(String sql, Object[] params) {
try {
pstmt = createPreparedStatement(sql, params);
int count = pstmt.executeUpdate();
if (count > 0)
return true;
else
return false;
} catch (ClassNotFoundException e) {
e.printStackTrace();
return false;
} catch (SQLException e) {
e.printStackTrace();
return false;
} catch (Exception e) {
e.printStackTrace();
return false;
} finally {
closeAll(null,pstmt,connection);
}
}
/**
* @Description: 通用的查
* @Param: sql:带?的sql语句 params:?参数数组
* @return:
* @Author: Zephon
* @Date:
*/
public static ResultSet query(String sql, Object[] params) {
try {
pstmt = createPreparedStatement(sql, params);
rs = pstmt.executeQuery();
return rs;
} catch (ClassNotFoundException e) {
e.printStackTrace();
return null;
} catch (SQLException e) {
e.printStackTrace();
return null;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
// 方法重构,将重复的代码整合成一个方法
public static Connection getConnection() throws ClassNotFoundException, SQLException {
Class.forName("com.mysql.jdbc.Driver");
connection = DriverManager.getConnection(URL, USERNAME, PWD);
return connection;
}
public static PreparedStatement createPreparedStatement(String sql, Object[] params) throws SQLException, ClassNotFoundException {
pstmt = getConnection().prepareStatement(sql);
// 设置sql语句中的?的值
for (int i = 1; i <= params.length; i++) {
pstmt.setObject(i, params[i - 1]);
}
return pstmt;
}
public static void closeAll(ResultSet rs,Statement stmt,Connection connection){
try {
if (stmt != null) stmt.close();
if (connection != null) connection.close();
if(rs!=null)rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}