• Mybatis--Statement Builders


    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 的所有可用的方法。 下表就 是可用方法的完整列表:

    方法

    描述

    BEGIN() / RESET() 这些方法清理 SelectBuilder 类的 ThreadLocal 的状态,而且 准备构建新的语句。当开始一条新的语句时,BEGIN()读取 得最好。当在执行中间因为某些原因(在某些条件下,也许 处理逻辑需要一个完整的而且不同的语句)要清理一条语句 时 RESET()读取的做好。
    SELECT(String) 开始或附加一个 SELECT 子句。可以被多次调用,而且参数 会被追加在 SELECT 子句后面。 参数通常是逗号分隔的列名 列表和别名,但要是驱动程序可以接受的东西。
    SELECT_DISTINCT(String) 开始或附加一个 SELECT 子句, 也在生成的查询语句中添加 “DISTINCT”关键字。可以被多次调用,而且参数会被追 加在 SELECT 子句后面。 参数通常是逗号分隔的列名列表和 别名,但要是驱动程序可以接受的东西。
    FROM(String) 开始或附加一个 FROM 子句。 可以被多次调用, 而且参数会 被追加在 FROM 子句后面。 参数通常是表明或别名, 或是驱 动程序可以接受的任意内容。
    • JOIN(String)
    • INNER_JOIN(String)
    • LEFT_OUTER_JOIN(String)
    • RIGHT_OUTER_JOIN(String)
    基于调用的方法,添加一个合适类型的新的 JOIN 子句。参 数可以包含列之间基本的 join 连接还有条件连接。
    WHERE(String) 添加一个新的 WHERE 条件子句,由 AND 串联起来。可以 被多次调用, AND 告诉它来串联一个新的条件。 由 使用 OR() 方法来分隔 OR 条件。
    OR() 使用 OR 来分隔当前 WHERE 子句的条件。 可以被多次调用, 但是在一行上多次调用会生成不稳定的 SQL。
    AND() 使用 AND 来分隔当前 WHERE 字句的条件。可以被多次调 用,但是在一行上多次调用会生成不稳定的 SQL。因为 WHERE 和 HAVING 两者都自动串联 AND,这样使用是非 常罕见的,包含它也仅仅是为了完整性。
    GROUP_BY(String) 附加一个新的 GROUP BY 子句,由逗号串联起来。可以被 多次调用,每次使用逗号来告诉它串联一个新的条件。
    HAVING(String) 附加一个新的 HAVING 条件子句,由 AND 串联起来。可以 被多次调用,每次使用 AND 来告诉它要串联新的条件。使 用 OR()方法来分隔 OR 条件。
    ORDER_BY(String) 附加一个新的 ORDER BY 子句,由逗号串联起来。可以被 多次调用,每次使用逗号来告诉它串联新的条件。
    SQL() 这会返回生成 SQL 而且重置 SelectBuilder 的状态(正如 BEGIN()或 RESET()方法被调用)。因此,这个方法只能被调 用一次!

    SqlBuilder

    和 SelectBuilder 相似,MyBatis 也包含一个一般性的 SqlBuilder。它包含 SelectBuilder 的所有方法,还有构建 insert,update 和 delete 的方法。在 DeleteProvider,InsertProvider 或 UpdateProvider 中(还有 SelectProvider)构建 SQL 字符串时这个类就很有用。

    在上述示例中要使用 SqlBuilder,你只需简单静态引入如下内容:

    import static org.apache.ibatis.jdbc.SqlBuilder.*;

    SqlBuilder 包含 SelectBuilder 中的所有方法,还有下面这些额外的方法:

    方法 描述
    DELETE_FROM(String) 开始一个 delete 语句,要指定删除的表。通常它后面要跟着一个 WHERE 语句!
    INSERT_INTO(String) 开始一个 insert 语句, 要指定插入的表。 它的后面要跟着一个或多 个 VALUES()调用。
    SET(String) 为更新语句附加“set”内容的列表。
    UPDATE(String) 开始一个 update 语句,要指定更新的表。它的后面要跟着一个或 多个 SET()调用,通常需要一个 WHERE()调用。
    VALUES(String, String) 附加到 insert 语句后。 第一个参数是要插入的列名, 第二个参数是 要插入的值。

    这里是一些示例:

    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();
    }
    









  • 相关阅读:
    Android 主题theme说明 摘记
    Android开发 去掉标题栏方法 摘记
    安卓项目五子棋代码详解(二)
    关于 ake sure class name exists, is public, and has an empty constructor that is public
    百度地图3.0实现图文并茂的覆盖物
    android onSaveInstanceState()及其配对方法。
    关于集成科大讯飞语音识别的 一个问题总结
    android 关于 webview 控制其它view的显示 以及更改view数据失败的问题总结
    C# 解析 json Newtonsoft果然强大,代码写的真好
    c#数据类型 与sql的对应关系 以及 取值范围
  • 原文地址:https://www.cnblogs.com/archermeng/p/7537357.html
Copyright © 2020-2023  润新知