Mybatis--Statement Builders
来源:互联网 发布:东盟水果进口贸易数据 编辑:程序博客网 时间:2024/06/09 14:33
Statement Builders
SelectBuilder
一个 Java 程序员面对的最痛苦的事情之一就是在 Java 代码中嵌入 SQL 语句。 通常这么 做是因为 SQL 要动态的生成-否则你可以将它们放到外部的文件或存储过程中。正如你已经 看到的,MyBatis 在它的 XML 映射特性中有处理生成动态 SQL 的很强大的方案。然而,有 时必须在 Java 代码中创建 SQL 语句的字符串。这种情况下,MyBatis 有另外一种特性来帮 助你,在减少典型的加号,引号,新行,格式化问题和嵌入条件来处理多余的逗号或 AND 连接词之前,事实上,在 Java 代码中动态生成 SQL 就是一个噩梦。
MyBatis 3 引入了一些不同的理念来处理这个问题,我们可以创建一个类的实例来调用 其中的方法来一次构建 SQL 语句。 但是我们的 SQL 结尾时看起来很像 Java 代码而不是 SQL 语句。相反,我们尝试了一些不同的做法。最终的结果是关于特定领域语言的结束,Java 也不断实现它目前的形式...
SelectBuilder 的秘密
SelectBuilder 类并不神奇, 如果你不了解它的工作机制也不会有什么好的作用。 别犹豫, 让我们来看看它是怎么工作的。 SelectBuilder 使用了静态引入和 TreadLocal 变量的组合来开 启简洁的语法可以很容易地用条件进行隔行扫描,而且为你保护所有 SQL 的格式。它允许 你创建这样的方法:
public String selectBlogsSql() { BEGIN(); // Clears ThreadLocal variable SELECT("*"); FROM("BLOG"); return SQL();}
这是一个非常简单的示例, 你也许会选择静态地来构建。 所以这里给出一个复杂一点的 示例:
private String selectPersonSql() { BEGIN(); // Clears ThreadLocal variable SELECT("P.ID, P.USERNAME, P.PASSWORD, P.FULL_NAME"); SELECT("P.LAST_NAME, P.CREATED_ON, P.UPDATED_ON"); FROM("PERSON P"); FROM("ACCOUNT A"); INNER_JOIN("DEPARTMENT D on D.ID = P.DEPARTMENT_ID"); INNER_JOIN("COMPANY C on D.COMPANY_ID = C.ID"); WHERE("P.ID = A.ID"); WHERE("P.FIRST_NAME like ?"); OR(); WHERE("P.LAST_NAME like ?"); GROUP_BY("P.ID"); HAVING("P.LAST_NAME like ?"); OR(); HAVING("P.FIRST_NAME like ?"); ORDER_BY("P.ID"); ORDER_BY("P.FULL_NAME"); return SQL();}
用字符串连接的方式来构建上面的 SQL 就会有一些繁琐了。比如:
"SELECT P.ID, P.USERNAME, P.PASSWORD, P.FULL_NAME, ""P.LAST_NAME,P.CREATED_ON, P.UPDATED_ON " +"FROM PERSON P, ACCOUNT A " +"INNER JOIN DEPARTMENT D on D.ID = P.DEPARTMENT_ID " +"INNER JOIN COMPANY C on D.COMPANY_ID = C.ID " +"WHERE (P.ID = A.ID AND P.FIRST_NAME like ?) " +"OR (P.LAST_NAME like ?) " +"GROUP BY P.ID " +"HAVING (P.LAST_NAME like ?) " +"OR (P.FIRST_NAME like ?) " +"ORDER BY P.ID, P.FULL_NAME";
如果你喜欢那样的语法,那么你就可以使用它。它很容易出错,要小心那些每行结尾增 加的空间。现在,即使你喜欢这样的语法,下面的示例比 Java 中的字符串连接要简单也是 没有疑问的:
private String selectPersonLike(Person p){ BEGIN(); // Clears ThreadLocal variable SELECT("P.ID, P.USERNAME, P.PASSWORD, P.FIRST_NAME, P.LAST_NAME"); FROM("PERSON P"); if (p.id != null) { WHERE("P.ID like #{id}"); } if (p.firstName != null) { WHERE("P.FIRST_NAME like #{firstName}"); } if (p.lastName != null) { WHERE("P.LAST_NAME like #{lastName}"); } ORDER_BY("P.LAST_NAME"); return SQL();}
这个例子有什么特殊之处?如果你看得仔细,那就不同担心偶然会重复的“AND”关 键字,或在“WHERE”和“AND”或两者都没有中选择!上面的语句将会由例子对所有 PERSON 记录生成一个查询,有像参数一样的 ID 或 firstName 或 lastName-或这三者的任意 组合。SelectBuilder 对理解哪里放置“WHERE” ,哪里应该使用“AND”还有所有的字符串 连接都是很小心的。 最好的情况, 无论你以何种顺序调用这些方法 (只有一种例外使用 OR() 方法)。
有两个方法会吸引你的眼球:BEGIN()和 SQL()。总之,每个 SelectBuilder 方法应该以 调用 BEGIN()开始,以调用 SQL()结束。当然你可以在中途提取方法来打断你执行的逻 辑,但是 SQL 生成的范围应该以 BEGIN()方法开始而且以 SQL()方法结束。BEGIN()方法清 理 ThreadLocal 变量,来确保你不会不小心执行了前面的状态,而且 SQL()方法会基于这些 调用, 从最后一次调用 BEGIN()开始组装你的 SQL 语句。 注意 BEGIN()有一个称为 RESET() 的代替方法,它们所做的工作相同,只是 RESET()会在特定上下文中读取的更好。
要按照上面示例的方式使用 SelectBuilder,你应该静态引入如下内容:
import static org.apache.ibatis.jdbc.SelectBuilder.*;
只要这个被引入了, 那么你使用的类就会拥有 SelectBuilder 的所有可用的方法。 下表就 是可用方法的完整列表:
方法
描述
- JOIN(String)
- INNER_JOIN(String)
- LEFT_OUTER_JOIN(String)
- RIGHT_OUTER_JOIN(String)
SqlBuilder
和 SelectBuilder 相似,MyBatis 也包含一个一般性的 SqlBuilder。它包含 SelectBuilder 的所有方法,还有构建 insert,update 和 delete 的方法。在 DeleteProvider,InsertProvider 或 UpdateProvider 中(还有 SelectProvider)构建 SQL 字符串时这个类就很有用。
在上述示例中要使用 SqlBuilder,你只需简单静态引入如下内容:
import static org.apache.ibatis.jdbc.SqlBuilder.*;
SqlBuilder 包含 SelectBuilder 中的所有方法,还有下面这些额外的方法:
这里是一些示例:
public String deletePersonSql() { BEGIN(); // Clears ThreadLocal variable DELETE_FROM("PERSON"); WHERE("ID = ${id}"); return SQL();}public String insertPersonSql() { BEGIN(); // Clears ThreadLocal variable INSERT_INTO("PERSON"); VALUES("ID, FIRST_NAME", "${id}, ${firstName}"); VALUES("LAST_NAME", "${lastName}"); return SQL();}public String updatePersonSql() { BEGIN(); // Clears ThreadLocal variable UPDATE("PERSON"); SET("FIRST_NAME = ${firstName}"); WHERE("ID = ${id}"); return SQL();}
- Mybatis--Statement Builders
- Mybatis--Statement Builders
- MyBatis Invalid bound statement
- MyBatis Invalid Bound Statement
- MyBatis Invalid bound statement
- mybatis错误: Invalid bound statement
- MyBatis使用statementType="STATEMENT"
- MyBatis的statementType="STATEMENT"
- mybatis 异常:Invalid bound statement (not found) .
- mybatis错误: Invalid bound statement (not found)
- MyBatis:Invalid bound statement (not found)
- mybatis错误:Invalid bound statement (not found)
- mybatis BindingException: Invalid bound statement (not found)
- mybatis:Invalid bound statement (not found)
- mybatis: Invalid bound statement (not found)
- mybatis的statement的解析与加载
- mybatis:Invalid bound statement (not found)
- mybatis错误:Invalid bound statement (not found)
- R语言数据挖掘之关联规则
- Linux 静态库与动态库搜索路径设置详解
- django static_root static_url media_root mdia_url详解
- react-native 轮播图 ——react-native-swiper使用
- C++学习:引用和函数的高级用法
- Mybatis--Statement Builders
- VMvare拷贝后提示路径错误(无法打开xxxx文件)
- lintcode-矩阵面积
- 【CountDownLatch实例】主线程等待其它线程执行完毕
- 生成1-256十进制,二进制,八进制,十六进制值
- JQuery
- c++ 解析从浏览器端传过来的图像base64编码,并转换成opencv识别的格式
- 今天第一天加入CSDN,发现CSDN网站的一个小BUG!
- Mybatis--Logging