通过JDBC传送SQL命令是经常用到的,为了避免重复繁琐的书写代码,我们利用java的封装特性,将其增删改查等细节封装为一个DAO工具类,方便后面的使用,下面我们就来了解下DAO封装是如何实现的,
在学习JDBC的DAO封装之前,我们应该先了解DAO封装的基本规则
JDBC封装的实现案例:
在开始写DAO封装类之前,我们会发现由于JDBC的使用流程是几乎固定的,所以比如Driver的注册和Connection的创建等操作都是固定的,因此我们可以先将其封装成一个通用的工具类
Util类封装
public class JDBCUtill {
//设置类文件属性,类文件属性可以在类中所有的方法中使用
//将他们提升成类文件属性(全局变量)视为了在销毁操作中不用传参进去就可直接知道应该销毁的Connection等实例化对象是哪一个
private Connection con = null;
private PreparedStatement ps = null;
//通过静态语句块完成初始化
static {
try {
Class.forName("com.mysql.jdbc.Driver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
System.out.println("Driver注册失败");
}
// System.out.println("Driver接口实现类已注册");
}
//封装Connection对象创建细节
public Connection creatConnection(){
//Connection con = null
try {
con = DriverManager.getConnection("jdbc:mysql://localhost:3306/name","root","233");
} catch (SQLException sqlException) {
sqlException.printStackTrace();
System.out.println("Connection创建失败");
}
//这里应该注意下throw和throws以及try..catch..的使用,也有人提到如果是工具类应该选择抛出异常,有调用它的去处理
return con;
}
//封装PrepareStatement对象创建细节
public PreparedStatement CreatPrepareStatement(String sql) {
//PreparedStatement ps=null;
//通过封装好的creatConnection()方法创建对象
Connection con = creatConnection();
try {
ps = con.prepareStatement(sql);
} catch (SQLException sqlException) {
sqlException.printStackTrace();
System.out.println("PreparedStatement创建失败!");
}
return ps;
}
//封装PrepareStatement和Connection的销毁细节
public void close(){
if (ps != null) {
try {
ps.close();
System.out.println("PrepareStatement关闭成功");
} catch (SQLException sqlException) {
sqlException.printStackTrace();
System.out.println("PrepareStatement关闭失败");
}
}
if (con != null) {
try {
con.close();
System.out.println("Connection关闭成功");
} catch (SQLException sqlException) {
sqlException.printStackTrace();
System.out.println("Connection关闭失败");
}
}
}
//通过方法重载和传参实现将可能存在的ResultSet销毁细节
public void close(ResultSet resultSet) {
if (resultSet != null) {
try {
resultSet.close();
System.out.println("ResultSet关闭成功");
} catch (SQLException sqlException) {
sqlException.printStackTrace();
System.out.println("ResultSet关闭失败");
}
}
close();//调用无参的close()方法来完成Connection和PrepareStatement的销毁
}
}
为了更直观的体会到这些方法的作用,我们让它输出了执行是否成功的反馈,实际上上不需要也可以的
工具类创建好后我们就可以开始书写DAO封装类了
这里写的是一个dept表的DAO类,表中有deptNo,dname,loc三个数据
DAO类的封装
public class DeptDao {
//将util设置为成员变量方便使用
private JDBCUtil util = new JDBCUtil();
//书写添加数据方法
public int add(String deptno,String dname,String loc) throws SQLException {//传参实现数据传入
String SQL = "insert into dept (deptNo,Dname,loc) values (?,?,?)";
PreparedStatement ps = util.CreatPrepareStatement(SQL);
int result = 0;
ps.setInt(1,Integer.valueOf(deptno));
ps.setString(2,dname);
ps.setString(3,loc);
result = ps.executeUpdate();
util.close();
return result;
}
//书写删除数据方法
public int delete(String deptno){
String SQL = "delete from dept where deptno = ?";
PreparedStatement ps = util.CreatPrepareStatement(SQL);
int result = 0;
try {
ps.setInt(1,Integer.valueOf(deptno));
result = ps.executeUpdate();
} catch (SQLException sqlException) {
sqlException.printStackTrace();
}finally {
util.close();
}
return result;
}
//书写更新数据方法
public int update(String deptno,String newdeptno,String newdname,String newloc ) throws SQLException {
String SQL = "update dept set deptNo=?,Dname=?,loc=? where deptno = ?";
PreparedStatement ps = util.CreatPrepareStatement(SQL);
int result = 0;
ps.setInt(4, Integer.valueOf(deptno));
ps.setInt(1, Integer.valueOf(newdeptno));
ps.setString(2, newdname);
ps.setString(3, newloc);
result = ps.executeUpdate();
util.close();
return result;
}
}
这上面的案例似乎有点问题,我们说的封装的的是一个表的增删改查细节,为什么上面只有增删改没有查呢?可以想到当我们在封装方法时是必须要在方法结尾处销毁掉Connection等对象的,其中自然包括了查询结果的ResultSet对象,既然ResultSet被销毁了,那我们如何将查询到的结果传出来呢,由此引出了实体类封装的操作
实体类Dept创建案例:
public class Dept {
Integer DeptNo;
String dname;
String loc;
public Dept(){}
public Dept(int deptNo,String dname,String loc){
this.DeptNo = deptNo;
this.dname = dname;
this.loc = loc;
}
public Integer getDeptNo() {
return DeptNo;
}
public String getDname() {
return dname;
}
public String getLoc() {
return loc;
}
public void setDeptNo(Integer deptNo) {
DeptNo = deptNo;
}
public void setDname(String dname) {
this.dname = dname;
}
public void setLoc(String loc) {
this.loc = loc;
}
}
于是我们就可以在DAO类加入带返回查询结果的方法
//书写查询方法
public List findAll(){
String sql = "select * from dept";
PreparedStatement ps = util.CreatPrepareStatement(sql);
ResultSet rs = null;
List list = new ArrayList();//创建一个集合来装入查询结果
try {
rs = ps.executeQuery();
while (rs.next()){
int deptNo = rs.getInt("deptno");
String dname = rs.getString("dname");
String loc = rs.getString("loc");
Dept dept = new Dept(deptNo,dname,loc);
list.add(dept);
}
} catch (SQLException sqlException) {
sqlException.printStackTrace();
} finally {
util.close(rs);
}
return list;
}
到此,圆满结束!
这些案例主要来源于动力节点老杨的课程,感兴趣的同学可以看看B站动力节点java web
以上是我自己整理的笔记和理解,如果有错误欢迎大家评论区交流指正,如果有什么好的课程也希望大家能分享一下呀