我也来写DBUtils
关于重复造轮子
作为一个程序员,我们不止一次听到师长前辈们说:不要重复造轮子,已经有现成的了,直接用就是了。
对于这个观点,我觉得得仔细分析分析。
如果我们正在做一个真实的项目,经理天天追在我们屁股后面问进度。我想只要是个正常的程序员,肯定不会想去再造一个"轮子"。
但是,程序员不是年年月月,每一天都在赶项目。那么在我们闲暇的时候,看看业内已经有的轮子,仔细分析一下轮子的构造,自己就权当是学习,再造一次轮子又何妨?
既然这个轮子已经是业内普遍接受的,那么代码的质量毋庸置疑,最起码一定比我们ctrl+c,ctrl+v的增删改查有质量的多。
程序员经常抱怨自己老是加班,工资又低。可问题是:你就会增删改查,高级的东西又不知道,如果你是老板,你会给这样的员工多少工资呢?
我们比较差,我们承认。但是在闲暇之余,我们可以看看那些比较牛逼的人是怎么写代码的,然后再把我们自己写的代码与大牛们对比对比,这个时候孰优孰劣,代码的健壮性,可移植行不都体现出来了么?就是大牛起的变量名都值得我们学习。
见贤思齐焉,孔老夫子诚不欺我。
第一 你得见----------------------------你都不知道有这个项目,那就什么都不用说了
井鼃不可以语于海者,拘于虚也;夏虫不可以语于冰者,笃于时也;曲士不可以语于道者,束于教也。
第二 那个工程必须真的贤-----------跟臭棋篓子下棋,越下越臭
第三 你得思-------------------------------把自己的糟糕的代码拉出来,跟"贤明"的代码比一比。别嫌丢人,哪个程序员不是从hello world起步的?
关于DBUtils
这个组件是干什么的?
请自己百度。
dbutils的使用教程
http://www.cnblogs.com/xdp-gacl/p/4007225.html
(上面的教程相当全,初级使用我认为只看前三节即可)
我的代码
咱们从junit测试代码开始看。
@Test
public void testBeanHandlerByDBSource() {
QueryRunner qr = new QueryRunner(new MyDBSource());
Student student = qr.query("select * from student where xh='02'", new BeanHandler<>(
Student.class));
System.out.println(student.getXm() + " " + student.getXh()+" "+student.getBirth());
}
其中MyDBSource只是一个获取数据源的工具类而已。
public class MyDBSource implements DataSource {
private static String driverClassName = "com.mysql.jdbc.Driver";
private static String url = "jdbc:mysql://localhost:3306/webexample";
private static String userName = "root";
private static String passWord = "root";
@Override
public Connection getConnection() throws SQLException {
try {
Class.forName(driverClassName);
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return DriverManager.getConnection(url, userName, passWord);
}
}
我们看看QueryRunner的构造函数
public class QueryRunner {
private Connection connection;
public QueryRunner(){
}
public QueryRunner(DataSource ds){
try {
connection=ds.getConnection();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//...
}
现在看重头戏,就是QueryRunner的一系列query方法
public class QueryRunner {
public <T> T query(String sql, ResultSetHandler<T> rsh) {
if (connection!=null) {
return query(connection, sql, rsh);
}else {
System.out.println("connection is null!");
return null;
}
}
public <T> T query(Connection conn, String sql, ResultSetHandler<T> rsh) {
return query(conn, sql, new Object[]{}, rsh);
}
public <T> T query(Connection conn, String sql, Object[] params, ResultSetHandler<T> rsh){
T object=null;
try{
PreparedStatement ps=conn.prepareStatement(sql);
for (int i = 0; i < params.length; i++) {
setParams(ps, i,params);
}
ResultSet rs=ps.executeQuery();
object=rsh.handle(rs);
}catch (Exception e) {
e.printStackTrace();
}
return object;
}
}
//为了方便,我这里只模拟了String与date型的数据
public void setParams(PreparedStatement ps,int i,Object[] params){
try {
if (params[i] instanceof String) {
ps.setString(i+1, (String) params[i]);
}
if (params[i] instanceof java.util.Date) {
ps.setDate(i+1, (Date) params[i]);
}
} catch (Exception e) {
e.printStackTrace();
}
}
OK,我们看到了更核心的方法
object=rsh.handle(rs);
在junit中,我们给QueryRunner里面注入的就是BeanHandler类。
public class BeanHandler<T> implements ResultSetHandler<T>{
private Class<T> type;
public BeanHandler(Class<T> type)
this.type=type;
}
@Override
public T handle(ResultSet rs) throws SQLException {
T o=null;
try {
while (rs.next()) {
o=BeanUtils.creatBean(rs, type);
}
} catch (Exception e) {
e.printStackTrace();
}
return o;
}
}
//BeanUtils.java
public class BeanUtils {
public static <T> T creatBean(ResultSet rs, Class<T> type) {
T o = null;
try {
o = type.newInstance();
Field[] field = type.getDeclaredFields();
for (int i = 0; i < field.length; i++) {
String filedName = field[i].getName();
Class<?> filedType = field[i].getType();
String methodName = "set"
+ filedName.substring(0, 1).toUpperCase()
+ filedName.substring(1);
Method m = type.getDeclaredMethod(methodName, filedType);
Object value=setValue(filedType,rs,filedName);
m.invoke(o, value);
}
} catch (Exception e) {
e.printStackTrace();
}
return o;
}
public static Object setValue( Class<?> filedType, ResultSet rs, String filedName){
Object value=null;
try {
if (filedType.getName().equals("java.lang.String")) {
value = rs.getString(filedName);
}
if (filedType.getName().equals("java.util.Date")) {
value = rs.getDate(filedName);
}
} catch (Exception e) {
e.printStackTrace();
}
return value;
}
}
上面的代码,怎么说呢,我也不嫌贻笑大方。
慢慢来嘛#
下面的是对dbutis源码浅层次的分析:
http://blog.csdn.net/dlf123321/article/details/45172429
下面的是堆dbutil的架构分析
http://blog.csdn.net/dlf123321/article/details/45203171
接下来,我就来比较一下,看看人家有多么牛逼,我自己有多么low
我也来写DBUtils的更多相关文章
- 基于jsp+servlet图书管理系统之后台万能模板
前奏: 刚开始接触博客园写博客,就是写写平时学的基础知识,慢慢发现大神写的博客思路很清晰,知识很丰富,非常又价值,反思自己写的,顿时感觉非常low,有相当长一段时间没有分享自己的知识.于是静下心来钻研 ...
- 关于List泛型的强制转换
当我们从数据库中查询出一些数据,有时返回的结果可能是List<Object>类型,而我们清楚的知道它的准确类型是List<User>,可能我们想直接的去进行类型的转换,你可能会 ...
- 基于jsp+servlet图书管理系统之后台用户信息删除操作
上一篇的博客写的是修改操作,且附有源码和数据库,这篇博客写的是删除操作,附有从头至尾写的代码(详细的注释)和数据库! 此次删除操作的源码和数据库:http://download.csdn.net/de ...
- 基于jsp+servlet图书管理系统之后台用户信息插入操作
前奏: 刚开始接触博客园写博客,就是写写平时学的基础知识,慢慢发现大神写的博客思路很清晰,知识很丰富,非常又价值,反思自己写的,顿时感觉非常low,有相当长一段时间没有分享自己的知识.于是静下心来钻研 ...
- javaweb笔记全套
Lesson 1 一.eclipse工具的使用 1. java代码的位置 1) 选择工作空间 workspace 选择一个文件夹存放程序(代码) 不要用中文和空格 2) 新建一个java 工程(Pr ...
- javaweb笔记分享
Lesson 1 一.eclipse工具的使用 1. java代码的位置 1) 选择工作空间 workspace 选择一个文件夹存放程序(代码) 不要用中文和空格 2) 新建一个java 工程(Pr ...
- 写一个ORM框架的第一步(Apache Commons DbUtils)
新一次的内部提升开始了,如果您想写一个框架从Apache Commons DbUtils开始学习是一种不错的选择,我们先学习应用这个小“框架”再把源代码理解,然后写一个属于自己的ORM框架不是梦. 一 ...
- java mysql多次事务 模拟依据汇率转账,并存储转账信息 分层完成 dao层 service 层 client层 连接池使用C3p0 写入库使用DBUtils
Jar包使用,及层的划分 c3p0-config.xml <?xml version="1.0" encoding="UTF-8"?> <c3 ...
- BenUtils组件和DbUtils组件
BenUtils组件和DbUtils组件 [TOC] 1.BenUtils组件 1.1.简介 程序中对javabean的操作很频繁,所有Apache提供了一套开源api,方便javabean的操作!即 ...
随机推荐
- Linux基础指令
Linux基础指令 只写了最简单的一些文件操作,基本没有带参数 查看当前目录 pwd 跳转到某路径 cd 查看当前目录下的文件 ls ls -l // -l 查看详细信息 打开当前所在文件夹 open ...
- GDALWarp设置GDALWarpOptions::dfWarpMemoryLimit过大时处理失败
使用GDALWarp写了一个裁切图像的算法,在小内存的电脑没事,大内存的电脑就处理失败(32位也没问题),查看GDAL的日志发现下面的错误信息: Fri Apr 08 17:39:02 2016: G ...
- Scala:集合类型Collection和迭代器
http://blog.csdn.net/pipisorry/article/details/52902549 Scala Collection Scala 集合分为可变的和不可变的集合. 可变集合可 ...
- Rxjava +Retrofit 你需要掌握的几个技巧,Retrofit缓存,RxJava封装,统一对有无网络处理,异常处理, 返回结果问题
本文出处 :Tamic 文/ http://blog.csdn.net/sk719887916/article/details/52132106 Rxjava +Rterofit 需要掌握的几个技巧 ...
- 最优化方法:范数和规则化regularization
http://blog.csdn.net/pipisorry/article/details/52108040 范数规则化 机器学习中出现的非常频繁的问题有:过拟合与规则化.先简单的来理解下常用的L0 ...
- 微信小程序基础之新建的项目文件图解
昨天发布的文章,感觉对于学习不够直观,所以今天重点在图标上进行了详细的对应介绍,稍后会尝试开发小程序控件的使用.转载请标注出处,谢谢!
- Hadoop介绍
是适合大数据的分布式存储与计算平台,用java编写的开源系统,能够安排在大规模的计算机平台上,从而长进计算效率:由 HDFS.MapReduce.HBase.Hive 和 ZooKeeper等成员组成 ...
- java创建对象详解和多态问题
一. java 构造方法不等于创建对象而是初始化对象,new 关键字分配内存和创建对象的. 二.Test test = new Test(); 有人用上面的表达式来说明构造方法返回对象引用,这是明显 ...
- 【伯乐在线】最值得阅读学习的 10 个 C 语言开源项目代码
原文出处: 平凡之路的博客 欢迎分享原创到伯乐头条 伯乐在线注:『阅读优秀代码是提高开发人员修为的一种捷径』http://t.cn/S4RGEz .之前@伯乐头条 曾发过一条微博:『C 语言进阶有 ...
- UE4联机多人游戏基本设置
UE4自带网络联机功能,但是似乎只有蓝图接口,而真正写功能的时候不能用C++,让人感觉相当诡异 还是作一个简单记录 1.建一个第三人称模板,为什么会用他呢,因为它自带模板的很多组件,直接支持联机功能, ...