学习使用DbUtils有感
参考
https://www.cnblogs.com/smyhvae/p/4085684.html
1、DbUtils是什么?
Commons DbUtils是Apache组织提供的一个对JDBC进行简单封装的开源工具类库,使用它能够简化JDBC应用程序的开发,同时也不会影响程序的性能。
DbUtils:主要是封装了JDBC的代码,简化了Dao(Data Acess Object)层的操作。帮助java程序员,更高效的开发Dao层代码的简单框架。
3.Dbutils三个核心类介绍:
1:DbUtils:连接数据库对象----jdbc辅助方法的集合类,线程安全
构造方法:DbUtils()
作用:控制连接,控制书屋,控制驱动加载额一个类。
2:QueryRunner:SQL语句的操作对象,可以设置查询结果集的封装策略,线程安全。
构造方法:
(1)QueryRunner():创建一个与数据库无关的QueryRunner对象,后期再操作数据库的会后,需要手动给一个Connection对象,它可以手动控制事务。
Connection.setAutoCommit(false); 设置手动管理事务
Connection.commit(); 提交事务
(2) QueryRunner(DataSource ds):创建一个与数据库关联的queryRunner对象,后期再操作数据库的时候,不需要Connection对象,自动管理事务。
DataSource:数据库连接池对象。
构造函数与增删改查方法的组合:
QueryRunner()
update(Connection conn, String sql, Object... params)
query(Connection conn, String sql, ResultSetHandler<T> rsh, Object... params)
QueryRunner(DataSource ds)
update(String sql, Object... params)
query(String sql, ResultSetHandler<T> rsh, Object... params)
(3)ResultSetHandle:封装数据的策略对象------将封装结果集中的数据,转换到另一个对象
策略:封装数据到对象的方式(示例:将数据库保存在User、保存到数组、保存到集合)
方法介绍:handle(ResultSet rs)
备注:详解参考ResultSetHandle实现类
4.Dbutils快速入门
使用Dbutils注意事项:
(1)需要导入的jar包:①MySql驱动 ②DbUtils包
(2)db-config.properties:属性文件,方便修改配置信息;
(3)可以自行添加一个JDBCUtils工具类:
QueryRunner的源码阅读,转自@N3verL4nd的博客
https://blog.csdn.net/x_iya/article/details/77370161
阅读源码是个好习惯,可更好的去使用DbUtils。
获取DbUtils
下载上图中的红框部分,然后解压。解压之后的文件如下:
上图中红框部分的文件就是我们所需要的内容。
二、核心方法:
DbUtils中的核心的类是QueryRunner类。来看一下里面的核心方法:
Query方法:
//源码
/**
* 执行一个带有替换参数的SQL SELECT查询
* 调用者负责关闭连接
* T:处理器返回对象的类型
* conn:执行查询的 Connection 对象
* sql:执行的查询语句
* rsh:将ResultSet 转换为其他对象的处理器
* params:可变参数列表,用于替换sql语句中的占位符
* 由 ResultSetHandler 负责返回相应对象
* 数据库访问出错则抛出 SQLException 异常
*/
public <T> T query(Connection conn, String sql, ResultSetHandler<T> rsh, Object... params) throws SQLException
/**
* 同上,只是不带有可变参数列表
*/
public <T> T query(Connection conn, String sql, ResultSetHandler<T> rsh) throws SQLException
/**
* 同上,只是不带有 Connection 参数,它会从构造函数的 DataSource 参数中获取
*/
public <T> T query(String sql, ResultSetHandler<T> rsh, Object... params) throws SQLException
/**
* 同上
*/
public <T> T query(String sql, ResultSetHandler<T> rsh) throws SQLException
//实际应用
//返回bean
User user = runner.query("select * from user where userId=?",1,new BeanHandler<User>(User.class));
//返回beanlist
System.out.println("返回BeanList结果......");
List<User> beanListResult =runner.query("select * from user",new BeanListHandler(User.class));
//返回一个值
Object increaseId=runner.query("select last_insert_id()", new ScalarHandler());
Update方法:
//源码
/**
* 执行 SQL INSERT, UPDATE, 或者 DELETE 操作
* 返回更新的行数
*/
public int update(Connection conn, String sql) throws SQLException {
return this.update(conn, false, sql, (Object[]) null);
}
/**
* 同上,带有一个参数
*/
public int update(Connection conn, String sql, Object param) throws SQLException {
return this.update(conn, false, sql, new Object[]{param});
}
/**
* 同上,带有可变参数
*/
public int update(Connection conn, String sql, Object... params) throws SQLException {
return update(conn, false, sql, params);
}
//实际应用
String sql = "update tb_Customer set Customer_id=?,Customer_name=?,Sex=?,Tel=?,Id=?,C_type=?,Remark=? where Customer_id=?";
int rowEffects= runner.update(DBUtils.getConnection(), sql, p.getCustomer_id(),p.getCustomer_name(),p.getSex(),p.getTel(),p.getId(),p.getC_type(),p.getRemark(),p.getCustomer_id());
代码实现:
先看一下整个工程的文件结构:(只有展开的类才是所需要的)
DbUtils:初步封装的JDBC工具类;db-config.properties:属性文件,方便修改配置信息;
Customer类就是领域模型,表示是对它(数据库表)进行增删改查。
CustomerDao接口:专门对Customer类进行操作(例如增删改查)的接口。注:这里不直接写操作类,是因为接口利于维护,可以在这里写上公共的代码。一个领域模型对应一个Dao接口。
CustomerDaoImpl类:实现上面的CustomerDao接口(也就是在这里用到了DbUtils工具,避免了自己写很多代码)
步骤如下:
首先创建数据库表:Customer. 字段:Customer_id,Customer_name,Sex,Tel,Id,C_type,Remark建表命令如下:
CREATE TABLE tb_Customer(
Customer_id char(10) NOT NULL PRIMARY key ,
Customer_name nvarchar(20) NOT NULL,
Sex char(2) NOT NULL,
Tel char(11) NOT NULL,
Id nchar(18) NOT NULL,
C_type char(10) NOT NULL,
Remark nvarchar(30) NULL
)
往里面填充简单的数据
接下来是具体的代码实现:
打开eclipse,新建Java工程,然后在根目录下新建一个文件夹libs,将mysql-connector-java-5.1.46-bin.jarr和刚刚下载好的commons-dbutils-1.7.jar添加到工程的Build path中。
DbUtils工具类
package com.util.db;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ResourceBundle;
import java.sql.PreparedStatement;
/**
* 数据库操作工具类
*
* @author lamp
*
*/
public class DBUtils {
// 数据库连接地址
public static String URL;
// 用户名
public static String USERNAME;
// 密码
public static String PASSWORD;
// mysql的驱动类
public static String DRIVER;
//注意获取属性文件的包名是否正确。稍后会定义这个属性文件。
private static ResourceBundle rb = ResourceBundle.getBundle("com.util.db.db-config");
private DBUtils() {
}
// 使用静态块加载驱动程序
static {
URL = rb.getString("jdbc.url");
USERNAME = rb.getString("jdbc.username");
PASSWORD = rb.getString("jdbc.password");
DRIVER = rb.getString("jdbc.driver");
try {
Class.forName(DRIVER);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
// 定义一个获取数据库连接的方法
public static Connection getConnection() {
Connection conn = null;
try {
conn = DriverManager.getConnection(URL, USERNAME, PASSWORD);
} catch (SQLException e) {
e.printStackTrace();
System.out.println("获取连接失败");
}
return conn;
}
}
// 关闭数据库连接
public static void close(ResultSet rs, Statement stat, Connection conn) {
try {
if (rs != null)
rs.close();
if (stat != null)
stat.close();
if (conn != null)
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
注意:获取属性文件的包名是否正确。稍后会定义这个属性文件。
(2)接下来新建一个属性文件,new–>file,命名为:db-config.properties,代码如下:
jdbc.url=jdbc:mysql://localhost:3306/Gym
jdbc.username=root
jdbc.password=root
jdbc.driver=com.mysql.jdbc.Driver
//若传输中文字符乱码可加上?useUnicode=true&characterEncoding=utf8
以后如果需要修改配置信息,只需要在这里改就行了。注意在上面的DBUtils类中是怎么来调用这个配置信息的。
(3)新建文件,定义好Customer类(package com.zonkidd.model)
package com.zonkidd.model;
public class Customer {
private String Customer_id;
private String Customer_name;
private String Sex;
private String Tel;
private String Id;
private String C_type;
private String Remark;
public Customer() {
}
public Customer(String Customer_id) {
this.Customer_id=Customer_id;
}
public Customer(String Customer_id,String Customer_name,String Sex,String Tel, String Id,String C_type,String Remark) {
this.Customer_id=Customer_id;
this.Customer_name=Customer_name;
this.Sex=Sex;
this.Tel=Tel;
this.Id=Id;
this.C_type=C_type;
this.Remark=Remark;
}
public String getCustomer_id() {
return Customer_id;
}
public void setCustomer_id(String customer_id) {
this.Customer_id = customer_id;
}
public String getCustomer_name() {
return Customer_name;
}
public void setCustomer_name(String customer_name) {
this.Customer_name = customer_name;
}
public String getSex() {
return Sex;
}
public void setSex(String sex) {
this.Sex = sex;
}
public String getTel() {
return Tel;
}
public void setTel(String tel) {
this.Tel = tel;
}
public String getId() {
return Id;
}
public void setId(String id) {
this.Id = id;
}
public String getC_type() {
return C_type;
}
public void setC_type(String c_type) {
this.C_type = c_type;
}
public String getRemark() {
return Remark;
}
public void setRemark(String remark) {
this.Remark = remark;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Customer other = (Customer) obj;
if (Customer_id != other.Customer_id)
return false;
return true;
}
@Override
public String toString() {
return "tb_Customer [Customer_id=" + Customer_id + ", Customer_name=" + Customer_name + ", Sex=" + Sex
+ ", Tel=" + Tel + ", Id=" + Id + ", C_type=" + C_type + ", Remark=" + Remark + "]";
}
}
这个Customer类就是领域模型,表示是对它进行增删改查。
紧接着定义CustomerDao接口:专门对Customer类进行操作(例如增删改查)的接口(package com.zonkidd.dao)
注意:是定义接口,不是定义类。代码如下:
package com.zonkidd.dao;
import java.util.List;
import com.zonkidd.model.Customer;
import java.sql.SQLException;
import com.zonkidd.model.Customer;
public interface CustomerDao {
// 添加方法
public void add(Customer p) throws SQLException;
// 更新方法
public void update(Customer p) throws SQLException;
// 删除方法
public void delete(String id) throws SQLException;
// 查找方法
public Customer findById(int id) throws SQLException;
// 查找所有
public List<Customer> findAll() throws SQLException;
// 查询有几条记录
public long CustomerCount() throws SQLException;
}
(4)然后,定义CustomerDaoImpl实现类 ,实现上面的CustomerDao接口(package com.zonkidd.dao.impl)
package com.zonkidd.dao.impl;
import java.sql.SQLException;
import java.util.List;
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.util.db.DBUtils;
import com.zonkidd.model.Customer;
import com.zonkidd.dao.CustomerDao;
import com.zonkidd.model.Customer;
public class CustomerDaoImpl implements CustomerDao {
private QueryRunner runner = null;//查询运行器
public CustomerDaoImpl(){
runner = new QueryRunner();
}
//方法:向数据库中添加一条记录
@Override
//Customer_id,Cusotmer_name,Sex,Tel,Id,C_type, Remark
public void add(Customer p) throws SQLException {
String sql = "insert into tb_Customer(Customer_id,Customer_name,Sex,Tel,Id,C_type, Remark)values(?,?,?,?,?,?,?)";
runner.update(DBUtils.getConnection(), sql, p.getCustomer_id(),p.getCustomer_name(),p.getSex(),p.getTel(),p.getId(),p.getC_type(),p.getRemark());
}
//方法:根据id向数据库中修改某条记录
@Override
public void update(Customer p) throws SQLException {
String sql = "update tb_Customer set Customer_id=?,Customer_name=?,Sex=?,Tel=?,Id=?,C_type=?,Remark=? where Customer_id=?";
runner.update(DBUtils.getConnection(), sql, p.getCustomer_id(),p.getCustomer_name(),p.getSex(),p.getTel(),p.getId(),p.getC_type(),p.getRemark(),p.getCustomer_id());
}
//方法:根据id删除数据库中的某条记录
@Override
public void delete(String id) throws SQLException {
String sql = "delete from tb_Customer where Customer_id=?";
runner.update(DBUtils.getConnection(), sql, id);
}
//方法:使用BeanHandler查询一个对象
@Override
public Customer findById(int id) throws SQLException {
String sql = "select * from tb_Customer where Customer_id=?";
Customer p = runner.query(DBUtils.getConnection(), sql, new BeanHandler<Customer>(Customer.class),id);
return p;
}
//方法:使用BeanListHandler查询所有对象
@Override
public List<Customer> findAll() throws SQLException {
String sql = "select * from tb_Customer";
List<Customer> persons = runner.query(DBUtils.getConnection(), sql, new BeanListHandler<Customer>(Customer.class));
return persons;
}
//方法:使用ScalarHandler查询一共有几条记录
@Override
public long CustomerCount()throws SQLException{
String sql = "select count(Customer_id) from tb_Customer";
return runner.query(DBUtils.getConnection(),sql, new ScalarHandler<Long>());
}
}
package com.zonkidd.test;
import java.sql.SQLException;
import java.util.List;
import com.zonkidd.dao.CustomerDao;
import com.zonkidd.dao.impl.CustomerDaoImpl;
import com.zonkidd.model.Customer;
public class Test {
public static void main(String[] args) throws SQLException {
CustomerDao dao = new CustomerDaoImpl();
//dao.update(new Customer("20180013", "zonkidd",
// "男", "15625523364", "123456789112345678","1", ""));
//dao.add(new Customer("20180014", "zonkidd",
// "男", "15625523364", "123456789112345678","1", ""));
//dao.delete("4");
Customer p = dao.findById(2018002);
System.out.println(p);
List<Customer> Customers = dao.findAll();
System.out.println(Customers);
}
}
运行结果:
Mysql:
控制台: