package com.atguigu.util;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;
import javax.sql.DataSource;
import com.alibaba.druid.pool.DruidDataSourceFactory;
/**
* 获取连接和释放连接的工具类
* @author yuanyuan liu
*
*/
public class JDBCUtils {
private static DataSource dataSource;//多态
/**
* ThreadLocal
* get()
* set()
* remove()
*/
private static ThreadLocal<Connection> threadLocal = new ThreadLocal<>();//保证一个事务中用的是同一个连接
static {
//指向需要一个数据源对象,所以写到静态块里了
try {
//1、读取druip.properties文件
Properties pro = new Properties();
pro.load(JDBCUtils.class.getClassLoader().getResourceAsStream("druid.properties"));
//2、连接连接池
dataSource = DruidDataSourceFactory.createDataSource(pro);//通过Druid工厂创建数据源对象
} catch (Exception e) {
e.printStackTrace();
}
}
//获取连接
public static Connection getConnection() {
Connection connection = threadLocal.get();
try {
if(connection == null) {//已经有了连接,就直接return connection 若没有连接,才创建新连接
connection = dataSource.getConnection();
threadLocal.set(connection);
}
} catch (SQLException e) {
e.printStackTrace();
}
return connection;
}
// public static Connection getConnection() {
// Connection connection = null;
// try {
// connection = dataSource.getConnection();
// } catch (SQLException e) {
// e.printStackTrace();
// }
// return connection;
// }
//释放连接
public static void releaseConnection() {
Connection connection = threadLocal.get();
if(connection != null) {//说明有连接未关闭
try {
connection.close();
threadLocal.remove();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
// public static void releaseConnection(Connection connection) {
// if(connection != null) {
// try {
// connection.close();
// } catch (SQLException e) {
// e.printStackTrace();
// }
// }
// }
}
package com.atguigu.servlet;
import java.io.IOException;
import java.lang.reflect.Method;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Servlet implementation class BaseServlet
*/
public class BaseServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//登录 || 注册
String method = request.getParameter("method");
try {
//使用反射通过方法名动态获取方法对象,
//Open Declaration Method java.lang.Class.getDeclaredMethod(String name, Class<?>... parameterTypes)
//throws NoSuchMethodException, SecurityException
Method method2 = this.getClass().getDeclaredMethod(method, HttpServletRequest.class,HttpServletResponse.class);
//从而执行该方法
//Open Declaration Object java.lang.reflect.Method.invoke(Object obj, Object... args)
//throws IllegalAccessException, IllegalArgumentException, InvocationTargetException
/**
* 这个this指的是哪个类的对象?这的是BookServlet类的对象,比如说图书管理界面增删改查图书,BookServlet?method=getBooksByPage
* 这个BookServlet extends BaseServlet的,这个方法是BookServlet里的getBooksByPage方法,所以this指代BookServlet这个类的类模板
*/
method2.invoke(this, request,response);
} catch (Exception e) {
// e.printStackTrace();
throw new RuntimeException(e);
}
// if("login".equals(method)) {
// //登录
// login(request, response);
// }else if("regist".equals(method)) {
// //注册
// regist(request, response);
// }
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
package com.atguigu.dao;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.List;
import org.apache.catalina.tribes.util.Arrays;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.apache.commons.dbutils.handlers.ScalarHandler;
import com.atguigu.util.JDBCUtils;
/**
* 定义一个用来被继承的对数据库进行基本操作的Dao
*
* @author Chunsheng Zhang
*
* @param <T>
*/
public class BaseDao<T> {
//这个是dbutils的操作数据库的对象
private QueryRunner queryRunner = new QueryRunner();
//定义一个变量来接收泛型的类型
//T.class和Class<T>有什么区别呢????
private Class<T> type;
// 获取T的Class对象,获取泛型的类型,泛型是在被子类继承时才确定
public BaseDao() {
//获取子类的类型
Class clazz = this.getClass();
System.out.println(this);//com.atguigu.dao.impl.BookDaoImpl@37dd134e
//获取父类的类型
//getGenericSuperclass()用来获取当前类的父类的类型
//ParameterizedType表示的是带泛型的类型
ParameterizedType parameterizedType = (ParameterizedType) clazz.getGenericSuperclass();
System.out.println(parameterizedType);//com.atguigu.dao.BaseDao<com.atguigu.bean.Book>
//获取具体的泛型类型 getActualTypeArguments获取具体的泛型的类型
//这个方法会返回一个Type的数组
Type[] types = parameterizedType.getActualTypeArguments();
System.out.println(Arrays.toString(types));//{class com.atguigu.bean.Book}
//获取具体的泛型的类型·
this.type = (Class<T>) types[0];
}
/**
* 通用的增删改操作
*
* @param sql
* insert
* delete
* update
* @param params
* @return
*/
public int update(String sql, Object... params) {
// 获取连接
Connection connection = JDBCUtils.getConnection();//这里获取连接
int count = 0;
try {
count = queryRunner.update(connection, sql, params);
} catch (SQLException e) {
// e.printStackTrace();
throw new RuntimeException(e);
} finally {
// JDBCUtils.releaseConnection(connection);
}
return count;
}
/**
* 通用的批处理增删改操作
*
* @param sql
* insert
* delete
* update
* @param params:二维数组
* 一维:次数
* 二维:参数
*
* @return
*/
public void batchUpdate(String sql, Object[][] params) {
// 获取连接
Connection connection = JDBCUtils.getConnection();
try {
queryRunner.batch(connection, sql, params);
} catch (SQLException e) {
// e.printStackTrace();
throw new RuntimeException(e);
} finally {
// JDBCUtils.releaseConnection(connection);
}
}
/**
* 获取一个对象
*
* @param sql
* @param params
* @return
*/
public T getBean(String sql, Object... params) {
// 获取连接
Connection connection = JDBCUtils.getConnection();
T t = null;
try {
t = queryRunner.query(connection, sql, new BeanHandler<T>(type),
params);
} catch (SQLException e) {
// e.printStackTrace();
throw new RuntimeException(e);
} finally {
// JDBCUtils.releaseConnection(connection);
}
return t;
}
/**
* 获取所有对象
* @param sql
* @param params
* @return
*/
public List<T> getBeanList(String sql, Object... params) {
// 获取连接
Connection connection = JDBCUtils.getConnection();
List<T> list = null;
try {
list = queryRunner.query(connection, sql, new BeanListHandler<T>(
type), params);
} catch (SQLException e) {
// e.printStackTrace();
throw new RuntimeException(e);
} finally {
// JDBCUtils.releaseConnection(connection);
}
return list;
}
/**
* 获取单个值
* @param sql :select count(*) from books
* @param params
* @return
*/
public Object getSingeValue(String sql, Object... params) {
// 获取连接
Connection connection = JDBCUtils.getConnection();
Object o = null;
try {
o = queryRunner.query(connection, sql, new ScalarHandler<>(),
params);
} catch (SQLException e) {
// e.printStackTrace();
throw new RuntimeException(e);
} finally {
// JDBCUtils.releaseConnection(connection);
}
return o;
}
}