DButils+dbcp数据源+spring实现增删改查小例子

2024-05-15 04:08

本文主要是介绍DButils+dbcp数据源+spring实现增删改查小例子,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

[b][color=green][size=large]本篇主要介绍DButils工具类的使用跟Spring的JDBCTemplate框架非常类似,比我们纯手写JDBC的sql语句,会方便许多,如果加上了连接池的配置,那么效果就会更加完美,
首先我们来看下DButils的简介:
Common Dbutils是操作数据库的组件,对传统操作数据库的类进行二次封装,可以把结果集转化成List。它是对JDBC的一个轻量级的封装,简化了很多重复的一些操作。

Dbutils的一些注意事项:

1、DBUtils是JDBC的简单封装,可以和JDBC混合使用。

2、DBUtils对结果集自动封装为JavaBean是有着苛刻要求的:必须满足JavaBean的规范,其次Bean的getter与setter方法的名字与结果集的列名一一对应,而不要求JavaBean的私有成员与表结果集列名一一对应。
比如:
person表中有个字段叫:address,那么对应的JavaBean的Person类中必须有getAddress和setAddress两个方法,而Person类中可以将address属性命名为add,这是没问题的。

3、DBUtils可以将结果集封装为各种类型,主要有:Bean/List<Bean>,Map/List<Map>/Map<Map>,数组/List<数组>,列/List<列>,这些类型。
对于Map<Map>的类型使用KeyedHandler作为结果集处理器,内层的Map是“列名-值"对,外层的Map是“主键-内层Map的引用”,但此处的主键不一定就是数据库的主键,可以随意指定

[/size][/color][/b]
[b][color=olive][size=large]4、DBUtils执行插入操作的时候,无法返回自增主键,这是一个很严重的问题,当然不能怪DBUtils,可以通过变通的方法来实现,比如在MySQL中,执行完了一个插入SQL后,接着执行SELECT LAST_INSERT_ID()语句,就可以获取到自增主键。

5、DBUtils的性能和JDBC性能是一样,测试过程中没发现性能损失,拥有了很高性能的同时,而不失JDBC的灵活性。[/size][/color][/b]

[b][color=olive][size=large]

下面散仙介绍一下,本次例子中使用的技术:

连接池:dbcp,也是common家族里面的包
bean注入和管理: 使用的是spring
轻量级的工具库:dbutils


数据源是在,spring的配置文件配置的:

[/size][/color][/b]

	<bean id="local" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
<property name="url" value="jdbc:mysql://localhost:3306/person?characterEncoding=utf-8"></property>
<property name="username" value="root"></property>
<property name="password" value="qin"></property>
<property name="maxActive" value="10"/>
<property name="initialSize" value="5"/>
<property name="defaultReadOnly" value="false"/>
</bean>


[b][color=olive][size=large]当然,上面的这个数据源,我们可以配置多个,也可配置不同的库,这样设计比较方便灵活,利于我们动态切换我们的库。

由于是java项目,并没有采用Web容器的方式启动,所以需要我们定义一个bean的加载器,来获取连接池,代码如下:
[/size][/color][/b]
package com.dhgate.dbutils.opera;

import javax.sql.DataSource;

import org.apache.commons.dbcp.BasicDataSource;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
import org.springframework.core.io.ClassPathResource;

/**
*
* 加载Spring的xml的bean配置
* */
public class XmlBeanLoad {


/**
*
* 根据连接池的名
* 得到一个连接池对象
*
* @param datasourceName 数据源名字
* @return 数据连接池对象
* */
public static BasicDataSource getDataSource(String datasourceName){
BeanFactory bean=new DefaultListableBeanFactory();
XmlBeanDefinitionReader reader=new XmlBeanDefinitionReader((BeanDefinitionRegistry)bean);
reader.loadBeanDefinitions(new ClassPathResource("datasource.xml"));
BasicDataSource data=(BasicDataSource) bean.getBean(datasourceName);
return data;
}




/***
* 测试连接信息
*
* **/
public static void main(String[] args) throws Exception{

BeanFactory bean=new DefaultListableBeanFactory();
XmlBeanDefinitionReader reader=new XmlBeanDefinitionReader((BeanDefinitionRegistry)bean);
reader.loadBeanDefinitions(new ClassPathResource("datasource.xml"));
// BasicDataSource data=(BasicDataSource) bean.getBean("common2");
BasicDataSource data=(BasicDataSource) bean.getBean("local");
System.out.println(data.getConnection());


}

}


[b][color=olive][size=large]增删改查代码示例:[/size][/color][/b]
package com.dhgate.dbutils.opera;


import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Arrays;
import java.util.List;

import javax.sql.DataSource;

import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.ResultSetHandler;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.dhgate.m2b.entity.Student;
/**
*
* dbutils+datasource
* 实现轻量级的增删改查
* @author qindongliang
*
* * */
public class DataQuery<T> {

private static Logger logger = LoggerFactory.getLogger(DataQuery.class);


private Class clazz;
public DataQuery(Class clazz) {
this.clazz=clazz;
}

public DataQuery() {
// TODO Auto-generated constructor stub
}


public T query(String sql,Object[] params,String name)throws Exception{
log(sql, params, name);
DataSource datasource=XmlBeanLoad.getDataSource(name);
System.out.println(datasource.getConnection().toString());
QueryRunner runner=new QueryRunner(datasource);
System.out.println(runner);
return (T) runner.query(sql, new BeanHandler(clazz),params);
}

/**
* 查询集合
* @param sql 添加的sql语句
* @param params 数据的参数
* @param name 连接池的名字
* */
public List<T> queryList(String sql,Object[] params,String name)throws Exception{
log(sql, params, name);
DataSource datasource=XmlBeanLoad.getDataSource(name);
QueryRunner runner=new QueryRunner(datasource);

return (List<T>) runner.query(sql, new BeanListHandler(clazz),params);
}

/**
* 添加一条数据
* @param sql 添加的sql语句
* @param params 数据的参数
* @param name 连接池的名字
* */
public void add(String sql,Object[] params,String name)throws Exception{
log(sql, params, name);
DataSource datasource=XmlBeanLoad.getDataSource(name);
QueryRunner runner=new QueryRunner(datasource);
int i=runner.update(datasource.getConnection(),sql, params);
if(i>0){
System.out.println("添加成功!");
}
}

/**
* 更新一条数据
* @param sql 添加的sql语句
* @param params 数据的参数
* @param name 连接池的名字
* */
public void update(String sql,Object[] params,String name)throws Exception{
log(sql, params, name);
DataSource datasource=XmlBeanLoad.getDataSource(name);
QueryRunner runner=new QueryRunner(datasource);
int i=runner.update(datasource.getConnection(),sql, params);
if(i>0){
System.out.println("更新成功!");
}
}

/**
* 删除一条数据
* @param sql 添加的sql语句
* @param params 数据的参数
* @param name 连接池的名字
* */
public void delete(String sql,Object[] params,String name)throws Exception{
log(sql, params, name);
DataSource datasource=XmlBeanLoad.getDataSource(name);
QueryRunner runner=new QueryRunner(datasource);
int i=runner.update(datasource.getConnection(),sql, params);
if(i>0){
System.out.println("删除成功!");
}
}


/**
* 统计某个表的count
* @param sql sql语句
* @param params 条件参数
* @param name 数据源名字
* @return 返回检索的数量
* **/
public int count(String sql,Object[] params,String name)throws Exception{

log(sql, params, name);
DataSource datasource=XmlBeanLoad.getDataSource(name);
QueryRunner runner=new QueryRunner(datasource);

int count=runner.query(sql, new ResultSetHandler<Integer>() {
@Override
public Integer handle(ResultSet rs) throws SQLException {
if(rs.next()){
return rs.getInt(1);
}
return 0;
}
},params);

return count;
}






private void log(String sql,Object[] params,String name){
logger.info("SQL语句:"+sql+" 检索参数: "+Arrays.toString(params)+" 连接池名字: "+name);
}



public static void main(String[] args)throws Exception {

// String sql="select * from person where name like ? ";
String datasourceName="local";
DataQuery<Student> sq=new DataQuery<Student>(Student.class);
//添加测试
//sq.add("insert into person (name,sex) values(?,?)", new Object[]{"散仙","女"},datasourceName);
//更新测试
//sq.update("update person set name=? , sex=? where id = ? ", new Object[]{"三劫散仙","男",5}, datasourceName);
//删除测试
sq.delete("delete from person where id = ? ", new Object[]{1}, datasourceName);
//

//单条查询测试
// Student st= sq.query(sql, new Object[]{"王晶"}, datasourceName);
// System.out.println(st);
// System.out.println("================================");
//批量查询测试
// List<Student> queryList = sq.queryList(sql, new Object[]{"%天%"}, datasourceName);
// System.out.println("查询数量: "+queryList.size());
// for(Student stt:queryList){
// System.out.println(stt);
// }
//System.out.println(st);
// testLimit();

}

public static void testLimit()throws Exception{
String sql="select * from person order by id desc limit ? , ? ";
String datasourceName="local";
DataQuery<Student> sq=new DataQuery<Student>(Student.class);
List<Student> queryList = sq.queryList(sql, new Object[]{2,3}, datasourceName);
System.out.println("查询数量: "+queryList.size());
for(Student stt:queryList){
System.out.println(stt);
}
}




}


[b][color=olive][size=large]以上代码,就是简化了封装操作数据库增删改查的过程,当然我们也可以扩展它,使它成为一个轻量级的ORM框架,这样更方便操作,另外注意一点,如果注意数据库的编码问题,如果编码不一致,可能会导致,中文查询有问题,而且程序不会报异常,只是查询的结果为空或null,所以这一点需要格外注意,最好在连接数据库的配置里,加上指定的数据库编码,如散仙上面的xml的写法。

最后看一下DButils一些Handler的封装:
[/size][/color][/b]

ArrayHandler:把结果集中的第一行数据转成对象数组。
ArrayListHandler:把结果集中的每一行数据都转成一个对象数组,再存放到List中。
BeanHandler:将结果集中的第一行数据封装到一个对应的JavaBean实例中。
BeanListHandler:将结果集中的每一行数据都封装到一个对应的JavaBean实例中,存放到List里。
ColumnListHandler:将结果集中某一列的数据存放到List中。
KeyedHandler:将结果集中的每一行数据都封装到一个Map里,然后再根据指定的key把每个Map再存放到一个Map里。
MapHandler:将结果集中的第一行数据封装到一个Map里,key是列名,value就是对应的值。
MapListHandler:将结果集中的每一行数据都封装到一个Map里,然后再存放到List。
ScalarHandler:将结果集中某一条记录的其中某一列的数据存成Object。

[b][color=olive][size=large]使用的主要jar包有:[/size][/color][/b]

commons-dbutils-1.6.jar dbutis的主要包
mysql的驱动包
spring的核心包

这篇关于DButils+dbcp数据源+spring实现增删改查小例子的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/990760

相关文章

C++使用栈实现括号匹配的代码详解

《C++使用栈实现括号匹配的代码详解》在编程中,括号匹配是一个常见问题,尤其是在处理数学表达式、编译器解析等任务时,栈是一种非常适合处理此类问题的数据结构,能够精确地管理括号的匹配问题,本文将通过C+... 目录引言问题描述代码讲解代码解析栈的状态表示测试总结引言在编程中,括号匹配是一个常见问题,尤其是在

Java实现检查多个时间段是否有重合

《Java实现检查多个时间段是否有重合》这篇文章主要为大家详细介绍了如何使用Java实现检查多个时间段是否有重合,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录流程概述步骤详解China编程步骤1:定义时间段类步骤2:添加时间段步骤3:检查时间段是否有重合步骤4:输出结果示例代码结语作

Java中String字符串使用避坑指南

《Java中String字符串使用避坑指南》Java中的String字符串是我们日常编程中用得最多的类之一,看似简单的String使用,却隐藏着不少“坑”,如果不注意,可能会导致性能问题、意外的错误容... 目录8个避坑点如下:1. 字符串的不可变性:每次修改都创建新对象2. 使用 == 比较字符串,陷阱满

Java判断多个时间段是否重合的方法小结

《Java判断多个时间段是否重合的方法小结》这篇文章主要为大家详细介绍了Java中判断多个时间段是否重合的方法,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录判断多个时间段是否有间隔判断时间段集合是否与某时间段重合判断多个时间段是否有间隔实体类内容public class D

使用C++实现链表元素的反转

《使用C++实现链表元素的反转》反转链表是链表操作中一个经典的问题,也是面试中常见的考题,本文将从思路到实现一步步地讲解如何实现链表的反转,帮助初学者理解这一操作,我们将使用C++代码演示具体实现,同... 目录问题定义思路分析代码实现带头节点的链表代码讲解其他实现方式时间和空间复杂度分析总结问题定义给定

IDEA编译报错“java: 常量字符串过长”的原因及解决方法

《IDEA编译报错“java:常量字符串过长”的原因及解决方法》今天在开发过程中,由于尝试将一个文件的Base64字符串设置为常量,结果导致IDEA编译的时候出现了如下报错java:常量字符串过长,... 目录一、问题描述二、问题原因2.1 理论角度2.2 源码角度三、解决方案解决方案①:StringBui

Java覆盖第三方jar包中的某一个类的实现方法

《Java覆盖第三方jar包中的某一个类的实现方法》在我们日常的开发中,经常需要使用第三方的jar包,有时候我们会发现第三方的jar包中的某一个类有问题,或者我们需要定制化修改其中的逻辑,那么应该如何... 目录一、需求描述二、示例描述三、操作步骤四、验证结果五、实现原理一、需求描述需求描述如下:需要在

Java中ArrayList和LinkedList有什么区别举例详解

《Java中ArrayList和LinkedList有什么区别举例详解》:本文主要介绍Java中ArrayList和LinkedList区别的相关资料,包括数据结构特性、核心操作性能、内存与GC影... 目录一、底层数据结构二、核心操作性能对比三、内存与 GC 影响四、扩容机制五、线程安全与并发方案六、工程

JavaScript中的reduce方法执行过程、使用场景及进阶用法

《JavaScript中的reduce方法执行过程、使用场景及进阶用法》:本文主要介绍JavaScript中的reduce方法执行过程、使用场景及进阶用法的相关资料,reduce是JavaScri... 目录1. 什么是reduce2. reduce语法2.1 语法2.2 参数说明3. reduce执行过程

如何使用Java实现请求deepseek

《如何使用Java实现请求deepseek》这篇文章主要为大家详细介绍了如何使用Java实现请求deepseek功能,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1.deepseek的api创建2.Java实现请求deepseek2.1 pom文件2.2 json转化文件2.2