前言
在初学JDBC阶段的已经换装一个可以获取数据库连接,和释放数据库资源的简单工具类。但随着进入WEB阶段的学习,大量的数据库操作,之前简单的封装已经不能够支持我们的开发。
基本思路(两个主要方法)
增删改操作:
返回影响数据库的行数
查询操作:
工具类返回结果集,可以在dao层再提取一个处理结果集的方法
工具类代码
import java.sql.*;
public class DBUtil {
static String driver = "com.mysql.cj.jdbc.Driver";
static String userName = "数据库用户名";// 数据库用户名
static String psw = "数据库密码";//数据库密码
static String url = "jdbc:mysql://127.0.0.1:3306/数据库名称?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=UTC";
static Connection conn;
static PreparedStatement stmt;
/**
* 静态块:初始化连接
*/
static {
conn=getConnection();
}
/**
* 获取连接
* @return 返回连接
*/
public static Connection getConnection() {
try {
// 加载驱动
Class.forName(driver);
// 获得连接
conn = DriverManager.getConnection(url, userName, psw);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return conn;
}
/**
* 处理传入的参数
* @param sql 数据库语句
* @param parameter 参数
* @return 返回预编译语句
*/
public static PreparedStatement handleParameter(String sql,Object[] parameter){
try {
//预编译
stmt=conn.prepareStatement(sql);
//判断是否需要传入参数
if(parameter!=null){
//传入数组中的参数
for (int i=0;i<parameter.length;i++){
stmt.setObject(i+1,parameter[i]);
}
}
return stmt;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 查询
* @param sql 数据库语句
* @param parameter 需要写入的参数
* @return 返回结果集
*/
public static ResultSet myExecuteQuery(String sql,Object[] parameter){
ResultSet rs=null;
try {
//处理数据
stmt=handleParameter(sql,parameter);
//执行
rs=stmt.executeQuery();
} catch (Exception e) {
e.printStackTrace();
}
return rs;
}
/**
* 增删改
* @param sql 数据库语句
* @param parameter 传入的参数
* @return 返回影响的行数
*/
public static int myExecuteUpdate(String sql,Object[] parameter){
int n=0;
try {
//数据处理
stmt=handleParameter(sql,parameter);
//执行
n=stmt.executeUpdate();
} catch (Exception e) {
e.printStackTrace();
}
return n;
}
/**
* 释放资源
* @param conn
* @param stmt
* @param rs
*/
public static void close(Connection conn,PreparedStatement stmt,ResultSet rs) {
try {
if(rs!=null) {
try {
rs.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(stmt!=null) {
try {
stmt.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(conn!=null) {
try {
conn.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
} catch (Exception e) {
}
}
}
测试代码
public static void main(String[] args) throws SQLException {
String sql="select * from car where bo=?";//数据库语句
Object[] objects=new Object[1];//传入的参数数组
objects[0]=0;
//测试查询,获取结果集
ResultSet rs=DBUtil.myExecuteQuery(sql,objects);
List<Car> list=reLogin(rs);
for (Car c:list) {
System.out.println(c.toString());
}
}
/**
* 封装的处理结果集方法
* @param rs 传入结果集
* @return 返回处理后的数据
* @throws SQLException
*/
static private List reLogin(ResultSet rs) throws SQLException {
List<Car> list=new ArrayList();
while(rs.next()) {
Car c=new Car();
c.setGoodsid(rs.getInt("goodsid"));
c.setcPrice(rs.getBigDecimal("C_price"));
c.setNumber(rs.getInt("number"));
c.setuId(rs.getInt("u_Id"));
c.setBo(rs.getInt("bo"));
list.add(c);
}
return list;
}
难点
- 如何给预编译语句传参
因为预编译语句是有规律的,dao层可以给工具类传入一个Object的数组,让工具类处理数据。
/**
* 处理传入的参数
* @param sql 数据库语句
* @param parameter 参数
* @return 返回预编译语句
*/
public static PreparedStatement handleParameter(String sql,Object[] parameter){
try {
//预编译
stmt=conn.prepareStatement(sql);
//判断是否需要传入参数
if(parameter!=null){
//传入数组中的参数
for (int i=0;i<parameter.length;i++){
stmt.setObject(i+1,parameter[i]);
}
}
return stmt;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
还可改进的地方
- 通过反射处理结果集
- 通过反射给PreparedStatement 存入参数