「这是我参与2022首次更文挑战的第19天,活动详情查看:2022首次更文挑战」。
一、使用c3p0数据库连接池
通过上面的案例,可以发现,每次操作都需要创建数据库连接,这样在实际开发中是不允许的。为了避免频繁的创建数据库连接,数据库连接池技术应运而生。数据库连接池负责分配、管理和释放数据库连接,它允许应用程序重复使用现有的数据库连接,而不是重新建立。
C3P0是目前最流行的开源数据库连接池之一,它实现了DataSource数据源接口,支持JDBC2和JDBC3的标准规范,易于扩展并且性能优越,著名的开源框架Hibernate和 Spring都支持该数据源。
1、下载c3p0数据库连接池:
c3p0-0.9.5.5.jar 以及依赖包mchange-commons-java-0.2.19.jar
Mvaen库
mvnrepository.com/artifact/co…
mvnrepository.com/artifact/co…
然后加入到项目中。
2、添加配置文件:c3p0-config.xml
在src根目录下面,创建一个c3p0-config.xml文件,然后添加配置信息如下:
<?xml version="1.0" encoding="UTF-8"?>\
<c3p0-config>\
<default-config>\
<property name="driverClass">com.mysql.cj.jdbc.Driver</property>\
<property name="jdbcUrl">\
jdbc:mysql://localhost:3306/train01?useSSL=FALSE&allowPublicKeyRetrieval=TRUE&serverTimezone=UTC\
</property>\
<property name="user">root</property>\
<property name="password">admin</property>\
<property name="checkoutTimeout">30000</property>\
<!--初始化连接数-->\
<property name="initialPoolSize">5</property>\
<!--最大空闲时间,60秒内未使用则连接被丢弃。若为0则永不丢弃。Default: 0 -->\
<property name="maxIdleTime">20</property>\
<!--连接池中保留的最大连接数。Default: 15 -->\
<property name="maxPoolSize">10</property>\
<!--初始化时获取三个连接,取值应在minPoolSize与maxPoolSize之间。Default: 3 -->\
<property name="minPoolSize">1</property>\
<!--Statement 最大数,设置为0就是关闭缓存-->\
<property name="maxStatements">0</property>\
</default-config>\
</c3p0-config>
3、创建c3p0utils工具类
创建一个c3p0utils工具类:
package com.hwadee.train.servlet.utils;\
\
import com.mchange.v2.c3p0.ComboPooledDataSource;\
import javax.sql.DataSource;\
\
public class C3p0Utils {\
\
private static DataSource ds;\
static {\
ds = new ComboPooledDataSource();\
}\
public static DataSource getDataSource() {\
return ds;\
}\
}
4、测试:
// 使用DBUtils和c3p0工具包\
public User findByNameAndPwd2(String username,String password){\
try {\
String sql = "SELECT id, username,password,sex,birthday,email,hobby,note " +\
"FROM user " +\
"where username=? and password=?"; //这里使用?占位符\
QueryRunner runner = new QueryRunner(C3p0Utils.getDataSource());\
return (User) runner.query(sql,new BeanHandler(User.class),username,password);\
} catch (SQLException throwables) {\
throwables.printStackTrace();\
}\
return null;\
}
5、数据库增删改查
创建一个通用基础工具类:
package com.hwadee.train.servlet.dao;
import com.hwadee.train.servlet.utils.C3p0Utils;\
import org.apache.commons.dbutils.QueryRunner;\
import org.apache.commons.dbutils.handlers.BeanHandler;\
import org.apache.commons.dbutils.handlers.BeanListHandler;\
\
import java.lang.reflect.ParameterizedType;\
import java.sql.SQLException;\
import java.util.List;\
\
\
public class BaseDAO<T> {\
private Class clasz=null;\
\
public BaseDAO(){\
//获得泛型参数类型的class\
ParameterizedType type = (ParameterizedType) this.getClass().getGenericSuperclass();\
clasz = (Class) type.getActualTypeArguments()[0];\
}\
\
public T find(String sql, Object... parameters) {\
try {\
QueryRunner runner = new QueryRunner(C3p0Utils.getDataSource());\
return (T) runner.query(sql,new BeanHandler(clasz),parameters);\
} catch (SQLException throwables) {\
throwables.printStackTrace();\
}\
return null;\
}\
\
public List<T> finds(String sql, Object... parameters) {\
try {\
QueryRunner runner = new QueryRunner(C3p0Utils.getDataSource());\
return (List<T>) runner.query(sql,new BeanListHandler(clasz),parameters);\
} catch (SQLException throwables) {\
throwables.printStackTrace();\
}\
return null;\
}\
public void update(String sql, Object... parameters) {\
try {\
QueryRunner runner = new QueryRunner(C3p0Utils.getDataSource());\
runner.update(sql,parameters);\
} catch (SQLException throwables) {\
throwables.printStackTrace();\
}\
}\
\
public void create(String sql, Object... parameters) {\
try {\
QueryRunner runner = new QueryRunner(C3p0Utils.getDataSource());\
runner.update(sql,parameters);\
} catch (SQLException throwables) {\
throwables.printStackTrace();\
}\
\
}\
\
public void delete(String sql, Object... parameters){\
try {\
QueryRunner runner = new QueryRunner(C3p0Utils.getDataSource());\
runner.update(sql,parameters);\
} catch (SQLException throwables) {\
throwables.printStackTrace();\
}\
}\
}
创建一个UserBaseDao继承BaseDAO
package com.hwadee.train.servlet.dao;\
\
import com.hwadee.train.servlet.entity.User;\
\
public class UserBaseDao extends BaseDAO<User>{\
}
创建一个UserService
package com.hwadee.train.servlet.srvice;\
\
import com.hwadee.train.servlet.dao.AdminBaseDao;\
import com.hwadee.train.servlet.dao.BaseDAO;\
import com.hwadee.train.servlet.entity.Admin;\
\
public class UserService {\
private BaseDAO<User> baseDAO=new UserBaseDao();\
\
public UserfindByName(String username){\
String sql = "SELECT id, username,password,sex,birthday,email,hobby,note " +\
"FROM user" +\
"where username=?"; //这里使用?占位符\
return baseDAO.find(sql,username);\
}\
}
测试使用:
二、BeanUtils 工具包
在注册页面,因为字段非常多,所以使用getParameter()一个一个地获得值不方便,这里推荐一个封装用户提交数据的工具包。
1、下载
Maven里面查询BeanUtils,下载包及依赖包
mvnrepository.com/artifact/co…
commons-beanutils-1.9.4.jar
commons-collections-3.2.2.jar
commons-logging-1.2.jar
2、引用
把上面的3个包引用到项目中
然后重新添加lib包。
2、使用测试:
BeanUtils.populate(user,req.getParameterMap());
在注册页面,因为实体类有java.util.Date字段,但是页面输入的是String,这样使用BeanUtils自动装配时就会报错:
org.apache.commons.beanutils.ConversionException: DateConverter does not support default String to 'Date' conversion.
那么我们就需要处理这个问题,先阶段我们使用一个简单的方式来处理。
处理步骤:
1)在User实体类里面添加一个转换日期的方法:
public void converterDate(String birthday) {\
Date date = null;\
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");\
if (birthday != null && birthday.trim().length() > 0) {\
try {\
date = sdf.parse(birthday);\
} catch (ParseException e) {\
System.out.println("日期输入错误!!!");\
}\
}\
setBirthday(date);\
}
2)修改注册页面生日的参数名称,使得和实体类属性名不一致,这样BeaUtils自动封装的时候,就找不到匹配的名称,就不会报错。
比如:
3)手动转换:
String date_birthday = req.getParameter("date_birthday");\ user.converterDate(date_birthday);