博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
使用dbutils进行数据库操作
阅读量:5056 次
发布时间:2019-06-12

本文共 7280 字,大约阅读时间需要 24 分钟。

  Common Dbutils是操作数据库的组件,是一个开源的JDBC工具类库,对传统操作数据库的类进行二次封装,可以把结果集转化成List。

  DBUtils是java编程中的数据库操作实用工具,小巧简单实用,没有Hibernate等一些ORM框架的庞大,繁琐的配置。

  1.对于数据表的读操作,他可以把结果转换成List,Array,Set等java集合,便于程序员操作;
  2.对于数据表的写操作,也变得很简单(只需写sql语句)
  3.可以使用数据源,使用JNDI,数据库连接池等技术来优化性能--重用已经构建好的数据库连接对象,而不像php,asp那样,费时费力的不断重复的构建和析构这样的对象。
  但是,如果使用dbutils包的话,需要注意以下几点:
  1.实体类属性的名称要与库中字段的名字一致,否则无法查到结果。
  2.ResultSetHandler rsh = 接口的实现类
    如果返回对象的话使用new BeanHandler();
    如果返回的是集合的话使用 new BeanListHandler();
  3.等等可以参考官方文档或其他资料

调用主要类

  • org.apache.commons.dbutils.QueryRunner
  • org.apache.commons.dbutils.ResultSetHandler
  • org.apache.commons.dbutils.DbUtils

Dbutils用法

  dbutils封装了jdbc的增删改查的操作,只需要new一个QueryRunner,然后调用其query方法,将sql语句,参数或参数数组,传入结果集处理器递。

结果集处理器ResultSetHandler 接口的实现类 

  1. ArrayHandler:把结果集中的第一行数据转成对象数组。
  2. ArrayListHandler:把结果集中的每一行数据都转成一个数组,再存放到List中。
  3. BeanHandler:将结果集中的第一行数据封装到一个对应的JavaBean实例中。
  4. BeanListHandler:将结果集中的每一行数据都封装到一个对应的JavaBean实例中,存放到List里。
  5. ColumnListHandler:将结果集中某一列的数据存放到List中。
  6. KeyedHandler(name):将结果集中的每一行数据都封装到一个Map里,再把这些map再存到一个map里,其key为指定的key。
  7. MapHandler:将结果集中的第一行数据封装到一个Map里,key是列名,value就是对应的值。
  8. MapListHandler:将结果集中的每一行数据都封装到一个Map里,然后再存放到List

  在mvc模式中,dao层只负责对数据库的操作,不应该有任何业务逻辑的代码,但是有一种情况,比如银行转账,几次数据库操作在一次事务中,在service中如何将转账服务放在一次事务中呢,一种解决办法是在dao层中保存一个Connection,由service传递进来对那个Connection操作,就可以解决这个问题。

  在mvc模式下,如何进行事务管理呢,上面的方法是,所有的dao层共享同一事务,即同一连接,实现此需求的另外一种方法是使用ThreadLocale技术,这个对象保存的是一个线程为键的map,如果在dao层中将得到的Connection存放在这个map中,则在service中得到的连接就是同一连接,可以写一个工具类实现获取连接,提交,回滚,关闭等操作。
  以上两种方法只能在dao层中实现共享事务,但是如果是servlet转发等情况,便不是同一连接,这时候就必须将事务管理提前到servlet之前,就写一个拦截器,每一次请求都获取连接,然后放行给servlet等,返回时再关闭连接等,缺点是占用连接时间过长,所以使用spring是好的方法,但是比较臃肿。

下面例子是dbutils+反射对Dao简单使用

实体类 UserRoleVo.java

public class UserRoleVo {    int id;    String name;    public int getId() {        return id;    }    public void setId(int id) {        this.id = id;    }    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    @Override    public String toString() {        return "UserRoleVo [id=" + id + ", name=" + name + "]";    }}

 

基于泛型的BaseDao.java

import java.lang.reflect.ParameterizedType;import java.sql.Connection;import java.sql.DriverManager;import java.sql.SQLException;import java.util.List;import org.apache.commons.dbutils.DbUtils;import org.apache.commons.dbutils.QueryRunner;import org.apache.commons.dbutils.handlers.BeanListHandler;public class BaseDao
{ private static final String CLASSNAME="com.microsoft.sqlserver.jdbc.SQLServerDriver"; private static final String URL="jdbc:sqlserver://127.0.0.1:1433;databasename=MybookShop"; private static final String UID="sa"; private static final String PWD=""; private Class cls; public Connection getConn() throws SQLException { Connection conn=DriverManager.getConnection(URL,UID,PWD); return conn; } public DBM() throws SQLException{ DbUtils.loadDriver(CLASSNAME); cls= (Class)((ParameterizedType) this.getClass().getGenericSuperclass()).getActualTypeArguments()[0]; } public List
query(String sql,Object...paras) throws SQLException{ QueryRunner qr=new QueryRunner(); BeanListHandler handler=new BeanListHandler(cls); Connection conn=getConn(); List
list= (List
) qr.query(getConn(), sql,paras , handler); DbUtils.close(conn); return list; } public void update(String sql,Object...paras) throws SQLException{ QueryRunner qr=new QueryRunner(); Connection conn=getConn(); qr.update(conn, sql,paras); DbUtils.close(conn); } }

 

数据访问层类UserRoleDAO.java:

import java.sql.SQLException;import java.util.List;import org.apache.commons.dbutils.QueryRunner;import org.apache.commons.dbutils.handlers.BeanListHandler;import com.accp.db.DBM;import com.accp.vo.UserRoleVo;public class UserRoleDao extends BaseDao
{ public UserRoleDao() throws SQLException { super(); } public List
findAll() throws SQLException{ return query("select * from userRoles"); } public List
findAllByName(String name) throws SQLException{ return query( "select * from userRoles where name like ?","%"+name+"%"); } public void add(UserRoleVo role) throws SQLException{ update("insert into userRoles values (?)",role.getName()); }}

  这样的BaseDao就可以很方便地被子类继承使用query(),update()等方法,没有set(),get()繁琐过程就可以得到结果集。其实还可以继续封装像(不过POJO是Bean 类的基类,这样做法好像代码不清晰)但你还是可以用其他办法想上面的例子一样封装操作数据库方法,只不过需要稍稍修改,如

/**     * 分页列出所有对象     * @param page     * @param size     * @return     */    public List
List(int page, int size) { String sql = "SELECT * FROM " + TableName() + " ORDER BY id DESC"; return QueryHelper.query_slice(getClass(), sql, page, size); } public List
Filter(String filter, int page, int size) { String sql = "SELECT * FROM " + TableName() + " WHERE " + filter + " ORDER BY id DESC"; return QueryHelper.query_slice(getClass(), sql, page, size); }/** * 根据主键读取对象详细资料,根据预设方法自动判别是否需要缓存 * @param id * @return */ @SuppressWarnings("unchecked") public
T Get(long id) { if(id <= 0) return null; String sql = "SELECT * FROM " + TableName() + " WHERE id=?"; boolean cached = IsObjectCachedByID(); return (T)QueryHelper.read_cache(getClass(), cached?CacheRegion():null, id, sql, id); } public List
BatchGet(List
ids) { if(ids==null || ids.size()==0) return null; StringBuilder sql = new StringBuilder("SELECT * FROM " + TableName() + " WHERE id IN ("); for(int i=1;i<=ids.size();i++) { sql.append('?'); if(i < ids.size()) sql.append(','); } sql.append(')'); List
beans = QueryHelper.query(getClass(), sql.toString(), ids.toArray(new Object[ids.size()])); if(IsObjectCachedByID()){ for(Object bean : beans){ CacheManager.set(CacheRegion(), ((POJO)bean).getId(), (Serializable)bean); } } return beans; }/** * 插入对象 * @param obj * @return 返回插入对象的主键 */ private static long _InsertObject(POJO obj) { Map
pojo_bean = obj.ListInsertableFields(); String[] fields = pojo_bean.keySet().toArray(new String[pojo_bean.size()]); StringBuilder sql = new StringBuilder("INSERT INTO ") ; sql.append(obj.TableName()); sql.append('('); for(int i=0;i
0) sql.append(','); sql.append(fields[i]); } sql.append(") VALUES("); for(int i=0;i
0) sql.append(','); sql.append('?'); } sql.append(')'); PreparedStatement ps = null; ResultSet rs = null; try{ ps = QueryHelper.getConnection().prepareStatement(sql.toString(), PreparedStatement.RETURN_GENERATED_KEYS); for(int i=0;i

这样的话数据层的子类会更加简单,大大减少代码量。

最后我是想说不用Hibernate等一些ORM框架,是感觉用了之后不灵活。

 

转载于:https://www.cnblogs.com/janko208/archive/2012/08/27/2658964.html

你可能感兴趣的文章
蓝桥杯-分小组-java
查看>>
Java基础--面向对象编程1(类与对象)
查看>>
Android Toast
查看>>
iOS开发UI篇—Quartz2D使用(绘制基本图形)
查看>>
docker固定IP地址重启不变
查看>>
桌面图标修复||桌面图标不正常
查看>>
JavaScript基础(四)关于对象及JSON
查看>>
关于js sort排序方法
查看>>
JAVA面试常见问题之Redis篇
查看>>
javascript:二叉搜索树 实现
查看>>
网络爬虫Heritrix源码分析(一) 包介绍
查看>>
__int128的实现
查看>>
Problem - 1118B - Codeforces(Tanya and Candies)
查看>>
jdk1.8 api 下载
查看>>
svn 图标不显示
查看>>
getElement的几中属性介绍
查看>>
iOS 使用Quartz 2D画虚线 【转】
查看>>
平面最接近点对
查看>>
HTML列表,表格与媒体元素
查看>>
PHP、Java、Python、C、C++ 这几种编程语言都各有什么特点或优点?
查看>>