Java Druid连接池与Apache的DBUtils使用教程

作者:Java 时间:2021-07-29 13:21:44 

Java Druid连接池与Apache的DBUtils使用教程

Druid连接池

连接池思想

在程序初始化时,提前创建好指定数量的数据库连接对象存储在“池子”中(这个池子称为“连接池”),当需要连接数据库的时候,从这个“池子”中取出一个连接对象使用,使用完毕后,不会将这个连接对象关闭,而是将这个连接对象放回“池子”中,实现复用,节省资源。

Druid连接池使用步骤

引入相关jar包

在lib文件夹中引入druid-1.1.5.jar文件和mysql-connector-java-5.1.0-bin.jar文件,并将两个jar文件配置到项目中。

创建database.properties配置文件

在src文件夹下创建database.properties配置文件,配置文件中内容如下: 连接设置

初始化连接,连接池连接对象数量

最大连接数

最小空闲连接

超时等待时间(毫秒为单位)

# 连接设置
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/jdbcdatabase
username=root
password=123456

# 初始化连接,连接池连接对象数量
initialSize=10

#最大连接数
maxActive=30

#最小空闲连接
maxIdle=5

#超时等待时间(毫秒为单位)
maxWait=3000

编写连接池工具类

声明一个连接池对象

实例化配置文件对象

  • 加载配置文件内容

  • 创建连接池

获取连接对象

  • 通过连接池获得连接对象

释放资源,将连接对象放入连接池中

  • 使用完连接对象后,将连接对象还给连接池,这里的close()方法是DruidPooledConnection

  • 实现类里的close()方法,将connection连接对象还给连接池

package com.cxyzxc.www.utils;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.pool.DruidDataSourceFactory;
public class DBUtils {
// 声明一个连接池对象
private static DruidDataSource druidDataSource;
static {
// 实例化配置文件对象
Properties properties = new Properties();
try {
// 加载配置文件内容
InputStream is = DBUtils.class
.getResourceAsStream("/database.properties");
properties.load(is);
// 创建连接池
druidDataSource = (DruidDataSource) DruidDataSourceFactory
.createDataSource(properties);
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
// 获取连接对象
public static Connection getConnection() {
try {
// 通过连接池获得连接对象
return druidDataSource.getConnection();
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
// 释放资源,将连接对象放入连接池中
public static void closeAll(Connection connection, Statement statement,
ResultSet resultSet) {
try {
if (resultSet != null) {
resultSet.close();
}
if (statement != null) {
statement.close();
}
if (connection != null) {
// 使用完连接对象后,将连接对象还给连接池,这里的close()方法是DruidPooledConnection实现类里的close()方法,将connection连接对象还给连接池
connection.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}

Druid连接池测试

package com.cxyzxc.www.utils;
import java.sql.Connection;
public class Test {
public static void main(String[] args) {
// 获取20个连接对象,输出连接对象,地址值不同
for (int i = 1; i <= 20; i++) {
Connection connection = DBUtils.getConnection();
System.out.println(connection);
// 调用关闭连接对象的方法后,发现获取的20个连接对象地址值是同一个,说明每次从连接池中取出的连接对象是同一个
// DBUtils.closeAll(connection, null, null);
}
}
}

Apache的DBUtils使用

&emsp;&emsp;前面的DBUtils工具类是我们经过千难万阻自己封装的,也有一些组织给我们封装DBUtils工具类,比如Apache组织提供了一个对JDBC进行简单封装的开源工具类库Commons DbUtils类,使用它能够简化JDBC应用程序的开发,同时也不影响程序的性能。

Apache DBUtils介绍

Apache DBUtils特征

Apache DBUtils是java编程中的数据库操作实用工具,小巧简单实用,主要特征有:

1)对于数据表的读操作,他可以把结果转换成List,Array,Set等java集合,便于程序员操作;

2)对于数据表的写操作,也变得很简单(只需写sql语句)

3)可以使用数据源,使用JNDI,数据库连接池等技术来优化性能&ndash;重用已经构建好的数据库连接对象,而不像php,asp那样,费时费力的不断重复的构建和析构这样的对象。

Apache DbUtils主要组成

1)ResultSetHandler接口:转换类型接口

  • BeanHandler类:实现类,把一条记录转换成对象。

  • BeanListHandler类:实现类,把多条记录转换成List集合。

  • ScalarHandler类:实现类,适合获取一行一列的数据。

2)QueryRunner类:执行SQL语句的类

  • update()方法:增、删、改

  • query()方法:查询 &emsp;

Apache DbUtils使用步骤

1)创建lib文件夹,导入需要的jar包,并将其配置到项目中

  • mysql-connector-java-5.1.0-bin.jar

  • druid-1.1.5.jar

  • commons-dbutils-1.7.jar

2)在src文件夹下创建database.properties配置文件,配置文件中内容如下:

  • 连接设置

  • 初始化连接,连接池连接对象数量

  • 最大连接数

  • 最小空闲连接

  • 超时等待时间(毫秒为单位)

# 连接设置
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/jdbcdatabase
username=root
password=123456

# 初始化连接,连接池连接对象数量
initialSize=10

#最大连接数
maxActive=30

#最小空闲连接
maxIdle=5

#超时等待时间(毫秒为单位)
maxWait=3000

3)编写DBUtils连接池工具类

声明一个连接池对象

实例化配置文件对象

  • 加载配置文件内容

  • 创建连接池

返回一个数据源

package com.cxyzxc.www.utils;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
import javax.sql.DataSource;
import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.pool.DruidDataSourceFactory;
public class DBUtils {
// 声明一个连接池对象
private static DruidDataSource druidDataSource;
static {
// 实例化配置文件对象
Properties properties = new Properties();
try {
// 加载配置文件内容
InputStream is = DBUtils.class
.getResourceAsStream("/database.properties");
properties.load(is);
// 创建连接池
druidDataSource = (DruidDataSource) DruidDataSourceFactory
.createDataSource(properties);
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
//返回一个数据源
public static DataSource getDataSource(){
return druidDataSource;
}
}

综合案例

创建product表

CREATE TABLE IF NOT EXISTS `product` (
`pid` INT PRIMARY KEY AUTO_INCREMENT COMMENT '产品编号',
`pname` VARCHAR(20) NOT NULL COMMENT '产品名称',
`price` DOUBLE NOT NULL COMMENT '产品价格',
`birthday` DATE NOT NULL COMMENT '产品生产日期'
);

向表中添加数据

INSERT INTO `product`(`pid`,`pname`,`price`,`birthday`)VALUES(1001,'虎皮凤爪',20.5,'2022-06-12');
INSERT INTO `product`(`pid`,`pname`,`price`,`birthday`)VALUES(1002,'卧龙锅巴',18.5,'2022-09-22');

创建实体类Product

  • 添加实体类的私有变量

  • 添加有参无参构造方法

  • 添加get/set方法

  • 重写toString()方法

package com.cxyzxc.www.entity;
import java.util.Date;
public class Product {
private int pid;
private String pname;
private double price;
private Date birthday;
public Product() {
super();
}
public Product(String pname, double price, Date birthday) {
super();
this.pname = pname;
this.price = price;
this.birthday = birthday;
}
public Product(int pid, String pname, double price, Date birthday) {
super();
this.pid = pid;
this.pname = pname;
this.price = price;
this.birthday = birthday;
}
public int getPid() {
return pid;
}
public void setPid(int pid) {
this.pid = pid;
}
public String getPname() {
return pname;
}
public void setPname(String pname) {
this.pname = pname;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
@Override
public String toString() {
return "Product [pid=" + pid + ", pname=" + pname + ", price=" + price
+ ", birthday=" + birthday + "]";
}
}

创建ProductDao接口

创建ProductDao接口,实现增删改查方法名的统一。

package com.cxyzxc.www.dao;
import java.util.List;
import com.cxyzxc.www.entity.Product;
public interface ProductDao {
//添加
int insert(Product product);
//删除
int delete(int pid);
//修改
int update(Product product);
//查询单个
Product selectOne(int pid);
//查询所有
List<Product> selectAll();
}

创建ProductDaoImpl实现类

创建ProductDaoImpl实现类来实现ProductDao接口,在重新方法中编写具体的逻辑代码。

package com.cxyzxc.www.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 com.cxyzxc.www.dao.ProductDao;
import com.cxyzxc.www.entity.Product;
import com.cxyzxc.www.utils.DBUtils;
import com.cxyzxc.www.utils.DateUtils;
public class ProductDaoImpl implements ProductDao {
// 创建QueryRunner对象,并传递一个数据源对象
private QueryRunner queryRunner = new QueryRunner(DBUtils.getDataSource());
@Override
public int insert(Product product) {
String sql = "INSERT INTO `product`(`pname`,`price`,`birthday`)VALUES(?,?,?);";
Object[] args = { product.getPname(), product.getPrice(),
DateUtils.utilDateToSqlDate(product.getBirthday()) };
try {
return queryRunner.update(sql, args);
} catch (SQLException e) {
e.printStackTrace();
}
return 0;
}
@Override
public int delete(int pid) {
String sql = "DELETE FROM `product` WHERE `pid` = ?;";
try {
return queryRunner.update(sql, pid);
} catch (SQLException e) {
e.printStackTrace();
}
return 0;
}
@Override
public int update(Product product) {
String sql = "UPDATE `product` SET `pname` = ?,`price`=?,`birthday`=? WHERE `pid`=?;";
Object[] args = { product.getPname(), product.getPrice(),
DateUtils.utilDateToSqlDate(product.getBirthday()),
product.getPid() };
try {
return queryRunner.update(sql, args);
} catch (SQLException e) {
e.printStackTrace();
}
return 0;
}
@Override
public Product selectOne(int pid) {
// 查询一个数据,使用BeanHandler将记录转换为对象
BeanHandler<Product> product = new BeanHandler<Product>(Product.class);
String sql = "SELECT * FROM `product` WHERE `pid`=?;";
try {
return queryRunner.query(sql, product, pid);
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
@Override
public List<Product> selectAll() {
// 查询一个数据,使用BeanHandler将记录转换为对象
BeanListHandler<Product> productList = new BeanListHandler<Product>(Product.class);
String sql = "SELECT * FROM `product`;";
try {
return queryRunner.query(sql, productList);
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
}

创建ProductService接口

创建ProductService接口来实现业务层增删改查方法名的统一。

package com.cxyzxc.service;
import java.util.List;
import com.cxyzxc.www.entity.Product;
public interface ProductService {
//增加
int addProduct(Product product);
//删除
int deleteProduct(int pid);
//修改
int updateProduct(Product product);
//查询单个
Product selectOneProduct(int pid);
//查询所有
List<Product> selectAllProduct();
}

创建ProductServiceImpl实现类

创建ProductServiceImpl实现类来实现ProductService接口。

package com.cxyzxc.service.impl;
import java.util.List;
import com.cxyzxc.service.ProductService;
import com.cxyzxc.www.dao.ProductDao;
import com.cxyzxc.www.dao.impl.ProductDaoImpl;
import com.cxyzxc.www.entity.Product;
public class ProductServiceImpl implements ProductService {
ProductDao productDao = new ProductDaoImpl();
@Override
public int addProduct(Product product) {
// 查询添加的商品是否存在
Product pd = productDao.selectOne(product.getPid());
if (pd == null) {
return productDao.insert(product);
} else {
System.out.println("商品已经存在,不能重复添加");
}
return 0;
}
@Override
public int deleteProduct(int pid) {
// 查询添加的商品是否存在
Product pd = productDao.selectOne(pid);
if (pd != null) {
return productDao.delete(pid);
} else {
System.out.println("商品不存在,不能删除");
}
return 0;
}
@Override
public int updateProduct(Product product) {
// 查询添加的商品是否存在
Product pd = productDao.selectOne(product.getPid());
if (pd!= null) {
return productDao.update(product);
} else {
System.out.println("商品不存在,不能修改");
}
return 0;
}
@Override
public Product selectOneProduct(int pid) {
Product product =productDao.selectOne(pid);
if(product!=null){
return product;
}else{
System.out.println("没有你要查找产品,查找失败");
}
return null;
}
@Override
public List<Product> selectAllProduct() {
List<Product> productList = productDao.selectAll();
if(productList.size()!=0){
return productList;
}else{
System.out.println("数据库为空,没有产品");
}
return null;
}
}

创建测试类

测试插入数据

package com.cxyzxc.www.view;
import com.cxyzxc.service.ProductService;
import com.cxyzxc.service.impl.ProductServiceImpl;
import com.cxyzxc.www.entity.Product;
import com.cxyzxc.www.utils.DateUtils;
public class Test01InsertProduct {
public static void main(String[] args) {
//创建ProductService引用,指向ProductServiceImpl实现类
ProductService productService = new ProductServiceImpl();
//增加产品
Product product = new Product(1003,"流心威化饼干", 13.5, DateUtils.strDateToUtilDate("2022-11-10"));
int result = productService.addProduct(product);
String str = result==1?"商品添加成功":"商品添加失败";
System.out.println(str);
}
}

测试删除数据

package com.cxyzxc.www.view;
import com.cxyzxc.service.ProductService;
import com.cxyzxc.service.impl.ProductServiceImpl;
public class Test02DeleteProduct {
public static void main(String[] args) {
// 创建ProductService引用,指向ProductServiceImpl实现类
ProductService productService = new ProductServiceImpl();
int result = productService.deleteProduct(1003);
String str = result == 1 ? "删除成功" : "删除失败";
System.out.println(str);
}
}

测试修改数据

package com.cxyzxc.www.view;
import com.cxyzxc.service.ProductService;
import com.cxyzxc.service.impl.ProductServiceImpl;
import com.cxyzxc.www.entity.Product;
import com.cxyzxc.www.utils.DateUtils;
public class Test03UpdateProduct {
public static void main(String[] args) {
// 创建ProductService引用,指向ProductServiceImpl实现类
ProductService productService = new ProductServiceImpl();
// 增加产品
Product product = new Product(1002, "流心威化饼干", 13.5,
DateUtils.strDateToUtilDate("2022-11-10"));
int result = productService.updateProduct(product);
String str = result == 1 ? "修改成功" : "修改失败";
System.out.println(str);
}
}

测试查询一条数据

package com.cxyzxc.www.view;
import com.cxyzxc.service.ProductService;
import com.cxyzxc.service.impl.ProductServiceImpl;
import com.cxyzxc.www.entity.Product;
public class Test04SelectOneProduct {
public static void main(String[] args) {
// 创建ProductService引用,指向ProductServiceImpl实现类
ProductService productService = new ProductServiceImpl();
Product product = productService.selectOneProduct(1003);
if (product != null) {
System.out.println(product);
} else {
System.out.println("你要查询的商品不存在");
}
}
}

测试查询所有数据

package com.cxyzxc.www.view;
import java.util.List;
import com.cxyzxc.service.ProductService;
import com.cxyzxc.service.impl.ProductServiceImpl;
import com.cxyzxc.www.entity.Product;
public class Test05SelectAllProduct {
public static void main(String[] args) {
// 创建ProductService引用,指向ProductServiceImpl实现类
ProductService productService = new ProductServiceImpl();
List<Product> productList = productService.selectAllProduct();
for (int i = 0; i < productList.size(); i++) {
System.out.println(productList.get(i));
}
}
}

来源:https://hh419.blog.csdn.net/article/details/128046816

标签:Java,Druid,连接池,Apache,DBUtils
0
投稿

猜你喜欢

  • 浅谈Android性能优化之内存优化

    2023-08-19 04:36:43
  • Activiti开发环境的搭建过程详解

    2021-08-16 07:13:05
  • VC对自定义资源加密解密(AES)的详解

    2023-01-10 00:27:15
  • C#实现剪刀石头布游戏

    2021-11-10 05:19:32
  • C#中DataGridView的样式

    2022-04-23 11:08:42
  • 基于SpringBoot Mock单元测试详解

    2021-09-25 02:49:41
  • Java Socket实现单线程通信的方法示例

    2022-04-22 15:43:02
  • 基于WebClient实现Http协议的Post与Get对网站进行模拟登陆和浏览实例

    2022-06-24 08:07:48
  • 详谈Java中的事件监听机制

    2022-08-05 00:29:30
  • Android RecyclerView使用ListAdapter高效刷新数据的操作方法

    2023-06-24 22:22:09
  • 超简单的几行代码搞定Android底部导航栏功能

    2022-08-03 09:26:56
  • 使用Android造了个滚轮控件轮子示例

    2023-04-29 07:09:17
  • C#中类成员的定义的修饰关键词知识点总结

    2023-08-13 15:10:10
  • Maven build 命令介绍的使用详解

    2023-08-20 18:09:35
  • 详解如何全注解方式构建SpringMVC项目

    2023-08-13 07:14:41
  • Maven profile实现不同环境的配置管理实践

    2021-11-11 09:52:15
  • SpringBoot @Scope与@RefreshScope注解使用详解

    2022-11-13 17:52:44
  • java 实现简单圣诞树的示例代码(圣诞节快乐)

    2023-03-13 13:13:37
  • WPF+ASP.NET SignalR实现后台通知功能的示例代码

    2021-10-11 04:49:45
  • 文件路径正确,报java.io.FileNotFoundException异常的原因及解决办法

    2022-01-28 04:52:57
  • asp之家 软件编程 m.aspxhome.com