连接数据库工具类的编写
1,工具类介绍
本工具类主要对连接数据库的操作进行了简化封装,避免代码的冗余书写,同时也加入了连接池,减少了因为开启和关闭连接带来的资源浪费问题。
主要封装功能有:注册驱动、获取连接、释放资源、(增删改)命令封装、查询命令封装,事务处理等。
2,工具类代码
public class DBUtils_Druid {
//创建线程池
private static DataSource dataSource=null;
//创建线程局部变量
private static ThreadLocal<Connection> threadLocal=new ThreadLocal<>();
//注册驱动
static{
Properties properties=new Properties();
InputStream resource = DBUtils_Druid.class.getClassLoader().getResourceAsStream("druid.properties");
try {
properties.load(resource);
dataSource=DruidDataSourceFactory.createDataSource(properties);
} catch (Exception e) {
e.printStackTrace();
}
}
//获取连接
public static Connection getConnection(){
try {
Connection conn=threadLocal.get();
if(conn==null){
conn= dataSource.getConnection();
//对象绑定
threadLocal.set(conn);
}
return conn;
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
//释放资源
public static void closeAll(ResultSet rs, Statement stat, Connection conn){
try {
if(rs!=null){
rs.close();
}
if(stat!=null){
stat.close();
}
if(conn!=null){
if(conn.getAutoCommit()){
threadLocal.remove();
conn.close();
}
}
}catch (Exception e){
e.printStackTrace();
}
}
//执行命令
public static int executeUpdate(String sql,Object...params){
PreparedStatement pstat=null;
Connection conn=null;
try {
conn=getConnection();
pstat= conn.prepareStatement(sql);
for (int i = 0; i < params.length; i++) {
pstat.setObject(i+1, params[i]);
}
return pstat.executeUpdate();
} catch (SQLException e) {
throw new RuntimeException("出现异常");
}finally {
closeAll(null,pstat,conn);
}
}
//与事务相关的办法
//开启事务
public static void startTransaction() throws SQLException {
Connection conn=getConnection();
if(conn!=null){
conn.setAutoCommit(false);
}
}
//提交事务
public static void commitTransaction() throws SQLException {
Connection conn=getConnection();
if(conn!=null){
conn.commit();
}
}
//回滚事务
public static void rollbackTransaction() throws SQLException {
Connection conn=getConnection();
if(conn!=null){
conn.rollback();
}
}
//关闭事务
public static void closeTransaction() throws SQLException {
Connection conn=getConnection();
if(conn!=null){
//与对象解除绑定
threadLocal.remove();
conn.close();
}
}
//封装查询(利用反射+内省实现)
public static <T> List<T> executeQuery(Class<T> clazz ,String sql,Object...params){
Connection conn=null;
PreparedStatement pstat=null;
ResultSet rs=null;
List<T> list=new ArrayList<>();
try {
conn=getConnection();
pstat=conn.prepareStatement(sql);
if(params!=null){
for (int i = 0; i < params.length; i++) {
pstat.setObject(i+1, params[i]);
}
}
rs=pstat.executeQuery();
//获取结果集的标题
ResultSetMetaData metaData = rs.getMetaData();
System.out.println("标题个数:"+metaData.getColumnCount());
while (rs.next()){
//遍历结果集的标题字段
T obj=clazz.newInstance();//根据反射创建对象
for (int i = 0; i < metaData.getColumnCount(); i++) {
String columnLabel = metaData.getColumnLabel(i + 1); //获得每列的字段名称
System.out.println(columnLabel);
try {
//利用内省完成属性赋值
PropertyDescriptor pd =new PropertyDescriptor(columnLabel,clazz);
if(pd!=null){
Method method = pd.getWriteMethod();
method.invoke(obj, rs.getObject(columnLabel));
}
} catch (Exception e) {
continue; //字段名出错就继续为下一个字段进行映射
}
}
System.out.println("-------");
list.add(obj);
}
return list;
}catch (Exception e){
throw new BookException("查询失败", e);
}finally {
closeAll(rs,pstat,conn);
}
}
}