为什么要再次封装Jdbc工具类
- 虽然本来的Jdbc工具类实现了三大功能的封装,但是在映射层Dao中还是存在许多相同的步骤需要自己手动写。
- 重复敲相同的功能代码,显然不符合我们的编程原则,所以对Jdbc进行再次的封装
如何封装
-
Dao中写的代码功能大体一致
-
里面不同的只有三种情况,
- 一种是对于数据库的操作:增删改大体一致,查询需要另外解析ResultSet
- 每次编写sql语句不同
- sql语句中添加的参数个数,参数不同;
-
因此封装的大致方向就是在Jdbc中封装两个方法,一个是对于数据库进行增删改,一个是查数据库,然后每个方法都传入两个参数,一个是String sql,编写的sql 语句,一个是集合,通过遍历集合的大小,得知每个sql语句需要插入多少个数据。
封装的代码
package com.util;
import com.pojo.Customer;
import java.io.IOException;
import java.io.InputStream;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
public class JdbcUtil {
//创建一个properties对象
private static final Properties props = new Properties();
//使用静态代码块,在项目启动之初,扫描配置文件db.properties
static {
//通过反射方法获取配置文件输入流
InputStream in = JdbcUtil.class.getClassLoader().getResourceAsStream("db.properties");
try {
props.load(in);
try {
//获取数据库驱动
Class.forName(props.getProperty("driverClassName"));
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
} catch (IOException e) {
e.printStackTrace();
}
}
//获取数据库的连接
public static Connection getConnection() throws SQLException {
return DriverManager.getConnection(props.getProperty("url"), props.getProperty("username"), props.getProperty("password"));
}
//写一个关闭三个进程的方法
public static void close(ResultSet rs, PreparedStatement pstm, Connection conn) {
try {
if (rs != null)
rs.close();
if (pstm != null) pstm.close();
if (conn != null) conn.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
//封装增删改功能
public static int executeUpdate(String sql, ArrayList list){
//每次调用此方法都在类中新new这三个进程,然后在最后关闭
Connection conn = null;
PreparedStatement pstm = null;
ResultSet rs = null;
try {
//调用本类的连接方法,获取连接
conn = getConnection();
//使用传入的sql字符串,获取preparedStatement
pstm = conn.prepareStatement(sql);
//对集合进行判定,因为有些情况是不需要传参的,防止发生空指针异常
if (list.size()!=0){
//通过集合的大小,按顺序对每个位置进行赋值
for(int i=0;i<list.size();i++){
if (list.get(i) instanceof String){
pstm.setString((i+1), (String) list.get(i));
}else
pstm.setInt((i+1), (Integer) list.get(i));
}
}
return pstm.executeUpdate();
} catch (SQLException throwables) {
throwables.printStackTrace();
}finally {
close(null,pstm,conn);
}
return 0;
}
//封装查
public static List<Customer> executeQuery(String sql,ArrayList list){
Connection conn = null;
PreparedStatement pstm = null;
ResultSet rs = null;
try {
conn = getConnection();
pstm = conn.prepareStatement(sql);
if (list.size()!=0){
for(int i=0;i<list.size();i++){
if (list.get(i) instanceof String){
pstm.setString((i+1), (String) list.get(i));
}else
pstm.setInt((i+1), (Integer) list.get(i));
}
}
rs = pstm.executeQuery();
return analyseRs(rs);
} catch (SQLException throwables) {
throwables.printStackTrace();
}finally {
close(rs,pstm,conn);
}
return null;
}
//解析resultSet
public static List<Customer> analyseRs(ResultSet rs) throws SQLException {
if (rs!=null){
List<Customer> list = new ArrayList<>();
while (rs.next()){
Customer customer = new Customer();
customer.setName(rs.getString("cname"));
customer.setGender(rs.getString("gender"));
customer.setBirthday(rs.getDate("birthday"));
customer.setCellphone(rs.getString("cellphone"));
customer.setEmail(rs.getString("email"));
customer.setDecription(rs.getString("decription"));
list.add(customer);
}
return list;
}
return null;
}
}
ps
- 其中还有瑕疵,比如说集合的泛型是比较头疼的问题,如果只有单个的实体类还好,但这显然是不可能的事情,这也是需要解决的问题;
- 在解析ResultSet中,其中用到的实体类,进行封装之后,如果是对其他的实体类进行赋值的话,现在这样做是不太行的。