Why#

一时兴起,自以为是的对Jdbc访问框架做了一个简单的摸底,近期主要采用Mybatis,之前也有不少采用Dbutils,因此希望能让这两个框架折腾的更好用。

DbUtils:非常简单的Jdbc访问框架,极为轻量级,对数据查询结果集转换成目标的对象或列表或其它集合结构做了很好的支持(xxHandler)。

Mybatis:ibatis(暂未使用过)的升级版,目前所知它至少有两个坑,其一是假分页(参考DefaultResultSetHandler的skipRows方法),其二是不能支持对象列表存储时对自增id字段的赋值(至少包括3.2.6和3.3.0版本)。

参考项目#

mybatis分页组件(也支持排序,通过外置增加的排序和分页选项,在mapper文件中配置sql不包含排序):mybatis-pagination

轻量级改造概要#

Dbutils

  • 简单的封装,增加代码复用,并尽量支持泛型化

Mybatis

  • 实际的处理分页拦截器,暂只支持MySQL和Oracle(目前网络上关于此已经有了大量的实践,但是个人认为某些实践破坏了Mybatis本身的一些优良特性,细节将在后面的文章给出说明)
  • 处理对象列表存储时自动对自增主键赋值,目前几乎完全照搬了Git上的一个项目mybatis-batch-insert的内容,只是稍做修改。

场景#

试想一下,当使用原生Jdbc执行SQL时,我们希望它有哪些feature呢?

  • 支持查询泛型对象列表
  • 支持插入对象列表时自动填充主键
  • 支持插入对象列表
  • 支持批量插入和更新
  • 支持SQL语句生成和解析
  • 支持多种数据库
  • 支持结果集处理成各类存储结构(list,map)

实现细节#

方言##

除去标准SQL支持,不同数据库的SQL语法略有差异(虽然知道的不多),比如分页,MySQL采用limit关键字支持,Oracle则采用rownum支持。

方言枚举(目前仅支持MySQL和Oracle,其它的暂时用不到)

package org.wit.ff.jdbc.dialect;

/**
* Created by F.Fang on 2015/11/19.
*/
public enum DialectType {
MYSQL, ORACLE
}

方言定义

请参考mybatis-pagination项目里关于方言的定义,此处就不引用他的代码了,请为他的Job增加人气。

标准SQL生成#

标准SQL支持##

请参考Mybatis的AbstractSQLBuilder和SQLBuilder

SQLBuilder(有修改,增加分页支持)##

/*
* Copyright 2009-2012 The MyBatis Team
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.wit.ff.jdbc.sql; import org.wit.ff.jdbc.dialect.Dialect; public abstract class SQLBuilder extends AbstractSQLBuilder<SQLBuilder> { protected boolean paging;
protected int offset;
protected int pageSize; @Override
public SQLBuilder getSelf() {
return this;
} protected abstract Dialect getDialect(); public SQLBuilder PAGE(int offset, int pageSize) {
paging = true;
// 这里作为底层接口不做任何检查,上层业务调用时检查.
this.offset = offset;
this.pageSize = pageSize;
return this;
} @Override
public String toString() {
if(paging){
return getDialect().getLimitString(super.toString(), offset, pageSize);
}else{
return super.toString();
}
} }

MySQLBuilder##

package org.wit.ff.jdbc.sql.db;

import org.wit.ff.jdbc.dialect.Dialect;
import org.wit.ff.jdbc.dialect.db.MySQLDialect;
import org.wit.ff.jdbc.sql.SQLBuilder; /**
* Created by F.Fang on 2015/2/16.
* Version :2015/2/16
*/
public class MySQLBuilder extends SQLBuilder { private Dialect dialect = new MySQLDialect(); @Override
public Dialect getDialect() {
return dialect;
}
}

OracleBuilder##

package org.wit.ff.jdbc.sql.db;

import org.wit.ff.jdbc.dialect.Dialect;
import org.wit.ff.jdbc.dialect.db.OracleDialect;
import org.wit.ff.jdbc.sql.SQLBuilder; /**
* Created by F.Fang on 2015/11/20.
*/
public class OracleBuilder extends SQLBuilder { private Dialect dialect = new OracleDialect(); @Override
public Dialect getDialect() {
return dialect;
}
}

自增主键处理#

自定义接收主键数据的接口

package org.wit.ff.jdbc.id;

/**
* Created by F.Fang on 2015/2/16.
* Version :2015/2/16
*/
public interface IdGenerator {
/**
* 参数为数组的原因是考虑联合主键,虽然暂时不会有对联合主键的支持.
* @param value
*/
void parseGenKey(Object[] value);
}

数据接口定义#

package org.wit.ff.jdbc.access;

import org.wit.ff.jdbc.converter.ParamsConverter;

import java.util.List;

/**
* Created by F.Fang on 2015/3/31.
* 简单公共数据访问层.
* Version :2015/3/31
*/
public interface IDataAccessor { /**
* 查询
* @param sql
* @param resultType 对象类型
* @param <T>
* @return
*/
<T> List<T> query(String sql, Class<T> resultType); /**
* 查询,如果返回类型是具体类型,那么就采用
* @param sql 查询语句
* @param params 查询参数
* @param resultType 返回类型
* @param <T>
* @return
*/
<T> List<T> query(String sql, Object[] params, Class<T> resultType); /**
* insert 对象列表.
* @param sql insert语句.
* @param params 对象参数列表.
* @param paramsType 参数类型.
* @param converter 参数转换器.
* @param <T>
*/
<T> void insert(String sql, List<T> params, Class<T> paramsType, ParamsConverter<T> converter); /**
* insert batch.
* @param sql
* @param params
*/
void insert(String sql, Object[][] params); /**
* single insert.
* @param sql
* @param params
*/
void insert(String sql, Object[] params); /**
* batch update.
* @param sql
* @param params
* @return
*/
int[] update(String sql, Object[][] params); /**
* single update.
* @param sql
* @param params
* @return
*/
int update(String sql, Object[] params); /**
* 删除,删除可采用条件替代批量.
* @param sql
* @param params
* @return
*/
int delete(String sql, Object[] params); }

参数处理#

package org.wit.ff.jdbc.converter;

/**
* Created by F.Fang on 2015/3/31.
* 用于参数转换的接口.
* Version :2015/3/31
*/
public interface ParamsConverter<T> {
Object[] convert(T obj);
}

结果集处理#

暂无(目前开源社区有大量的相关API)

QA#

轻量级封装DbUtils&Mybatis之一概要的更多相关文章

  1. 轻量级封装DbUtils&Mybatis之三MyBatis分页

    MyBatis假分页 参考DefaultResultSetHandler的skipRows方法. 温馨提示:部分代码请参考轻量级封装DbUtils&Mybatis之一概要 解决方案 1)之前公 ...

  2. 轻量级封装DbUtils&Mybatis之二Dbutils

    DbUtils入门 Apache出品的极为轻量级的Jdbc访问框架,核心类只有两个:QueryRunner和ResultSetHandler. 各类ResultSetHandler: ArrayHan ...

  3. 轻量级封装DbUtils&Mybatis之四MyBatis主键

    MyBatis主键 不支持对象列表存储时对自增id字段的赋值(至少包括3.2.6和3.3.0版本),如果id不是采用底层DB自增主键赋值,不必考虑此问题 温馨提示:分布式DB环境下,DB主键一般会采用 ...

  4. Apache DbUtils - JDBC轻量级封装的工具包

    前段时间使用了Apache Common DbUtils这个工具,在此留个印,以备不时查看.大家都知道现在市面上的数据库访问层的框架很多,当然很多都是包含了OR-Mapping工作步骤的例如大家常用的 ...

  5. 简单封装DBUtils 和 pymysql 并实现简单的逆向工程生成class 类的py文件

    这里使用的 Python 版本是:Python 3.6.0b2. 涉及的三方库:DBUtils.pymysql 1.ConfigurationParser 通过调用Python内置的 xml.dom. ...

  6. iOS的KVO使用和轻量级封装

    KVO的使用方法 注冊 [object addObserver:observer forKeyPath:@"text" options:NSKeyValueObservingOpt ...

  7. 封装的mybatis连接类

    package com.kevin.utils;import org.apache.ibatis.io.Resources;import org.apache.ibatis.session.SqlSe ...

  8. 对JDBC的轻量级封装,Hibernate框架

    IDEA是真的好用... 用脑子下jar包..http://mvnrepository.com/

  9. 使用DbUtils对JDBC封装实现面向实体查询

    直接上代码 package org.smart4j.chapter2.helper; import org.apache.commons.dbcp2.BasicDataSource; import o ...

随机推荐

  1. linux FTP 操作

    1.登陆: ftp 172.xxx.xxx.xxx 按提示输入用户名和密码 2.上传: 单个文件:put /路径/文件名 批量: 输入 prom 此命令是关闭交互(否则总是询问你是否要上传) 输入下载 ...

  2. Markdown_02_作图

    [TOC] 前言 一.序列图(Sequence) 序列图由 js-sequence提供支持,可以将代码块转成序列图 示例如下: ```sequence Title: Here is a title A ...

  3. 【Html 学习笔记】第八节——表单实践

    列举一些实践的例子: 1.点击按钮后跳转: <html> <body> <form action="1.html"> First <inp ...

  4. 第1课:接口测试和jmeter总结

    接口测试 1. 接口的分类:webService和http api接口 1) webService接口:是按照soap协议通过http传输,请求报文和返回报文都是xml格式,一般要借助工具来测试接口: ...

  5. HEVC简介】CTU、CU、PU、TU结构

    https://www.cnblogs.com/DwyaneTalk/p/5711342.html

  6. 《Drools7.0.0.Final规则引擎教程》第4章 4.5RHS语法

    RHS语法 使用说明 RHS是满足LHS条件之后进行后续处理部分的统称,该部分包含要执行的操作的列表信息.RHS主要用于处理结果,因此不建议在此部分再进行业务判断.如果必须要业务判断需要考虑规则设计的 ...

  7. Photon——Feature Overview 功能概述

    Photon——Feature Overview 功能概述   Feature Overview 功能概述        Photon is a real-time socket server and ...

  8. python常用模块之json、pickle模块

    python常用模块之json.pickle模块 什么是序列化? 序列化就是把内存里的数据类型转换成字符,以便其能存储到硬盘或者通过网络进行传输,因为硬盘或网络传输时只接受bytes. 为什么要序列化 ...

  9. 显卡、显卡驱动、显存、GPU、CUDA、cuDNN

    显卡 Video card,Graphics card,又叫显示接口卡,是一个硬件概念(相似的还有网卡),执行计算机到显示设备的数模信号转换任务,安装在计算机的主板上,将计算机的数字信号转换成模拟 ...

  10. Linux libusb 安装及简单使用

    Linux libusb 安装及简单使用 一.参考文档: . libusb1 fails do_configure task with “udev support requested but libu ...