DBUtils 学习使用
2018-06-18 01:37:27来源:未知 阅读 ()
DBUtils 学习使用
commons-dbutils简介
commons-dbutils是Apache组织提供的一个开源JDBC工具类库,它是对JDBC的简单封装,学习成本极低,并且使用dbutils能极大简化jdbc编码的工作量,同时也不会影响程序的性能。因此dbutils成为很多不喜欢hibernate的公司的首选。 dbutils的官方网站http://commons.apache.org/proper/commons-dbutils/download_dbutils.cgi
dbutils 优点
- 对于数据表的读操作,他可以把结果转换成List,Array,Set等java集合,便于程序员操作;
- 对于数据表的写操作,也变得很简单(只需写sql语句)
- 可以使用数据源,使用JNDI,数据库连接池(dbcp,c3p0)等技术来优化性能--重用已经构建好的数据库连接对象,而不像php,asp那样,费时费力的不断重复的构建和析构这样的对象。
commons-dbutils API介绍
- org.apache.commons.dbutils.QueryRunner QueryRunner (insert、update、delete使用)
- org.apache.commons.dbutils.ResultSetHandler (用于查询结果处理使用)
- org.apache.commons.dbutils.DbUtils (工具类)
QueryRunner 类的主要方法
public Object query(Connection conn, String sql, Object[] params, ResultSetHandler rsh) throws SQLException
执行一个查询操作,在这个查询中,对象数组中的每个元素值被用来作为查询语句的置换参数。该方法会自行处理PreparedStatement和ResultSet的创建和关闭。
public Object query(String sql, Object[] params, ResultSetHandler rsh) throws SQLException
几乎与第一种方法一样;唯一的不同在于它不将数据库连接提供给方法,并且它是从提供给构造方法的数据源(DataSource)或使用的setDataSource方法中重新获得Connection。
public Object query(Connection conn, String sql, ResultSetHandler rsh) throws SQLException
执行一个不需要置换参数的查询操作。
public int update(Connection conn, String sql, Object[] params) throws SQLException
用来执行一个更新(插入、更新或删除)操作。
public int update(Connection conn, String sql) throws SQLException
用来执行一个不需要置换参数的更新操作。
public int[] batch(Connection conn, String sql, Object[][] params) throws SQLException
这个方法对应着批处理,经常用于在同一个表中批量插入数据,或批量更新表的数据。 该方法为何会接收二维数组Object[][] params
呢? 答:例如现在要想在同一个表中批量插入数据,编写的SQL语句为:
String sql = "insert into users(id,name) values(?,?)";
该方法接收二维数组Object[][] params
,那么调用其的时候就要传递一个诸如这样的实参[[1,aa],[2,bb],[3,cc]]
,即用二维数组里面的每一个一维数组生成一条sql语句。 那为何又会返回int[]
呢? 答:该方法的返回值是int[]
,所以会返回诸如这样的结果:[1,1,1]
,意思是生成的第一条sql语句影响数据库几行、生成的第二条sql语句影响数据库几行、生成的第三条sql语句影响数据库几行。
ResultSetHandler接口使用讲解
该接口用于处理java.sql.ResultSet,将数据按要求转换为另一种形式。ResultSetHandler接口提供了一个单独的方法:Object handle (java.sql.ResultSet .rs)
。
ResultSetHandler接口的实现类
- ArrayHandler:把结果集中的第一行数据转成对象数组。
- ArrayListHandler:把结果集中的每一行数据都转成一个数组,再存放到List中。
- BeanHandler:将结果集中的第一行数据封装到一个对应的JavaBean实例中。
- BeanListHandler:将结果集中的每一行数据都封装到一个对应的JavaBean实例中,存放到List里。
- ColumnListHandler:将结果集中某一列的数据存放到List中。
- KeyedHandler(name):将结果集中的每一行数据都封装到一个Map里,再把这些map再存到一个map里,其key为指定的key。
- MapHandler:将结果集中的第一行数据封装到一个Map里,key是列名,value就是对应的值。
- MapListHandler:将结果集中的每一行数据都封装到一个Map里,然后再存放到List。
DbUtils类使用讲解
DbUtils:提供如关闭连接、装载JDBC驱动程序等常规工作的工具类,里面的所有方法都是静态的。主要方法如下:
public static void close(…) throws java.sql.SQLException
DbUtils类提供了三个重载的关闭方法。这些方法检查所提供的参数是不是NULL,如果不是的话,它们就关闭Connection、Statement和ResultSet。public static void closeQuietly(…)
这一类方法不仅能在Connection、Statement和ResultSet为NULL情况下避免关闭,还能隐藏一些在程序中抛出的SQLException。public static void commitAndCloseQuietly(Connection conn)
用来提交连接,然后关闭连接,并且在关闭连接时不抛出SQL异常。public static boolean loadDriver(java.lang.String driverClassName)
这一方法装载并注册JDBC驱动程序,如果成功就返回true。使用该方法,你不需要捕捉这个异常ClassNotFoundException。
使用DBUtils完成数据库的CRUD
在使用DBUtils完成数据库的CRUD之前,我们先编写测试用的SQL脚本:
CREATE TABLE `user` (
`id` int(11) NOT NULL auto_increment,
`name` varchar(50) NOT NULL,
`age` tinyint(10) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
使用dbutils遵从以下步骤
- 加载JDBC驱动程序类,并用DriverManager来得到一个数据库连接conn。
- 实例化 QueryRunner,得到实例化对象qRunner。
- qRunner.update()方法,执行增改删的sql命令,qRunner.query()方法,得到结果集。
获取连接对象
private static final String url = "jdbc:mysql://192.168.1.15:3306/test?useUnicode=true&characterEncoding=utf8";
private static final String driver = "com.mysql.jdbc.Driver";
private static final String user = "znsd_test";
private static final String password = "123456";
public static Connection getConnect() {
Connection conn = null;
try {
Class.forName(driver);
conn = DriverManager.getConnection(url, user, password);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
return conn;
}
创建bean对象关联数据库
public class User implements Serializable {
private Integer id; // 用户ID
private String name; // 用户姓名
private Integer age; // 用户年龄
// ...忽略set、get方法
}
添加
public Integer add(User user) {
QueryRunner queryRunner = new QueryRunner();
Connection connect = ConnectionUtil.getConnect();
try {
return queryRunner.update(connect, "insert into user(name, age) values(?, ?)", user.getName(), user.getAge());
} catch (SQLException e) {
e.printStackTrace();
} finally {
DbUtils.closeQuietly(connect);
}
return 0;
}
修改
public Integer update(User user) {
QueryRunner queryRunner = new QueryRunner();
Connection conn = ConnectionUtil.getConnect();
try {
return queryRunner.update(conn , "update user set name = ?, age = ? where id = ?", user.getName(), user.getAge(), user.getId());
} catch (SQLException e) {
e.printStackTrace();
} finally {
DbUtils.closeQuietly(conn);
}
return 0;
}
删除
public Integer delete(Integer id) {
QueryRunner queryRunner = new QueryRunner();
Connection conn = ConnectionUtil.getConnect();
try {
return queryRunner.update(conn , "delete from user where id = ?", id);
} catch (SQLException e) {
e.printStackTrace();
} finally {
DbUtils.closeQuietly(conn);
}
return 0;
}
批量添加
public int[] batch(Object[][] values) {
QueryRunner queryRunner = new QueryRunner();
Connection conn = ConnectionUtil.getConnect();
try {
return queryRunner.batch(conn, "insert into user(name, age) values(?, ?)", values);
} catch (SQLException e) {
e.printStackTrace();
} finally {
DbUtils.closeQuietly(conn);
}
return null;
}
查询所有
public List<User> select() {
QueryRunner queryRunner = new QueryRunner();
Connection conn = ConnectionUtil.getConnect();
try {
return queryRunner.query(conn, "select id id1, name, age from user", new UserBeanListHandler(User.class));
} catch (SQLException e) {
e.printStackTrace();
} finally {
DbUtils.closeQuietly(conn);
}
return null;
}
查询返回map
public List<Map<String, Object>> selectAsMap() {
QueryRunner queryRunner = new QueryRunner();
Connection conn = ConnectionUtil.getConnect();
try {
List<Map<String, Object>> userMaps = queryRunner.query(conn, "select id id1, name, age from user", new MapListHandler());
return userMaps;
} catch (SQLException e) {
e.printStackTrace();
} finally {
DbUtils.closeQuietly(conn);
}
return null;
}
查询单个对象
public User selectOne(Integer id) {
QueryRunner queryRunner = new QueryRunner();
Connection conn = ConnectionUtil.getConnect();
try {
return queryRunner.query(conn, "select id id1, name, age from user where id = ? limit 1", new BeanHandler<User>(User.class) {
@Override
public User handle(ResultSet rs) throws SQLException {
if (rs.next()) {
return new User(rs.getInt("id1"), rs.getString("name"), rs.getInt("age"));
}
return null;
}
}, id);
} catch (SQLException e) {
e.printStackTrace();
} finally {
DbUtils.closeQuietly(conn);
}
return null;
}
结合c3p0数据源使用dbutils
c3p0简介
C3P0是一个开源的JDBC连接池,它实现了数据源和JNDI绑定,支持JDBC3规范和JDBC2的标准扩展。目前使用它的开源项目有Hibernate,Spring等
数据库连接池简介
数据库连接池负责分配、管理和释放数据库连接,它允许应用程序重复使用一个现有的数据库连接,而不是再重新建立一个;连接池允许多个客户端使用缓存起来的连接对象,这些对象可以连接数据库,它们是共享的、可被重复使用的。
打开/关闭数据库连接开销很大,连接池技术允许我们在连接池里维护连接对象,这样可以提高数据库的执行命令的性能。多个客户端请求可以重复使用相同的连接对象,当每次收到一个客户端请求时,就会搜索连接池,看看有没有闲置的连接对象。如果没有闲置对象的话,要么所有的客户端请求都进入队列排队,要么在池中创建一个新的连接对象(这取决于池里已经有多少个连接存在以及配置支持多少连接)。一旦某个请求使用完连接对象之后,这个对象会被重新放入池中,然后会被重新分派给排队等待的请求(分派给哪个请求要看使用什么调度算法)。因为大部分请求都是使用现存的连接对象,所以连接池技术大大减少了等待创建数据库连接的时间,从而减少了平均连接时间。
使用连接池的优点
- 资源重用:
由于数据库连接得以重用,避免了频繁创建,释放连接引起的大量性能开销。在减少系统消耗的基础上,另一方面也增加了系统运行环境的平稳性。
- 更快的系统反应速度:
数据库连接池在初始化过程中,往往已经创建了若干数据库连接置于连接池中备用。此时连接的初始化工作均已完成。对于业务请求处理而言,直接利用现有可用连接,避免了数据库连接初始化和释放过程的时间开销,从而减少了系统的响应时间。
- 统一的连接管理,避免数据库连接泄露:
在较为完善的数据库连接池实现中,可根据预先的占用超时设定,强制回收被占用连接,从而避免了常规数据库连接操作中可能出现的资源泄露。
使用步骤
- 首先要导入c3p0和dbutils以及mysql的jar包
- c3p0-0.9.5.2.jar
- commons-dbutils-1.7.jar
- mchange-commons-java-0.2.11.jar
- mysql-connector-java-5.1.22.jar
- 编写c3p0的配置文件c3p0-config.xml
在src目录下存放c3p0的配置文件,配置文件是c3p0自己去识别并读入的,我们不需要在代码中做任何的操作,但是配置文件一定要命名为c3p0-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<c3p0-config>
<!-- 这是默认配置信息 -->
<default-config>
<!-- jdbc连接四大参数配置 -->
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql://192.168.1.15:3306/test</property>
<property name="user">znsd_test</property>
<property name="password">123456</property>
<!-- 池参数配置 -->
<!--JDBC的标准参数,用以控制数据源内加载的PreparedStatements数量。但由于预缓存的statements
属于单个connection而不是整个连接池。所以设置这个参数需要考虑到多方面的因素。
如果maxStatements与maxStatementsPerConnection均为0,则缓存被关闭。Default: 0
-->
<property name="acquireIncrement">3</property>
<!--初始化时获取的连接数,取值应在minPoolSize与maxPoolSize之间。Default: 3 -->
<property name="initialPoolSize">10</property>
<!--连接池中保留的最小连接数。-->
<property name="minPoolSize">2</property>
<!--连接池中保留的最大连接数。Default: 15 -->
<property name="maxPoolSize">10</property>
</default-config>
</c3p0-config>
- 使用c3p0获取获取数据库连接对象
public class C3p0ConnectionUtil {
// 配置文件的默认配置!要求你必须给出c3p0-config.xml
private static ComboPooledDataSource c3p0DataSource = new ComboPooledDataSource();
/**
* 获取连接对象
* @return
*/
public static Connection getConnection() {
try {
// 得到连接器
return c3p0DataSource.getConnection();
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
/**
* 获取数据源
*
* @return
*/
public static DataSource getDataSource() {
return c3p0DataSource;
}
}
- dbutils 使用c3p0
public Integer add(User user) {
QueryRunner queryRunner = new QueryRunner(C3p0ConnectionUtil.getDataSource());
try {
return queryRunner.update("insert into user(name, age) values(?, ?)", user.getName(), user.getAge());
} catch (SQLException e) {
e.printStackTrace();
}
return 0;
}
- 返回主键例子
public Integer add(User user) {
DataSource dataSource = C3p0ConnectionUtil.getDataSource();
QueryRunner queryRunner = new QueryRunner(dataSource);
try {
String sql = "insert into user(name, age) values(?, ?)";
// 需要条用insert方法,指定MapHandler参数
Map<String, Object> idMap = queryRunner.insert(sql, new MapHandler() {
@Override
public Map<String, Object> handle(ResultSet rs) throws SQLException {
//rs = rs.getStatement().getGeneratedKeys();
// 获取主键
int id = rs.next() ? rs.getInt(1) : -1;
// 将数据库返回主键放入map中
Map<String, Object> idMap = new HashMap<String, Object>();
idMap.put("id", id);
return idMap;
}
}, user.getName(), user.getAge());
return (Integer) idMap.get("id");
} catch (SQLException e) {
e.printStackTrace();
}
return 0;
}
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
- PHP访问MySQL查询超时怎么办 2020-03-09
- MySQL中使用WHERE子句的方法 2019-10-25
- PHP进阶学习之垃圾回收机制详解 2019-10-09
- 关于laravel后台模板laravel-admin select框的使用详解 2019-10-08
- PHP语言好不好?优势在哪里? 2019-09-30
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash