1、三层架构与MVC设计模式的目标一致:都只为了解耦合,提高代码复用; 区别:二者对项目的的理解不同
2、三层组成:a、视觉层:前台:对应MVC中的View,用于和用户交互、界面的显示;后台:对应MVC中的Controller,用于控制跳转,业务逻辑层Servlet);
b、业务逻辑层:接收表示层的请求,调用,组装数据访问层逻辑性的操作(增删改查:增加(先查询+再增加))
c、数据库访问层:直接访问数据库的操作,原子性的增删改查
三层优化:1、加入接口:面向接口,先接口再实现类 主要针对service、dao
*命名规范:
接口: I xxxService XXX为实体类名 例如我做的学生信息三层架构中为IStudentService
IxxxDao 如:IStudentDao
service接口一般存放在xxx.service包中 dao接口一般存放在xxx.dao接口中
实现类:xxxServiceImpl 如:StudentServiceImpl xxxDaoImpl 如:StudentDaoImpl
实现类也放在特定的包中: xxx.service.impl xxx.dao.impl
使用方法:接口 X=new 实现类()
2、DBUtil:数据库帮助类,可以简化Dao层代码 一般建议写下xxx.util包里
public class DBUtil {
//所要连接的数据库的信息
private final static String URL="jdbc:mysql://localhost:3306/userinfo?serverTimezone=GMT%2B8";
private final static String USERNAME="root";
private final static String PWD="843878";
//图稿代码复用
public static Connection connection=null;
public static PreparedStatement pstmt=null;
public static ResultSet rs=null;
//获取连接对象 增删改查都需要建立与数据库的连接 所以把这一部分封装成一个方法
public static Connection getconnection(){
try {
//1.加载具体的驱动类
Class.forName("com.mysql.cj.jdbc.Driver");
//2.与数据库建立连接
return DriverManager.getConnection(URL,USERNAME,PWD);
} catch (ClassNotFoundException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
return null;
}catch (SQLException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
return null;
}
}
//获取PreparedStatement
public static PreparedStatement createPreparedStatement(String sql,Object[] params) {
try {
pstmt=getconnection().prepareStatement(sql);
//避免空指针
if(params!=null) {
//参数设置 ?的个数 ?的实际赋值
for(int i=0;i<params.length;i++) {
pstmt.setObject(i+1,params[i]);
}
}
return pstmt;
} catch (SQLException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
return null;
}
}
//关闭数据流
public static void CloseAll(ResultSet rs,Statement stmt,Connection connection) {
try {
if(rs!=null) rs.close();
if(stmt!=null) stmt.close();
if(connection!=null) connection.close();
}catch (SQLException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
}
//增、删、改操作
public static boolean executeUpdate(String sql,Object[] params) {
pstmt=createPreparedStatement(sql,params);
int count;
try {
count = pstmt.executeUpdate();
if(count>0)
return true;
else
return false;
} catch (SQLException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
return false;
}finally {
//关闭数据流
CloseAll(null,pstmt,connection);
}
}
//通用的查询操作
public static ResultSet executeQuery(String sql,Object[] params) {
//这就是上面createPreparedStatement方法封装的部分
/* try {
//1.加载具体的驱动类
Class.forName("com.mysql.cj.jdbc.Driver");
//2.与数据库建立连接
connection=DriverManager.getConnection(URL,USERNAME,PWD);
pstmt=connection.prepareStatement(sql);
//参数设置
if(params!=null) {
for(int i=0;i<params.length;i++) {
pstmt.setObject(i+1,params[i]);
}
}
*/
pstmt=createPreparedStatement(sql,params);
try {
//通用的查询 只返回一个结果、
return rs=pstmt.executeQuery();
} catch (SQLException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
return null;
//后面具体的查询方法还需要用到rs 所以此处最后不能关闭数据流
}
}
}
``三层架构中遇到的BUG
查询全部学生的过程中,一直报空指针
最后竟然是我把遍历结果集的条件写错 while(rs.next())写成while(rs!=null)