前言:dbutils的好用之处不必多说,但是在使用的过程中发现要对每个Bean写一个BeanDao,来实现Bean的访问,虽然一个Bean只需要写一次,但是对于复杂的Bean来说,其属性众多,写起来也是非常费时间的。所有我想写一个万能的BaseDao来一劳永逸。 1、BaseDao之前的BeanDao的添加实现:
2、BaseDao的添加实现是万能的,所有使用如下:public boolean addTestBean(TestBean testBean){
QueryRunner qr = new TxQueryRunner();
String sql = "insert into group values(?,?,?,?,?,?,?)";
Object params[] = {
testBean.getTitle(),testBean.getCount(),testBean.getClick(), testBean.getLen(),testBean.getId(),testBean.getName(),testBean.getChild()}
;
try {
qr.update(sql, params);
return true;
}
catch (SQLException e) {
e.printStackTrace();
return false;
}
}
可见BaseDao还是非常好用的,只需实例化的时传入3个参数,然后就随意的增删改查了。第1个参数是表名,如果传入null,则会使用Bean的名称作表名(TestBean ==> test_bean),第2个参数为Bean的class,第3个参数为主键,可以为多键联合主键。 3、这里除了BaseDao的源码外还有一个工具类:MBUtils包含了BaseDao中用到的反射工具,都是刚开始写的,所以功能不是很多,但是还有个很好用的功能是可以根据Bean生成创建表的sql语句,方便Bean属性过多时使用非常方便,但是非常简易,以后再优化。 使用非常简单,一行代码:BaseDao bd = new BaseDao
("test_bean", TestBean.class, new String[]{
"id"}
);
TestBean bean = new TestBean();
bean.setId("123");
bean.setName("test");
bd.addObject(bean);
其中第1个参数是表名,如果传入null,则会使用Bean的名称作表名(TestBean ==> test_bean)。 效果如下:MBUtils.generateCreateTable(null, TestBean.class,new String[]{
"id"}
)
4、依赖的jar包CREATE TABLE '
test_bean'
( '
name'
varchar(255), '
click'
varchar(255), '
id'
varchar(255), '
count'
int(32), '
title'
varchar(255), '
child'
varchar(255), '
len'
varchar(255), PRIMARY KEY ('
id'
)) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
下载地址: 5、关于c3p0的使用,需要将c3p0-config.xml文件放到src目录下,文件名不可更改。然后配置一下内容:c3p0-0.9.2-pre1.jarcommons-dbutils-1.4.jarcommons-logging-1.1.1.jaritcast-tools-1.4.2.jarmchange-commons-0.2.jarmysql-connector-java-5.1.28-bin.jar
6、为了BaseDao的独立使用,BaseDao包含了MBUtils的部分函数,两个类的代码如下: BaseDao.java
jdbc:mysql://localhost:3306/dbname com.mysql.jdbc.Driver root 123456 3 10 2 10
package com.match.sqlmodel;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import cn.itcast.jdbc.TxQueryRunner;
/** * 基于dbutils的万能的BaseDao * @author 亓根火柴 * @date 2017-1-26 * @param*/public class BaseDao {
private QueryRunner qr = new TxQueryRunner();
/** * 表名 */ private String table;
/** * 对象类型 */ private Class cls;
/** * 主键(联合主键) */ private String[] primaryKeys;
/** * 隐藏默认构造器,强制初始化各参数 */ private BaseDao(){
}
;
public BaseDao(String tableName,Class cls,String[] primaryKeys){
if((tableName==null)||tableName.equals("")){
table = getSqlName(cls.getSimpleName());
}
else{
table = tableName;
}
this.cls = cls;
this.primaryKeys = primaryKeys;
}
/** * 添加对象到数据库中 * @param obj 对象 * @return 成功返回true */ public boolean addObject(Object obj){
Mapresult = generateInsertParams(table,obj,cls);
String sql = (String) result.get("sql");
Object params[] = (Object[]) result.get("params");
printLog(sql, params);
try {
qr.update(sql, params);
return true;
}
catch (SQLException e) {
e.printStackTrace();
return false;
}
}
/** * 根据主键从数据库中删除该对象 * @param obj 对象 * @return 删除成功返回true */ public boolean deleteObject(Object obj){
Mapresult = generateDeleteParams(table,obj,cls);
String sql = (String) result.get("sql");
Object params[] = (Object[]) result.get("params");
printLog(sql, params);
try {
qr.update(sql,params);
return true;
}
catch (SQLException e) {
e.printStackTrace();
return false;
}
}
/** * 根据主键修改数据库中的对象 * @param obj 修改对象 * @return 修改成功返回true */ public boolean editObject(Object obj){
Mapresult = generateEditParams(table,obj,cls);
String sql = (String) result.get("sql");
Object params[] = (Object[]) result.get("params");
printLog(sql, params);
try {
qr.update(sql, params);
return true;
}
catch (SQLException e) {
e.printStackTrace();
return false;
}
}
/** * 根据主键查询对象 * @param obj 对象 * @return 查询出的对象 */ public T queryObject(Object obj) {
Mapresult = generateQueryParams(table,obj,cls);
String sql = (String) result.get("sql");
Object params[] = (Object[]) result.get("params");
printLog(sql, params);
try {
return qr.query(sql, new BeanHandler(cls), params);
}
catch (SQLException e) {
e.printStackTrace();
return null;
}
}
/** * 查询所有对象 * @return 对象列表 */ public ListfindAll(){
String sql = "select * from "+table;
try {
return qr.query(sql, new BeanListHandler(cls));
}
catch (SQLException e) {
e.printStackTrace();
}
return null;
}
/** * 生成插入语句和参数 * @param table 表名 * @param obj 对象 * @param cls 类型 * @return 语句和参数 */ private MapgenerateInsertParams(String table, Object obj, Class cls) {
Mapdata = new HashMap ();
//生成sql语句 String[] fields = getAllFields(cls);
StringBuffer sql = new StringBuffer("insert into "+table+"(");
StringBuffer val = new StringBuffer("values(");
for(String temp : fields){
sql.append(temp+",");
val.append("?,");
}
sql.deleteCharAt(sql.length()-1);
val.deleteCharAt(val.length()-1);
sql.append(") ");
val.append(")");
data.put("sql", sql.append(val).toString());
//生成参数 Object values[] = new Object[fields.length];
for(int i = 0;
i < fields.length;
i++){
values[i] = getValues(fields[i],obj,cls);
}
data.put("params", values);
return data ;
}
/** * 生成删除语句和参数 * @param table 表名 * @param obj 对象 * @param cls 类型 * @return 语句和参数 */ private MapgenerateDeleteParams(String table, Object obj,Class cls) {
Mapdata = new HashMap ();
//生成sql语句和参数 StringBuffer sql = new StringBuffer("delete from "+table+" where ");
Object values[] = new Object[primaryKeys.length];
for(int i = 0;
i < primaryKeys.length;
i++){
sql.append(primaryKeys[i] + "=? and ");
values[i] = getValues(primaryKeys[i],obj,cls);
}
sql = sql.delete(sql.length()-4, sql.length());
data.put("sql", sql.toString());
data.put("params", values);
return data;
}
/** * 生成修改语句和参数 * @param table 表名 * @param obj 对象 * @param cls 类型 * @return 语句和参数 */ private MapgenerateEditParams(String table, Object obj,Class cls) {
Mapdata = new HashMap ();
//生成sql语句 String[] fields = getAllFields(cls);
Listpks = Arrays.asList(primaryKeys);
StringBuffer sql = new StringBuffer("update "+table+" set ");
for(String temp : fields){
if(!pks.contains(temp)){
sql.append(temp+"=?,");
}
}
sql.deleteCharAt(sql.length()-1);
sql.append(" where ");
for(String temp : primaryKeys){
sql.append(temp+"=? and ");
}
sql = sql.delete(sql.length()-4, sql.length());
data.put("sql", sql.toString());
//生成参数 Object values[] = new Object[fields.length];
int j = 0;
for(int i = 0;
i < fields.length;
i++){
if(!pks.contains(fields[i])){
values[j] = getValues(fields[i],obj,cls);
j++;
}
}
for(String temp : primaryKeys){
values[j] = getValues(temp,obj,cls);
j++;
}
data.put("params", values);
return data ;
}
/** * 生成查询语句和参数 * @param table 表名 * @param obj 对象 * @param cls 类型 * @return 语句和参数 */ private MapgenerateQueryParams(String table, Object obj,Class cls) {
Mapdata = new HashMap ();
//生成sql语句和参数 StringBuffer sql = new StringBuffer("select * from "+table+" where ");
Object values[] = new Object[primaryKeys.length];
for(int i = 0;
i < primaryKeys.length;
i++){
sql.append(primaryKeys[i] + "=? and ");
values[i] = getValues(primaryKeys[i],obj,cls);
}
sql = sql.delete(sql.length()-4, sql.length());
data.put("sql", sql.toString());
data.put("params", values);
return data;
}
/** * 根据set方法和Class.getFields(),获取该类的所有域,包括公共域和私有域 * @param cls 类型 * @return */ private String[] getAllFields(Class cls) {
Field[] pubFields = cls.getFields();
ListsetFields = new ArrayList ();
Method[] methods = cls.getMethods();
for(Method method : methods){
if(method.getName().startsWith("set")){
String field = method.getName().substring(3).toLowerCase();
setFields.add(field);
}
}
for(Field temp:pubFields){
if(!setFields.contains(temp.getName())){
setFields.add(temp.getName());
}
}
return setFields.toArray(new String[setFields.size()]);
}
/** * 根据域名获取该对象域的值 * @param field 域名 * @param obj 对象 * @param cls 类型 * @return */ private Object getValues(String field, Object obj, Class cls) {
Method[] methods = cls.getMethods();
String firstChar = field.charAt(0)+"";
firstChar = firstChar.toUpperCase();
String methodName = "get"+firstChar+field.substring(1);
for(Method method : methods){
if(method.getName().equals(methodName)){
try {
return method.invoke(obj, null);
}
catch (IllegalAccessException e) {
e.printStackTrace();
}
catch (IllegalArgumentException e) {
e.printStackTrace();
}
catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}
return null;
}
private String getSqlName(String name){
if((name == null)||(name.equals("")))return null;
name = (name.charAt(0)+"").toLowerCase()+name.substring(1);
int index = 0;
while((index = contains(name))!=-1){
char c = name.charAt(index);
name = name.replaceFirst(c+"", ("_"+c).toLowerCase());
}
return name;
}
private int contains(String str){
for(int i=0;
ii++){
c="str.charAt(i);
" char="" nparams=");
// for(int i=0;
i<cke:params.length-1;
i++){
// System.out.print(params[i]+" pre="" private="" return="" sql="+sql+" string="" void="">MBUtils.javapackage com.match.sqlmodel;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/** * MySql & Bean Utils * @author 亓根火柴 * @date 2017-1-26 */public class MBUtils {
/** * 简易地生成数据表创建语句 * @param table * @param cls * @param primaryKeys * @return */ public static String generateCreateTable(String table,Class cls,String[] primaryKeys){
StringBuffer sql = new StringBuffer();
Listpks = Arrays.asList(primaryKeys);
if((table == null)||table.equals("")){
table = getSqlName(cls.getSimpleName());
}
sql.append("CREATE TABLE '
"+table+"'
(n");
String[] fields = getAllFields(cls);
for(String field:fields){
sql.append("t'
"+getSqlName(field)+"'
");
String type = getFieldType(field,cls);
if(pks.contains(field)){
sql.append(type+" NOT NULL,n");
}
else{
sql.append(type+",n");
}
}
sql.append("t PRIMARY KEY (");
for(String pk:pks){
sql.append("'
"+pk+"'
,");
}
sql.deleteCharAt(sql.length()-1);
sql.append(")n) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
");
return sql.toString();
}
/** * 根据set方法和Class.getFields(),获取该类的所有域,包括公共域和私有域 * @param cls 类型 * @return */ public static String[] getAllFields(Class cls) {
Field[] pubFields = cls.getFields();
ListsetFields = new ArrayList ();
Method[] methods = cls.getMethods();
for(Method method : methods){
if(method.getName().startsWith("set")){
String field = method.getName().substring(3).toLowerCase();
setFields.add(field);
}
}
for(Field temp:pubFields){
if(!setFields.contains(temp.getName())){
setFields.add(temp.getName());
}
}
return setFields.toArray(new String[setFields.size()]);
}
/** * 根据域名获取该对象域的值 * @param field 域名 * @param obj 对象 * @param cls 类型 * @return */ public Object getValues(String field, Object obj, Class cls) {
Method[] methods = cls.getMethods();
String firstChar = field.charAt(0)+"";
firstChar = firstChar.toUpperCase();
String methodName = "get"+firstChar+field.substring(1);
for(Method method : methods){
if(method.getName().equals(methodName)){
try {
return method.invoke(obj, null);
}
catch (IllegalAccessException e) {
e.printStackTrace();
}
catch (IllegalArgumentException e) {
e.printStackTrace();
}
catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}
return null;
}
/** * 获取域的类型和大小 * @param field * @param cls * @return */ private static String getFieldType(String field,Class cls) {
Method[] methods = cls.getMethods();
String methodName = "get"+getFirstUpperString(field);
for(Method method:methods){
if(method.getName().equals(methodName)){
Class clss = method.getReturnType();
String typeName = clss.getSimpleName();
if(typeName.equals("String")){
typeName = "varchar(255)";
}
else if(typeName.equals("Date")){
typeName = "datatime()";
}
else if(typeName.equals("int")){
typeName = "int(32)";
}
return typeName;
}
}
return null;
}
/** * 获取数据库用的名称(TestBean==>test_bean) * @param name * @return */ public static String getSqlName(String name){
if((name == null)||(name.equals("")))return null;
name = (name.charAt(0)+"").toLowerCase()+name.substring(1);
int index = 0;
while((index = contains(name))!=-1){
char c = name.charAt(index);
name = name.replaceFirst(c+"", ("_"+c).toLowerCase());
}
return name;
}
/** * 返回字符串中第一个大写字母的索引 * @param str * @return 没有大写字母返回-1 */ public static int contains(String str){
for(int i=0;
ii++){ i++){
c="str.charAt(i);
" char="" firstchar="str.charAt(0)+"";
" param="" pre="" public="" return="" static="" str="" string="">
>