欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

利用ThreadLocal完美解决JDBC动态拼接SQL的多条件查询

程序员文章站 2022-05-10 17:25:39
...
再摘一段JDBC多条件查询的单元测试实例(源码可在jSQLBox项目下找到),大家知道在条件不确定的情况下,执行动态拼接生成的SQL,即要保证SQL安全性,防止SQL注入,又要保证编码的简洁性,这一直是一个头痛的问题。 jSQLBox利用ThreadLocal解决了这个问题:
Java代码  收藏代码

    public class ConditionQueryTest { 
        @Before 
        public void setup() { 
            TestPrepare.dropAndRecreateTables(); 
            User u = new User(); // use default SqlBoxContext 
            u.setUserName("User1"); 
            u.setAddress("Address1"); 
            u.setAge(10); 
            u.insert(); 
        } 
     
        @After 
        public void cleanUp() { 
            TestPrepare.closeDefaultContexts(); 
        } 
     
        public int conditionQuery(int condition, Object parameter) { 
            User u = SqlBox.createBean(User.class); 
            String sql = "Select count(*) from " + u.table() + " where "; 
            if (condition == 1 || condition == 3) 
                sql = sql + u.userName() + "=" + q(parameter) + " and " + u.address() + "=" + q("Address1"); 
     
            if (condition == 2) 
                sql = sql + u.userName() + "=" + q(parameter); 
     
            if (condition == 3) 
                sql = sql + " or " + u.age() + "=" + q(parameter); 
     
            return SqlBox.queryForInteger(sql); 
        } 
     
        @Test 
        public void doJdbcConditionQuery() { 
            Assert.assertEquals(1, conditionQuery(1, "User1")); 
            Assert.assertEquals(0, conditionQuery(2, "User does not exist")); 
            Assert.assertEquals(1, conditionQuery(3, 10)); 
            Assert.assertEquals(0, conditionQuery(3, 20)); 
        } 
    } 


再顺便说一下u.userName()也可以直接写成"username"字串,写成u.userName()是jSQLBox项目鼓励的一种方式,当User类字段名重构或字段名不变但是数据库列名更改时(配置文件变化),所有JDBC SQL语句自动适应更改,不需要一个个手工检查和改正SQL,保证了SQL语句的建壮性。另外u.UserName()这种写法在查询中还会利用到,因为项目还在开发中,就不多说了,总之个人认为这是一种比较好的编程风格,在不改变SQL语法的前提下实现了SQL支持重构。