数据库连接池
数据库连接池用c3p0-0.9.1.2.jar包,通过配置文件的方式来维护数据库连接信息。在类路径下新建c3p0-config.xml文件,内容如下:
<?xml version=\”1.0\” encoding=\”UTF-8\”?>
<c3p0-config>
<named-config name=\”shiro\”>
<!– 指定连接数据源的基本属性 –>
<property name=\”user\”>root</property>
<property name=\”password\”>123456789</property>
<property name=\”driverClass\”>com.mysql.jdbc.Driver</property>
<property name=\”jdbcUrl\”>jdbc:mysql://localhost:3306/shiro?characterEncoding=utf-8</property>
<!– 若数据库中连接数不足时, 一次向数据库服务器申请多少个连接 –>
<property name=\”acquireIncrement\”>5</property>
<!– 初始化数据库连接池时连接的数量 –>
<property name=\”initialPoolSize\”>5</property>
<!– 数据库连接池中的最小的数据库连接数 –>
<property name=\”minPoolSize\”>5</property>
<!– 数据库连接池中的最大的数据库连接数 –>
<property name=\”maxPoolSize\”>20</property>
<!– C3P0 数据库连接池可以维护的 Statement 的个数 –>
<property name=\”maxStatements\”>20</property>
<!– 每个连接同时可以使用的 Statement 对象的个数 –>
<property name=\”maxStatementsPerConnection\”>5</property>
</named-config>
</c3p0-config>
JdbcUtils类
该类主要用来加载c3p0数据源属性,获取connection及释放connection。
/**
* 获取数据库连接,及sql语句
* @author 逍遥居士
* @version V 1.0
*/
public class JdbcUtils {
private static DataSource dataSource = null;
static {
//加载c3p0数据源
dataSource = new ComboPooledDataSource(\”shiro\”);
}
/**
* 返回、connection
*
* @return
* @throws SQLException
*/
public static Connection getConnection()throws SQLException {
return dataSource.getConnection();
}
/**
* 根据sql 语句名获取具体的sql语句命令
*
* @param name
* @return
*/
public static String getSql(String name) {
Map<String, String> sqls = null;
try {
sqls = QueryLoader.instance().load(\”/sql.properties\”);
return sqls.get(name);
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
/**
* 释放连接资源
*
* @param connection
*/
public static void realseDb(Connection connection) {
if (connection != null) {
try {
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
public static void relase(ResultSet reslutSet,Statementsatement) {
if (reslutSet != null) {
try {
reslutSet.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (satement != null) {
try {
satement.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
JDBC Dao 接口
Dao<T> 定义 Dao 的基本操作, 由 BaseDao<T> 提供实现。
/**
* Dao 接口, 定义 Dao 的基本操作, 由 BaseDao 提供实现.
*
* @param <T>:
* Dao 实际操作的泛型类型
* @author 逍遥居士
* @version V 1.0
*/
public interface DAO<T> {
/**
* 执行 INSERT 操作, 返回插入后的记录的 ID
*
* @param sql:
* 待执行的 SQL 语句
* @param args:
* 填充占位符的可变参数
* @return: 插入新记录的 id
*/
int insert(String sql, Object… args);
/**
* 执行 UPDATE 操作, 包括 INSERT(但没有返回值), UPDATE, DELETE
*
* @param sql:
* 待执行的 SQL 语句
* @param args:
* 填充占位符的可变参数
*/
boolean update(String sql, Object… args);
/**
* 执行单条记录的查询操作, 返回与记录对应的类的一个对象
*
* @param sql:
* 待执行的 SQL 语句
* @param args:
* 填充占位符的可变参数
* @return: 与记录对应的类的一个对象
*/
T query(String sql, Object… args);
/**
* 执行多条记录的查询操作, 返回与记录对应的类的一个 List
*
* @param sql:
* 待执行的 SQL 语句
* @param args:
* 填充占位符的可变参数
* @return: 与记录对应的类的一个 List
*/
List<T> queryForList(String sql, Object… args);
/**
* 执行一个属性或值的查询操作, 例如查询某一条记录的一个字段, 或查询某个统计信息, 返回要查询的值
*
* @param sql:
* 待执行的 SQL 语句
* @param args:
* 填充占位符的可变参数
* @return: 执行一个属性或值的查询操作, 例如查询某一条记录的一个字段, 或查询某个统计信息, 返回要查询的值
*/
<E> E getForValue(String sql, Object… args);
/**
* 执行批量更新操作
*
* @param sql:
* 待执行的 SQL 语句
* @param args:
* 填充占位符的可变参数
*/
void batch(String sql, Object[]… args);
}
BaseDao泛型类
BaseDao<T> 实现DAO<T> 的方法。
/**
* 定义BaseDao泛型类
*
* @author 逍遥居士
* @version V 1.0
*
* @param <T><T>
* 实际操作类型
*/
public class BaseDAO<T> implements DAO<T> {
private QueryRunner queryRunner = new QueryRunner();
private Class<T> type;
public BaseDAO() {
type = ReflectionUtils.getSuperGenericType(getClass());
}
/**
* 返回一个具体的值
*
* @param sql
* @param args
* @return
*/
public <E> E getForValue(String sql, Object… args) {
Connection connection = null;
try {
connection = JdbcUtils.getConnection();
return (E) queryRunner.query(connection, sql,new ScalarHandler<>(), args);
} catch (SQLException e) {
e.printStackTrace();
}
finally{
JdbcUtils.realseDb(connection);
}
return null;
}
/**
* 返回多个对象
*
* @param sql
* @param args
* @return
*/
public List<T> queryForList(String sql, Object… args) {
Connection connection = null;
try {
connection = JdbcUtils.getConnection();
return queryRunner.query(connection, sql,new BeanListHandler<>(type), args);
} catch (SQLException e) {
e.printStackTrace();
}
finally{
JdbcUtils.realseDb(connection);
}
return null;
}
/**
* 返回一个对象
*
* @param sql
* @param args
* @return
*/
public T query(String sql, Object… args) {
Connection connection = null;
try {
connection = JdbcUtils.getConnection();
return queryRunner.query(connection, sql,new BeanHandler<>(type), args);
} catch (SQLException e) {
e.printStackTrace();
}
finally{
JdbcUtils.realseDb(connection);
}
return null;
}
/**
* 增、删、改
*
* @param sql
* @param args
*/
public boolean update(String sql, Object… args) {
Connection connection = null;
boolean flag = false;
try {
connection = JdbcUtils.getConnection();
queryRunner.update(connection, sql, args);
flag = true;
} catch (SQLException e) {
e.printStackTrace();
}
finally{
JdbcUtils.realseDb(connection);
}
return flag;
}
/**
* 根据插入的记录获取相应的主键值
*
* @param sql
* @param args
*/
@Override
public int insert(String sql, Object… args) {
int id = 0;
Connection connection = null;
java.sql.PreparedStatement preparedStatement = null;
ResultSet resultSet = null;
try {
connection = JdbcUtils.getConnection();
preparedStatement = connection.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
if (args != null) {
for (int i = 0; i < args.length; i++) {
preparedStatement.setObject(i + 1, args[i]);
}
}
preparedStatement.executeUpdate();
resultSet = preparedStatement.getGeneratedKeys();
if (resultSet.next()) {
id = resultSet.getInt(1);
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
JdbcUtils.relase(resultSet, preparedStatement);
}
return id;
}
/**
* 批量处理
*
* @param sql
* @param args
*/
@Override
public void batch(String sql, Object[]… args) {
Connection connection = null;
try {
connection = JdbcUtils.getConnection();
queryRunner.batch(connection, sql, args);
} catch (SQLException e) {
e.printStackTrace();
}
}
}
具体业务DAO实现
根据不同的业务来定义需要的接口,例如维护用户信息(CRUD)的UserDao。
在数据持久层定义UserDao的实现类UserDaoImpl去继承BaseDao泛型类实现具体的UserDao。
在逻辑业务层去实例化UserDaoImpl,再调用相应的方法完成数据的CRUD。