1.数据源的配置,使用C3p0数据源。
导入C3p0数据源包,添加C3p0配置文件
2.创建JDBCUtil,用来获取连接,和释放资源。
public class JDBCUtils {
// 由于数据源对象很大,所有设置为静态资源,使其只有一份
private static DataSource dataSource = new ComboPooledDataSource("c3p0");
/**
* 获取数据库连接
*/
public static Connection getConnection() {
Connection connection = null;
try {
connection = dataSource.getConnection();
} catch (SQLException e) {
e.printStackTrace();
}
return connection;
}
/**
* 释放资源
*/
public static void realseResources(Connection connection, Statement statement, ResultSet resultSet) {
try {
DbUtils.close(connection);
} catch (SQLException e) {
e.printStackTrace();
}
try {
DbUtils.close(statement);
} catch (SQLException e) {
e.printStackTrace();
}
try {
DbUtils.close(resultSet);
} catch (SQLException e) {
e.printStackTrace();
}
}
}
3.创建BaseDao:添加通用CRUD方法。代码如下:
public abstract class BaseDao<T> {
private QueryRunner queryRunner = new QueryRunner();
private Class<T> beanType = null;
@SuppressWarnings("unchecked")
public BaseDao() {
Type type = this.getClass().getGenericSuperclass();
ParameterizedType tp = (ParameterizedType) type;
beanType = (Class<T>) tp.getActualTypeArguments()[0];
}
/**
* 查询泛型对象列表
*/
public List<T> getBeanList(String sql, Object... params) {
List<T> list = null;
Connection connection = JDBCUtils.getConnection();
BeanListHandler<T> beanListHandler = new BeanListHandler<T>(beanType);
try {
list = queryRunner.query(connection, sql, beanListHandler, params);
} catch (SQLException e) {
e.printStackTrace();
} finally {
JDBCUtils.realseResources(connection, null, null);
}
return list;
}
/**
* 查询单个泛型对象
*/
public T getBean(String sql, Object... params) {
T t = null;
Connection connection = JDBCUtils.getConnection();
ResultSetHandler<T> handler = new BeanHandler<T>(beanType);
try {
t = queryRunner.query(connection, sql, handler, params);
} catch (SQLException e) {
e.printStackTrace();
} finally {
JDBCUtils.realseResources(connection, null, null);
}
return t;
}
/**
* 通用的增删改
*/
public void commonUpdate(String sql, Object... params) {
Connection connection = JDBCUtils.getConnection();
try {
queryRunner.update(connection, sql, params);
} catch (SQLException e) {
e.printStackTrace();
}
JDBCUtils.realseResources(connection, null, null);
}
}
重点是:获取泛型T的类型。在构造器中获取,需要注意的是,创建子类对象,父类中的this代表子类对象。通过this.getClass().getGenericSuperclass()获取到的Type并不是实际泛型类型,
是可能包含多个泛型类型的一个类型,所以需要对其进行转换,以来获取真正的泛型类型。
4.每个具体模块的DaoImpl都继承了 BaseDao,然后实现了对应模块的Dao接口。
5.创建了BaseServlet,有一个作用,进行请求的分发。
public abstract class BaseServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String methodName = req.getParameter("method");
try {
Method method = this.getClass().getDeclaredMethod(methodName, HttpServletRequest.class,
HttpServletResponse.class);
method.setAccessible(true);
method.invoke(this, req, resp);
} catch (Exception e) {
e.printStackTrace();
}
}
}
根据请求参数中method的值,去调用对应的方法。每个模块的Servlet继承了BaseServlet。
6.请求参数自动注入实体对象。提供对应工具类
public class WebUtil {
public static <T> T param2Bean(HttpServletRequest req, Class<T> beanType) {
T t = null;
try {
t = beanType.newInstance();
Field[] fields = beanType.getDeclaredFields();
for (Field field : fields) {
String name = field.getName();
String value = req.getParameter(name);
if (value != null) {
BeanUtils.copyProperty(t, name, value);
}
}
} catch (Exception e) {
e.printStackTrace();
}
return t;
}
}
遍历传入实体Class的所有属性对象,获取每一个属性名,再通过String value = req.getParameter(name);来获取对应值,需要注意的是:表单name值和实体对象属性值必须对应。
在不使用BeanUtils的时候,不能进行自动的类型转换,需要实现自动类型转换还需要写较多的代码。
使用BeanUtils.copyProperty()之后,若请求参数为null,对应属性类型为Integer,则还是会给赋值为0,所以这里进行判断。
×BeanUtils和PropertyUtils的区别:BeanUtils可以进行类型的自动转换而PropertyUtils不可以。