模拟ibtais参数注入的过程

使用Ibatis时,只需要把sql语句写好,指明需要注入的参数对应对象中的属性就可以了。这样极大的提高了开发效率。

我在工作过程中,遇到了一些场景,需要自己去直接连接JDBC写数据库,我又想模拟Ibatis自动补全参数的功能,所以就写了下面的这些代码。欢迎指证批评。

 

创建数据库连接的代码

import java.sql.Connection;
import java.sql.DriverManager;

/**
 * 2012-8-9 tracy.liuy
 */
public class DbConnection {


    public Connection conn = null;

    public DbConnection(String driver, String url, String user, String password){
        try {
            // 注册驱动程序类
            Class.forName(driver);
            // 1、初始化连接对象
            conn = DriverManager.getConnection(url, user, password);
            // 2、设置连接对象的自动提交模式
            conn.setAutoCommit(false);
        } catch (Exception e) {
            throw new RuntimeException("get connect failed", e);
        }
    }
}
 

 

 

Customer对象

/**
 * 2012-8-15 tracy.liuy
 */
public class Customer {

    private Long   custId;
    private String name;

    public Long getCustId() {
        return custId;
    }

    public void setCustId(Long custId) {
        this.custId = custId;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

}
 

 

批量修改的代码

 

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;



/**
 * 
 * 2012-8-15
 * tracy.liuy
 */
public class IBatis {

    /**
     * @param sql
     * @param campaignBdLogList 2012-8-1 tracy.liuy
     * @throws InvocationTargetException
     * @throws IllegalAccessException
     * @throws NoSuchMethodException
     * @throws IllegalArgumentException
     * @throws SecurityException
     */
    public int updateBatch(List objList) {
        
        DbConnection dbC = new DbConnection("com.mysql.jdbc.Driver", "address",  
                                            "username", "password");  

        PreparedStatement stmt = null;
        int rows = 0;

        if (objList != null && objList.size() != 0) {
            return rows;
        }
        //ibatis中的sql语句
        String sql = "update coustomer set name=#name# where custid = #custId#";
        
        //1.将 sql语句中 ## 及之间的内容替换成 ?,即  update coustomer set name=? where custid = ? 
        String prepareSql = placeSomeCharacter(sql);

        try {
            
            //2.创建连接
            stmt = dbC.conn.prepareStatement(prepareSql);
            for (Object obj : objList) {
                //3.补全参数(详细介绍看下面的代码)
                this.fillStatementBatch(stmt, sql, obj);
                rows += stmt.executeUpdate();
            }

        } catch (SQLException e) {
            throw new RuntimeException(sql + " update failed", e);

        } catch (Exception e) {
            throw new RuntimeException(sql + " update failed", e);
        }

        finally {
            close(stmt);
        }

        return rows;

    }

    /**
     * 使用正则表达式,替换需要注入的内容
     * @param sql
     * @return
     * 2012-8-2
     * tracy.liuy
     */
    private String placeSomeCharacter(String sql) {
       return sql.replaceAll("#.+?#", "?");
    }
    
    /**
     * 将对象中的属性根据sql语句中指定的一一替换PreparedStatement中的?号
     * @param stmt
     * @param obj 2012-8-1 tracy.liuy
     * @param obj2
     * @throws SQLException
     * @throws NoSuchMethodException
     * @throws SecurityException
     * @throws InvocationTargetException
     * @throws IllegalAccessException
     * @throws IllegalArgumentException
     */
    private void fillStatementBatch(PreparedStatement stmt, String sql, Object obj) throws SQLException,
                                                                                   SecurityException,
                                                                                   NoSuchMethodException,
                                                                                   IllegalArgumentException,
                                                                                   IllegalAccessException,
                                                                                   InvocationTargetException {
        char c = '#';
        int begin = 0;
        List<Integer> indexList = new ArrayList<Integer>();

        while (true) {
            int index = sql.indexOf(c, begin);
            if (index == -1) {
                break;
            }
            indexList.add(index);
            begin = index+1;
        }

        List<String> props = new ArrayList<String>();

        for (int i = 0; i < indexList.size(); i += 2) {
            props.add(sql.substring(indexList.get(i)+1, indexList.get(i + 1)));
        }
        int i = 1;
        for (String prop : props) {
            stmt.setObject(i++, getProperties(obj, prop));
        }

    }

    /**
     * @param obj
     * @param prop
     * @return 2012-8-1 tracy.liuy
     * @throws NoSuchMethodException
     * @throws SecurityException
     * @throws InvocationTargetException
     * @throws IllegalAccessException
     * @throws IllegalArgumentException
     */
    @SuppressWarnings({ "rawtypes", "unchecked" })
    private Object getProperties(Object obj, String prop) throws SecurityException, NoSuchMethodException,
                                                         IllegalArgumentException, IllegalAccessException,
                                                         InvocationTargetException {
        Method metd = null;
        Class clazz = obj.getClass();
        metd = clazz.getMethod("get" + change(prop), null);
        if (metd != null) {
            return metd.invoke(obj, null);
        }
        return null;
    }

    /**
     * @param src 源字符串
     * @return 字符串,将src的第一个字母转换为大写,src为空时返回null
     */
    public String change(String src) {
        if (src != null) {
            StringBuffer sb = new StringBuffer(src);
            sb.setCharAt(0, Character.toUpperCase(sb.charAt(0)));
            return sb.toString();
        } else {
            return null;
        }
    }
    

    /**
     * 关闭结果集
     * 
     * @param rs 结果集
     */
    protected void close(ResultSet rs) {
        if (rs != null) {
            try {
                rs.close();
            } catch (SQLException e) {
                throw new RuntimeException("rs close failed", e);
            }
        }
    }
    
    
    /**
     * 关闭语句对象
     * 
     * @param stmt 语句对象
     */
    protected void close(Statement stmt) {
        if (stmt != null) {
            try {
                stmt.close();
            } catch (SQLException e) {
                throw new RuntimeException("stmt close failed", e);
            }
        }
    }

}
ibtais使用指南 ibtais使用指南,初学者必看 ibtais使用指南,初学者必看 ibtais使用指南,初学者必看 立即下载

相关推荐

java ibatis 动态注入_通过ibatis解决sql注入问题

于ibaits参数引用可以使用#和两种写法,其中#写法会采用预编译方式,将转义交给了数据库,不会出现注入问题;如果采用两种写法,其中#写法会采用预编译方式,将转义交给了数据库,不会出现注入问题;如果采用写法,则相当于拼接字符串,会出现注入问题。例如,如果属性值为“' or '1'='1 ”,采用#写法没有问题,采用写法就会有问题。对于语句,难免要使用写法就会有问题。对于like语句,难免要使用写法...

weixin_42138525的博客 400

JDBC和JPA的区别

1.JDBC提供一种接口,它是由各种数据库厂商提供类和接口组成的数据库驱动,为多种数据库提供统一访问。我们使用数据库时只需要调用JDBC接口就行了。 JDBC的用途:与数据库建立连接、发送 操作数据库的语句并处理结果。 常见数据库:Oracle、MySQL等。 2.JPA是Java持久层API。它是对java应用程序访问ORM(对象关系映射)框架的规范。为了我们能用相同的方法使用各种OR...

SteveForever的博客 1万+

Spring技术内幕之数据库操作组件的实现(02)-ORM的设计与实现

Spring ORM的设计与实现    java作为雨中面向对象的语言,为面向对象原则(封装/继承/多态)的实现提供了语言及运行环境支持,然而,由于这些面向对象的原则是从软件工程的基础上发展而来的,与从数据理 论中发展起来的关系型数据库技术在基础上存在着很大的差异。因此,在利用java进行开发时,操作关系型数据库时有很大的不便,为了解决这些不匹配的问题,出现了ORM产品 较常用的O

乐于学习、乐于分享、乐于总结 542

在绑定数据源的GirdView上,在删除数据时不触发datasource的删除命令

在ASP.NET中, GridView用来显示数据,datasource用来获取,删除,插入数据。不过,有时我们不需要datasource来处理删除或插入等操作。比如我们需要对被删除的数据进行判断。row command是负责处理数据编辑,插入,删除的。我们可以在protected void GridView1_RowCommand(object sender, GridViewComma

闫炜的专栏 1403

iBtais 多重嵌套循环

iBatis支持集合循环, 但是如何做到双重循环, 请见下例子 例子描述: 需要去三张结构相同的表中获取信息, 需要将信息拼合去重后返回 入参数据类型: Map,   regions  = List class OrderRegionNums{ String regionSchema String regionCode List orderNums }

zhwbqd的专栏 1111

Redis持久化方案该如何选型

前言这篇文章主要介绍Redis高可用相关的知识——持久化、复制(及读写分离)、哨兵、以及集群。本文将先说明上述几种技术分别解决了Redis高可用的什么问题;然后详细介绍Redis的持久化技术,主要是RDB和AOF两种持久化方案;在介绍RDB和AOF方案时,不仅介绍其作用及操作方法,同时介绍持久化实现的一些原理细节及需要注意的问题。最后,介绍在实际使用中,持久化方案的选择,以及经常遇到的问题等。一、...

weixin_40581617的博客 615

AJAX AutoComplete简单的小例子

因为项目需要,写了一个简单的AJAX自动完成的小例子,这里给出代码。代码没有优化,优化方向是:1.进一步解耦  2.增加本地数据缓存的筛选,减少交互次数  3.优化筛选算法 有兴趣的朋友可以去尝试一下。/**//* *    AutoComplete Class *  Author: Robin Chen(robchen@126.com)*///AutoComplete Classvar 

萝卜的技术专栏 4966

ibtais中的isNotNull、isEqual、isEmpty

isNotNull:判断property字段是否是nullisEmpty:判断property字段是否是null或者是否是空字符串(比上面的更好用)isEqual:相当于equals,数字用得多些,一般都是判断状态值

XuJiangDong 1121

java开发涉及到的各种框架比较,技术选型

SOA服务框架 Dubbo: 一个分布式服务框架,以及SOA治理方案. SOA框架有:淘宝的HSF、阿里的dubbo、amazon coral、twitter Finagle,Xfire(ws服务)+OSGI+Spring,支付宝SOA架构,WebService也是古老的SOA。 其功能主要包括:高性能NIO通讯及多协议集成,服务动态寻址与路由,软负载均衡与容错,依赖分析与降级等。是远程服

葛明的博客 9785

ibatis解决sql注入问题

对于ibaits参数引用可以使用#和$两种写法,其中#写法会采用预编译方式,将转义交给了数据库,不会出现注入问题;如果采用$写法,则相当于拼接字符串,会出现注入问题。 例如,如果属性值为“' or '1'='1 ”,采用#写法没有问题,采用$写法就会有问题。 对于like语句,难免要使用$写法, 1. 对于Oracle可以通过'%'||'#param#'||'%'避免; 2. 对于MySQ...

小白编程 388

一个简单的MyBatis程序实例

1、在test库创建表student(MySql数据库) CREATE TABLE `student` (   `id` int(5) NOT NULL AUTO_INCREMENT,   `name` varchar(10) DEFAULT NULL,   `age` int(3) DEFAULT NULL,   `score` double DEFAULT NULL,   PRIM

abc5232033的博客 7681

spring mvc求高人指点

最近学习spring mvc 老报这个错误,哪位大虾帮忙看看   javax.servlet.jsp.JspTagException: Neither BindingResult nor plain target object for bean name 'users' available as request attribute at org.springframework.web...

cupsstop的博客 128

iBatis解决自动防止sql注入

#xxx# 代表xxx是属性值,map里面的key或者是你的pojo对象里面的属性, ibatis会自动在它的外面加上引号,表现在sql语句是这样的where xxx = 'xxx' ; (1)ibatis xml配置:下面的写法只是简单的转义name like '%$name$%'   (2) 这时会导致sql注入问题,比如参数name传进一个单引号“'”,生成的sql语句会是:name

cnbird's blog 1万+

JSP:include 用于构建动态网站的简单 JSP 标记

JSP:include 用于构建动态网站的简单 JSP 标记    (转载)Brett McLaughlin作家, OReilly and Associates2003 年 7 月 06 日本文是 Java Brett McLaughlin 继第一篇 JSP 最佳实践文章后的后续文章,在文中,作者向您演示了如何扩展 JSP 技术中用于动态内容的包含功能。了解静态 include 伪指令和动态 j

Antonio 的专栏 1287

jstat 工具使用

jstat [Options] vmid [interval] [count]    Options — 选项,我们一般使用 -gcutil 查看gc情况    vmid    — VM的进程号,即当前运行的java进程号    interval– 间隔时间,单位为秒或者毫秒    count   — 打印次数,如果缺省则打印无数次    S0  — Heap上的 Survivor space 0

lilp_ndsc的专栏 859

利用Freemarker实现表到功能界面的一键生成

利用Freemarker产生项目所需的常用文件,可以根据一个表产生对应的ibtaisjava及xml文件,及前台的JSP文件,这样可以大大的提高普通程序编写人员的开发效率,及从表到界面及CURD功能利用这个工程可以直接生成好,下面提供下最核心的文件产生类,代码如下: 另外提供编译过的工程文件,可执行文件,在附件中,由于大小控制,已经删除里面的freema...

weixin_33774883的博客 140

mybatis入门详解

一、Mybatis介绍    MyBatis是一个支持普通SQL查询,存储过程和高级映射的优秀持久层框架。MyBatis消除了几乎所有的JDBC代码和参数的手工设置以及对结果集的检索封装。MyBatis可以使用简单的XML或注解用于配置和原始映射,将接口和Java的POJO(Plain Old Java Objects,普通的Java对象)映射成数据库中的记录。二、mybat...

weixin_33907511的博客 300

easy-UI作为页面展示的一个例子

String path = request.getContextPath();  String beforeDay = com.companyname.dhm.common.util.StringUtil.beforeDay(); // 昨天 String weeks = com.companyname.dhm.common.util.StringUtil.weeks(); // 上周一 S

okkeqin的专栏 3098
上一篇: JDBC 连接示例
下一篇: InnoDB
mesum
博客等级 码龄18年 1粉丝 10原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值