JavaWeb学习(17):优化三层(加入接口和 DBUtil)
饭前点心:
如果对三层架构有什么不理解的:
改进了那些地方:
1、加入接口(面向接口开发)
我们在实际开发中一般都是先有一个大致的框架,然后在后期实现各个模块的功能。
先接口 -- > 再实现类。
2、DBUtil
通用的数据库帮助类,可以简化Dao层的代码量
帮助类 一般建议写在 xxx.util包
接口与实现类的命名规范:
接口:interface, 起名 I实体类Service IStudentService
IStudentDao
实现类:implements 起名 实体类ServiceImpl StudentServiceImpl
StudentDaoImpl
接口: I实体类层所在包名 IStudentService、IStudentDao
接口所在的包: xxx.service xx.dao
实现类: 实体类层所在包名Impl StudentServiceImpl、StudentDaoImpl
实现类所在的包:xxx.service.impl xx.dao.impl
以后使用接口/实现类时,推荐写法:
接口 x = new 实现类();
IStudentDao studentDao = new StudentDaoImpl();
效果如图:
Code:
本次代码是在上一个介绍中进行有优化,在此只展现修改的代码,其他的的部分可参考:
interface IStudentDao:
package org.dao;
import java.util.List;
import org.entity.Student;
// 接口:更加贴近设计要求,一般都先有一个大概,然后通过实现类实现各个方法
public interface IStudentDao {
// 判断该用户是否存在
public boolean isExist(int sno) ;
// 添加新用户
public boolean addStudent(Student student);
// 根据学生学号修改学生信息
public boolean updateStudentBySno(int sno,Student student) ;
// 删除用户
public boolean deleteStudentBySno(int sno) ;
// 通过学号查询学生信息(返回值是一个学生,如果学生不存在返回 Null)
public Student queryStudentBySno(int sno);
public List<Student> queryAllStudents();
}
interface IStudentService:
package org.service;
import java.util.List;
import org.entity.Student;
//接口:更加贴近设计要求,一般都先有一个大概,然后通过实现类实现各个方法
public interface IStudentService {
public Student queryStudentBySno(int sno);
// 查询所有用户信息
public List<Student> queryAllStudents();
// 更新用户(更新用户之前需要先判断用户是否已经存在)
public boolean updateStudent(int sno,Student student);
// 删除用户(删除用户之前需要先判断用户是否已经存在)
public boolean deleteStudent(int sno) ;
// 增加用户(增加用户之前需要先判断用户是否已经存在
public boolean addStudent(Student student);
}
DBUtil:
package org.util;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
/*
* 数据库帮助类:可以简化代码(将每个模块中重复的代码弄到一个方法中,增加代码复用)
* DBUtil: 简化 Dao 层的代码
*
* */
public class DBUtil {
private static final String URL = "jdbc:mysql://localhost:3306/sqltest";
private static final String User = "root";
private static final String Password = "root";
public static Connection conn = null;
public static PreparedStatement pstam = null;
public static ResultSet rs = null;
// 用于加载驱动和与驱动建立连接
public static Connection getConnection() throws ClassNotFoundException, SQLException {
Class.forName("com.mysql.jdbc.Driver") ;
return DriverManager.getConnection( URL,User,Password ) ;
}
// 操作数据库,执行 sql 语句
// Object 数组用来存储 ? (占位符所代表的信息),因为 ? 所代表的数据类型不一致,所以用 Object
// 静态方法,方便直接调用 --> 类名.方法
public static PreparedStatement createPreParedStatement(String sql,Object[] params) throws ClassNotFoundException, SQLException {
// 预处理
pstam = getConnection().prepareStatement(sql) ;
// 防止出现空指针
if(params!=null ) {
for(int i=0;i<params.length;i++) {
pstam.setObject(i+1, params[i]);
}
}
// 返回一个 PreparedStatement 对象,与原先操作数据库类似
return pstam;
}
// update 操作: 增加、删除、更新(通用代码,只是 Sql 语句不一样,所以我们只需要传递不同的 sql 语句
// 和占位符所代表的意义即可)
public static boolean exeucateUpdate(String sql,Object[] pstams) {
int result = 0;
try {
pstam = createPreParedStatement(sql,pstams);
result = pstam.executeUpdate();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
try {
if(rs != null) rs.close();
if(pstam != null) pstam.close();
if(conn != null) conn.close();
} catch(SQLException e) {
e.printStackTrace();
}
}
if(result > 0) return true;
else return false;
}
// 查询时的通用代码: 因为我们是面对所用用户的,不同的用户所对应的字段有所不同,所以我们在这里只能
// 返回一个结果集,剩下的交给其他地方进行处理。
public static ResultSet excucateQuery(String sql, Object[] pstams) {
try {
pstam = createPreParedStatement(sql,pstams);
rs = pstam.executeQuery();
return rs;
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
StudentDaoImpl:
package org.dao.impl;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import org.dao.IStudentDao;
import org.entity.Student;
import org.util.DBUtil;
/*
* 我们将冗余的一部分代码放到 DBUtil 中,其次我们将 DBUtil 中的方法设置成 static
* 那我们我们就可以直接在这个项目的方法其他地方进行 类名.方法 进行调用
*
* 由于 增加、删除、修改 操作只是 sql 语句不同,所以我们每次只需要传递不同的 sql 语句即可。
* 由于 每种功能对应的 sql 语句中的 占位符数量及数据类型也是不同的,所以我们可以将 所有的
* 占位符所代表的意义存储到 一个 Object 数组中,一起传递到 DBUtil 中。
*
* */
public class StudentDaoImpl implements IStudentDao {
// 判断该用户是否存在
public boolean isExist(int sno) {
// 查询该学生的学号是否存在,存在就返回true,不存在则返回 false
return queryStudentBySno(sno) == null ? false : true;
}
// 添加新用户
public boolean addStudent(Student student) {
String sql = "insert into student values (?,?,?,?,?)";
Object[] params = { student.getSno(), student.getName(), student.getAge(), student.getSex(), student.getSad() };
return DBUtil.exeucateUpdate(sql, params);
}
// 根据学生学号修改学生信息
public boolean updateStudentBySno(int sno, Student student) {
String sql = "update student set sname = ?,sage = ?,ssex = ?,sad = ? where sno = ?";
Object[] params = { student.getName(), student.getAge(), student.getSex(), student.getSad(), sno };
return DBUtil.exeucateUpdate(sql, params);
}
// 删除用户
public boolean deleteStudentBySno(int sno) {
String sql = "delete from student where sno = ?";
Object[] params = { sno };
return DBUtil.exeucateUpdate(sql, params);
}
// 查询所有用户
public List<Student> queryAllStudents() {
Connection conn = null;
PreparedStatement pstam = null;
ResultSet rs = null;
List<Student> students = new ArrayList<>();
Student student = null;
try {
String sql = "select * from student";
rs = DBUtil.excucateQuery(sql, null);
while (rs.next()) {
int no = rs.getInt("sno");
String name = rs.getString("sname");
int age = rs.getInt("sage");
String sex = rs.getString("ssex");
String sad = rs.getString("sad");
student = new Student(no, name, age, sex, sad);
students.add(student);
}
return students;
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
} finally {
if (rs != null)
try {
rs.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if (conn != null) {
try {
DBUtil.conn.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if (pstam != null) {
try {
DBUtil.pstam.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
return null;
}
// 通过学号查询学生信息(返回值是一个学生,如果学生不存在返回 Null)
public Student queryStudentBySno(int sno) {
ResultSet rs = null;
Student student = null;
try {
String sql = "select * from student where sno = ?";
Object[] pstams = {sno};
rs = DBUtil.excucateQuery(sql, pstams);
if(rs.next()) {
int no = rs.getInt("sno");
String name = rs.getString("sname");
int age = rs.getInt("sage");
String sex = rs.getString("ssex");
String sad = rs.getString("sad");
student = new Student(no,name,age,sex,sad);
return student;
} else {
return null;
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
} finally {
if(rs != null )
try {
rs.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return null;
}
}
客官留步:
如果说年轻人未来是一场盛宴的话,那么我首先要有赴宴的资格。