DbUtils源码分析系列(二)

今天分析一下QueryRunner这个DbUtils核心类,它
利用可插拨的策略执行SQL查询来处理ResultSets。QueryRunner类图如下所示:

QueryRunner类图
从类图中我们可以看出它继承AbstractQueryRunner。
QueryRunner构造器有多个重载方法:

public AbstractQueryRunner() {
        ds = null;
    }

    /**
     * Constructor to control the use of <code>ParameterMetaData</code>.
     *
     * @param pmdKnownBroken
     *            Some drivers don't support
     *            {@link ParameterMetaData#getParameterType(int) }; if
     *            <code>pmdKnownBroken</code> is set to true, we won't even try
     *            it; if false, we'll try it, and if it breaks, we'll remember
     *            not to use it again.
     */
    public AbstractQueryRunner(boolean pmdKnownBroken) {
        this.pmdKnownBroken = pmdKnownBroken;
        ds = null;
    }

    /**
     * Constructor to provide a <code>DataSource</code>. Methods that do not
     * take a <code>Connection</code> parameter will retrieve connections from
     * this <code>DataSource</code>.
     *
     * @param ds
     *            The <code>DataSource</code> to retrieve connections from.
     */
    public AbstractQueryRunner(DataSource ds) {
        this.ds = ds;
    }

    /**
     * Constructor to provide a <code>DataSource</code> and control the use of
     * <code>ParameterMetaData</code>. Methods that do not take a
     * <code>Connection</code> parameter will retrieve connections from this
     * <code>DataSource</code>.
     *
     * @param ds
     *            The <code>DataSource</code> to retrieve connections from.
     * @param pmdKnownBroken
     *            Some drivers don't support
     *            {@link ParameterMetaData#getParameterType(int) }; if
     *            <code>pmdKnownBroken</code> is set to true, we won't even try
     *            it; if false, we'll try it, and if it breaks, we'll remember
     *            not to use it again.
     */
    public AbstractQueryRunner(DataSource ds, boolean pmdKnownBroken) {
        this.pmdKnownBroken = pmdKnownBroken;
        this.ds = ds;
    }

构造函数中有两个成员变量:boolean类型的pmdKnownBroken和DataSource类型的ds。
有些情况下,你需要在PreparedStatement中设置空值,这个时候如果你还使用设置具体类型的方法,如setInt(1,null),程序会毫不留情的报出空指针异常,所以你需要做的是使用setNull(index, type)方法来代替你原来的方法。例如

stmt.setNull(1,Types.INTEGER);

第二个参数为java.sql.Types中具体的类型值,你可以通过Types查找到你需要的具体类型。通过这个方法,就可以完成在PreparedStatement设置null值,前提当然是你的数据库字段允许null值。
pmdKnownBroken这个变量,源码的解释是这样的:有些数据库驱动程序不支持ParameterMetaData.getParameterType方法,如果pmdKnownBroken设置为false,在调用fillStatement进行SQL参数填充的时候,如果某个参数值为NULL,我们则会尝试着使用ParameterMetaData.getParameterType方法来获取参数类型,如果有异常抛出,则将pmdKnownBroken值置为 true,以后不再使用。如果pmdKnownBroken设置为true,不进行getParameterType尝试处理。
pmdKnownBroken被定义为volatile类型原因是为了保证这个类的线程安全性。它可以用来确保变量的更新操作通知到其他线程。需要注意的是volatile变量只能保证可见性,在当且仅当满足以下条件的时候才应该使用它:

  • 在访问变量时不需要加锁
  • 对变量的写入操作不会依赖变量的当前值,或者确保只有当个线程更新变量值
  • 该变量不会和其他状态变量一起纳入不变性条件中
    显然pmdKnownBroken满足以上使用条件。它只是某个状态标记。
    private volatile boolean pmdKnownBroken = false;
/**
     * Fill the <code>PreparedStatement</code> replacement parameters wi
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值