关于重复造轮子

作为一个程序员,我们不止一次听到师长前辈们说:不要重复造轮子,已经有现成的了,直接用就是了。

对于这个观点,我觉得得仔细分析分析。

如果我们正在做一个真实的项目,经理天天追在我们屁股后面问进度。我想只要是个正常的程序员,肯定不会想去再造一个"轮子"。

但是,程序员不是年年月月,每一天都在赶项目。那么在我们闲暇的时候,看看业内已经有的轮子,仔细分析一下轮子的构造,自己就权当是学习,再造一次轮子又何妨?

既然这个轮子已经是业内普遍接受的,那么代码的质量毋庸置疑,最起码一定比我们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的更多相关文章

  1. 基于jsp+servlet图书管理系统之后台万能模板

    前奏: 刚开始接触博客园写博客,就是写写平时学的基础知识,慢慢发现大神写的博客思路很清晰,知识很丰富,非常又价值,反思自己写的,顿时感觉非常low,有相当长一段时间没有分享自己的知识.于是静下心来钻研 ...

  2. 关于List泛型的强制转换

    当我们从数据库中查询出一些数据,有时返回的结果可能是List<Object>类型,而我们清楚的知道它的准确类型是List<User>,可能我们想直接的去进行类型的转换,你可能会 ...

  3. 基于jsp+servlet图书管理系统之后台用户信息删除操作

    上一篇的博客写的是修改操作,且附有源码和数据库,这篇博客写的是删除操作,附有从头至尾写的代码(详细的注释)和数据库! 此次删除操作的源码和数据库:http://download.csdn.net/de ...

  4. 基于jsp+servlet图书管理系统之后台用户信息插入操作

    前奏: 刚开始接触博客园写博客,就是写写平时学的基础知识,慢慢发现大神写的博客思路很清晰,知识很丰富,非常又价值,反思自己写的,顿时感觉非常low,有相当长一段时间没有分享自己的知识.于是静下心来钻研 ...

  5. javaweb笔记全套

    Lesson 1 一.eclipse工具的使用 1. java代码的位置 1) 选择工作空间 workspace  选择一个文件夹存放程序(代码) 不要用中文和空格 2) 新建一个java 工程(Pr ...

  6. javaweb笔记分享

    Lesson 1 一.eclipse工具的使用 1. java代码的位置 1) 选择工作空间 workspace  选择一个文件夹存放程序(代码) 不要用中文和空格 2) 新建一个java 工程(Pr ...

  7. 写一个ORM框架的第一步(Apache Commons DbUtils)

    新一次的内部提升开始了,如果您想写一个框架从Apache Commons DbUtils开始学习是一种不错的选择,我们先学习应用这个小“框架”再把源代码理解,然后写一个属于自己的ORM框架不是梦. 一 ...

  8. java mysql多次事务 模拟依据汇率转账,并存储转账信息 分层完成 dao层 service 层 client层 连接池使用C3p0 写入库使用DBUtils

    Jar包使用,及层的划分 c3p0-config.xml <?xml version="1.0" encoding="UTF-8"?> <c3 ...

  9. BenUtils组件和DbUtils组件

    BenUtils组件和DbUtils组件 [TOC] 1.BenUtils组件 1.1.简介 程序中对javabean的操作很频繁,所有Apache提供了一套开源api,方便javabean的操作!即 ...

随机推荐

  1. Android TV开发总结(四)通过RecycleView构建一个TV app列表页(仿腾讯视频TV版)

    转载请把头部出处链接和尾部二维码一起转载,本文出自逆流的鱼yuiop:http://blog.csdn.net/hejjunlin/article/details/52854131 前言:昨晚看锤子手 ...

  2. 给定一个实数数组,按序排列(从小到大),从数组从找出若干个数,使得这若干个数的和与M最为接近,描述一个算法,并给出算法的复杂度。

    有N个正实数(注意是实数,大小升序排列) x1 , x2 ... xN,另有一个实数M. 需要选出若干个x,使这几个x的和与 M 最接近. 请描述实现算法,并指出算法复杂度. #define M 8 ...

  3. SpringMVC基础配置(通过注解配置,非xml配置)

    SpringMVC是什么,有多火,我这里就不再啰嗦了,SpringMVC比Struts2好用太多,我在学校的时候私下里两种都接触过,对比之后果断选择了SpringMVC,后来在做Android应用开发 ...

  4. “出错了”和报告Bug的艺术

    "出错了." 没有那句话能像"出错了"一样让程序员/开发者如此沮丧,心里翻江倒海,怒火一点即燃,还要死掉一大片脑细胞. 这句生硬的开场白通常标志着让开发者恐惧的 ...

  5. 17 ContentProvider

    1 Loader 转载器 Android3.0以后出来的 它可以使Activity和Fragment 异步加载数据 变得简单(Loader里封装了AsyncTask) 2 Loader特点: 对每一个 ...

  6. Android开发中StackOverflowError

    Android开发中StackOverflowError错误实例分析 一.概述 我在一个复杂的layout嵌套较多的android界面,碰到了java.lang.StackOverflowError这 ...

  7. C++对C语言register的增强

    register关键字 请求编译器让变量a直接放在寄存器里面,速度快 在c语言中 register修饰的变量 不能取地址,但是在c++里面做了内容 1 register关键字的变化 register关 ...

  8. hive编程指南——读书笔记(无知拾遗)

    set hive.metastore.warehouse.dir=/user/myname/hive/warehouse; 用户设定自己的数据仓库目录.不影响其他用户.也在$HOME/.hiverc中 ...

  9. Android开发学习之路--Activity之生命周期

    其实这篇文章应该要在介绍Activity的时候写的,不过那个时候还不怎么熟悉Activity,还是在这里详细介绍下好了.还是参考下官方文档的图吧: 从上面的流程,我们可以看出首先就是打开APP,开始执 ...

  10. 从二进制数据流中构造GDAL可以读取的图像数据

    在很多时候,我们的图像数据往往都不是文件方式存储在磁盘上,而是可能从网络或者数据库中获取的是二进制的图像数据流.最简单的方式和最容易想到的方式就是将这个文件流保存到磁盘上形成一个文件,然后再使用GDA ...