MyBatis SQL 语句构建器

1 问题

Java 程序员面对的最痛苦的事情之一就是在 Java 代码中嵌入 SQL 语句。

如你所见,MyBatis 在 XML 映射中具备强大的 SQL 动态生成能力。

但有时,我们还是需要在 Java 代码里构建 SQL 语句。

在 Java 代码中动态生成 SQL 代码真的就是一场噩梦。例如:

String 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";

2 解决方案

MyBatis 3 提供了方便的工具类来帮助解决此问题。

借助 SQL 类,我们只需要简单地创建一个实例,并调用它的方法即可生成 SQL 语句。

让我们来用 SQL 类重写上面的例子:

private String selectPersonSql() {

  return new SQL() {{

    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");

  }}.toString();

}

这个例子有什么特别之处吗? 仔细看一下你会发现,你不用担心可能会重复出现的 "AND" 关键字,或者要做出用 "WHERE" 拼接还是 "AND" 拼接还是不用拼接的选择。 SQL 类已经为你处理了哪里应该插入 "WHERE"、哪里应该使用 "AND" 的问题,并帮你完成所有的字符串拼接工作。

3 SQL 类

这里有一些示例:

// 匿名内部类风格

public String deletePersonSql() {

  return new SQL() {{

    DELETE_FROM("PERSON");

    WHERE("ID = #{id}");

  }}.toString();

}

// Builder / Fluent 风格

public String insertPersonSql() {

  String sql = new SQL()

    .INSERT_INTO("PERSON")

    .VALUES("ID, FIRST_NAME", "#{id}, #{firstName}")

    .VALUES("LAST_NAME", "#{lastName}")

    .toString();

  return sql;

}

// 动态条件(注意参数需要使用 final 修饰,以便匿名内部类对它们进行访问)

public String selectPersonLike(final String id, final String firstName, final String lastName) {

  return new SQL() {{

    SELECT("P.ID, P.USERNAME, P.PASSWORD, P.FIRST_NAME, P.LAST_NAME");

    FROM("PERSON P");

    if (id != null) {

      WHERE("P.ID like #{id}");

    }

    if (firstName != null) {

      WHERE("P.FIRST_NAME like #{firstName}");

    }

    if (lastName != null) {

      WHERE("P.LAST_NAME like #{lastName}");

    }

    ORDER_BY("P.LAST_NAME");

  }}.toString();

}

public String deletePersonSql() {

  return new SQL() {{

    DELETE_FROM("PERSON");

    WHERE("ID = #{id}");

  }}.toString();

}

public String insertPersonSql() {

  return new SQL() {{

    INSERT_INTO("PERSON");

    VALUES("ID, FIRST_NAME", "#{id}, #{firstName}");

    VALUES("LAST_NAME", "#{lastName}");

  }}.toString();

}

public String updatePersonSql() {

  return new SQL() {{

    UPDATE("PERSON");

    SET("FIRST_NAME = #{firstName}");

    WHERE("ID = #{id}");

  }}.toString();

}

你可能感兴趣的:(MyBatis SQL 语句构建器)