MyBatis Generator 自动生成的POJO对象的使用(二)
四、Example Class使用说明
示例类指定如何构建动态where子句。
表中的每个非BLOB列都可以选择包含在where子句中。 示例是演示此类用法的最佳方法。
示例类可用于生成几乎无限制的where子句。
Example类包含一个名为Criteria的内部静态类,Criteria类包含了一个条件List,这些条件都会通过“and”运算添加到where子句中。
Example 类包含一个Criteria对象的List,源自内部类的所有子句都将通过“or”运算连接起来。
使用不同的Criteria类集允许您生成几乎无限制类型的where子句。
可以使用Example类中的createCriteria方法或“or”方法创建Criteria对象。
当使用createCriteria方法创建第一个Criteria对象时,它会自动添加到Criteria对象列表中 - 如果您不需要或其他几个子句,则可以轻松编写简单的where子句。
使用or方法时,Criteria类将被添加到所有实例的列表中。
重要提示:
我们建议您仅使用or方法创建Criteria类。 我们相信这种方法可以使代码更具可读性。
4.1、简单查询
此示例显示如何使用生成的示例类生成简单的WHERE子句:
TestTableExample example = new TestTableExample(); example.createCriteria().andField1EqualTo(5);
或者,以下语法也奏效:
TestTableExample example = new TestTableExample(); example.or().andField1EqualTo(5);
在上面的任何一个例子中,动态生成的where子句实际上是:
where field1 = 5
4.2 复杂查询
下一个示例演示如何使用生成的示例类生成复杂的WHERE子句(使用JSE 5.0参数化类型)
TestTableExample example = new TestTableExample(); example.or() .andField1EqualTo(5) .andField2IsNull(); example.or() .andField3NotEqualTo(9) .andField4IsNotNull(); List<Integer> field5Values = new ArrayList<Integer>(); field5Values.add(8); field5Values.add(11); field5Values.add(14); field5Values.add(22); example.or() .andField5In(field5Values); example.or() .andField6Between(3, 7);
在上面的例子中,动态生成的where子句实际上是:
where (field1 = 5 and field2 is null) or (field3 <> 9 and field4 is not null) or (field5 in (8, 11, 14, 22)) or (field6 between 3 and 7)
返回的records(记录)将会符合这些条件。
4.3、非同查询(Distinct Queries)
您可以通过在任何示例类上调用setDistinct(true)方法来强制查询为DISTINCT。
4.4、条件类(Criteria Classes)
Criteria内部类包括每个字段的andXXX方法,以及每个标准SQL谓词,包括:
- IS NULL - meaning the related column must be NULL
- IS NOT NULL - meaning the related column must not be NULL
- = (equal) - meaning the related column must be equal to the value passed in on the method call
- <> (not equal) - meaning the related column must not be equal to the value passed in on the method call
- > (greater than) - meaning the related column must be greater than the value passed in on the method call
- >= (greater than or equal) - meaning the related column must be greater than or equal to the value passed in on the method call
- < (less than) - meaning the related column must be less than the value passed in on the method call
- <= (less than or equal) - meaning the related column must be less than or equal to the value passed in on the method call
- LIKE - meaning the related column must be "like" the value passed in on the method call. The code does not add the required '%', you must set that value yourself in the value you pass in on the method call.
- NOT LIKE - meaning the related column must be "not like" the value passed in on the method call. The code does not add the required '%', you must set that value yourself in the value you pass in on the method call.
- BETWEEN - meaning the related column must be "between" the two values passed in on the method call.
- NOT BETWEEN - meaning the related column must be "not between" the two values passed in on the method call.
- IN - meaning the related column must be one of the list of values passed in on the method call.
- NOT IN - meaning the related column must not be one of the list of values passed in on the method call.
五、扩展Example类
在某些情况下,可能需要扩展生成的示例类。
您可能希望添加特定于数据库的条件(例如Oracle ROWNUM支持),或添加未自动生成的条件(例如不区分大小写的搜索)。
在这些情况下,您可以扩展生成的示例类以添加这些附加条件。
5.1、通用原则
MyBatis Generator(MBG)会为每个表生成一个“示例”类,除非在配置中另有说明。
“example”类用于生成在xxxByExample语句中使用的动态where子句。 标准“example”类会包含所有标准SQL谓词的功能。
在某些情况下,可能需要为应用程序的特定需求添加其他谓词。 这可能包括添加对非标准谓词的支持,或者在where子句中使用特定于数据库的函数。
生成的“example”类包含一个嵌套的内部类,其中存在谓词的实际功能。
这个内部类始终命名为GeneratedCriteria。 MBG还生成一个名为Criteria的内部类,它扩展了GeneratedCriteria,您可以使用它来将自己的函数添加到示例类中。
Eclipse Java代码合并不会删除Criteria类,因此您可以添加它,而不必担心在重新生成时丢失更改。
例如,假设有一个名为CUSTOMER的表。 通常,MBG会生成一个名为CustomerExample的类。要向CustomerExample类添加功能,您应该向CustomerExample.Criteria类添加其他方法。
5.2、Extending vs Plugging ln
如果您频繁扩展示例类,那么创建一个插件以生成附加功能而不是手动编写扩展类可能会更方便。
下面的示例(在“Single Parameter Predicates”标题下)也可以使用插件来完成,如org.mybatis.generator.plugins.CaseInsensitiveLikePlugin类所示。
5.3、添加谓词(Adding Predicates)
MBG生成一个动态SQL片段,允许在运行时创建几乎没有限制的where子句。为此,生成的SQL片段支持四种广泛类型的SQL谓词。对于每种类型的SQL谓词,GeneratedCriteria内部类中都有一个相应的方法,可用于向动态where子句添加谓词。
1、简单的字符串替换
当不需要将参数对象中的属性代入where子句时,将使用此类型的谓词。示例:
FIRST_NAME is null LAST_NAME is not null
此谓词在GeneratedCriteria类中的方法是:
addCriterion(String anyString)
其中“anyString”是要代入where子句的字符串。此方法可用于向生成的where子句添加任何类型的测试。
例如,假设您想使用SOUNDEX函数执行“sounds like”名称搜索。在MySQL中,谓词应如下所示:
SOUNDEX(FIRST_NAME) = SOUNDEX('frod')
这个谓词太复杂而无法使用任何其他方法,因此必须通过简单的字符串替换将其插入到where子句中。将以下方法添加到Criteria内部类以实现此功能:
public Criteria andFirstNameSoundsLike(String value) { StringBuffer sb = new StringBuffer("SOUNDEX(FIRST_NAME) = SOUNDEX('"); sb.append(value); sb.append("')"); addCriterion(sb.toString()); return this; }
以下代码显示了使用selectByExample方法使用此新功能:
CustomerExample example = new CustomerExample(); Criteria criteria = example.createCriteria(); criteria.andFirstNameSoundsLike("frod"); List results = selectByExample(example);
此方法可用于将几乎任何谓词添加到where子句。但是,如果可能,通常最好使用参数替换,因为存在正确格式化不同数据类型的问题(最明显的是日期,时间和时间戳)。
此外,如果您暴露了一个过于通用的方法,则此方法可能会出现SQL注入问题。 如果可能,我们建议使用下面列出的其他方法之一。
2、单参数谓词(Single Parameter Predicates)
当参数对象中有一个属性要代入为where子句时,将使用这种类型的谓词。
例如:
FIRST_NAME = ?
LAST_NAME <> ?
为此谓词生成的Criteria类方法是:
addCriterion(String anyString, Object anyObject, String propertyName)
anyString 是在参数替换之前代入where子句的字符串。
anyObject 是字符串替换后代入where子句的Object
propertyName的 是一个字符串,表示与此子句相关的属性名称。此字符串仅用于潜在的错误消息。
此方法可用于将与单个参数相关的简单测试添加到生成的where子句中。
例如,假设您要对某些列执行不区分大小写的搜索。 在MySQL中,谓词可能如下所示:
upper(FIRST_NAME) like ?
此谓词适合单个参数谓词的功能 - 其中谓词是字符串值,后跟单个参数。
将以下方法添加到ExtendedCriteria以获得此功能:
public ExtendedCriteria andFirstNameLikeInsensitive(String value) { addCriterion("upper(FIRST_NAME) like", value.toUpperCase(), "firstName"); return this; }
以下代码显示了使用selectByExample方法使用此新功能:
ExtendedExample example = new ExtendedExample(); ExtendedCriteria criteria = (ExtendedCriteria) example.createCriteria(); criteria.andFirstNameLikeInsensitive("fred%"); List results = selectByExample(example);
3、List Predicates
列表谓词用于将可变大小的值的列表作为参数添加到where子句。
例子包括:
FIRST_NAME IN (?, ?, ?)
LAST_NAME NOT IN (?, ?, ?, ?)
此谓词的灵活性低于其他谓词,因为它专门用于“in”和“not in”标准谓词。
尽管如此,如果您发现它的一些用途,Criteria类中的相应方法如下:
addCriterion(String anyString, List listOfObjects, String propertyName)
anyString是在参数替换之前代入where子句的字符串
listOfObjects是字符串替换后要替换为where子句的对象列表(在列表之前将附加一个左括号,列表项将以逗号分隔,并且在列表之后将附加一个右括号)。
propertyName的是一个字符串,表示与此子句相关的属性名称。 此字符串仅用于潜在的错误消息。
4、Between predicates
Between predicates用于将两个参数添加到特定格式的where子句中。
例子包括:
FIRST_NAME BETWEEN ? AND ?
LAST_NAME NOT BETWEEN ? AND ?
此谓词的灵活性低于其他谓词,因为它专门用于“between”和“not between”标准谓词。尽管如此,如果您发现它的一些用途,Criteria类中的相应方法如下:
addCriterion(String anyString, Object object1, Object object2, String propertyName)
anyString是在参数替换之前代入where子句的字符串。
object1是字符串替换后代入where子句的对象(单词“and”将在此对象后面附加)。
object2是要代入单词“and”之后的where子句的对象。
propertyName是一个字符串,表示与此子句相关的属性名称。 此字符串仅用于潜在的错误消息。
五、MyBatis Dynamic SQL使用说明
此页面简要介绍了如何使用为MyBatis3DynamicSQL运行时生成的类
这些类依赖于MyBatis Dynamic SQL库。有关库如何工作的完整信息,请参阅该站点。
对于每个内省表,生成器将生成三个对象:
- 表示表中一行的“record”类。 这与其他运行时相同;
- 一个“support”类,包括数据库表的表定义和列定义;
- 映射器接口,包含其他运行时生成的所有典型方法。
关于这些生成的对象的说明:
- 有关生成的对象的重要说明:
- 没有生成XML
- 没有生成单独的“Example”类
- 没有单独的“with BLOBs”和“without BLOBs”方法。 如果您的表包含BLOB字段,则它们将包含在所有操作中。
- 模型类总是在“flat”模型中生成,这意味着没有单独的主键类或BLOB类
- 需要Java 8或更高版本
- 需要MyBatis 3.4.2或更高版本
5.1、support类的格式
每个表都会创建一个“support”类。
support类包括表的定义和表中的所有列。 这些项目用作映射器中生成的代码的输入 - 通常用于您将编写的where子句。
例如,假设数据库“MYSCHEMA”中有一个表“TABLE_CODE”。 进一步假设该表具有“ID”和“DESCRIPTION”列。 生成的支持类将如下所示:
package example; import java.sql.JDBCType; import org.mybatis.dynamic.sql.SqlColumn; import org.mybatis.dynamic.sql.SqlTable; public final class TableCodeDynamicSqlSupport { public static final TableCode tableCode = new TableCode(); public static final SqlColumn<Integer> id = tableCode.id; public static final SqlColumn<String> description = tableCode.description; public static final class TableCode extends SqlTable { public final SqlColumn<Integer> id = column("ID", JDBCType.INTEGER); public final SqlColumn<String> description = column("DESCRIPTION", JDBCType.VARCHAR); public TableCode() { super("MYSCHEMA.TABLE_CODE"); } } }
在您的代码中,通常导入此支持类的静态元素,以便可以直接在您编写的代码中使用它们。使用此静态导入,您可以以直接或合格的方式引用字段 - “id”或“tableCode.id”。
5.2 Mapper类的使用
以下方法与其他运行时的工作方式相同,我们不会在此处介绍它们:
- Delete by Primary Key
- Insert - will insert nulls
- insert selective - ignores null properties
- Select by Primary Key
- Update by Primary Key - will set null values
- Update by Primary Key Selective - ignores null values
而"by example"放啊却很不同,生成器将创建以下“通过示例”方法:
- Count by example
- Delete by example
- Select by example
- Update by example
这些方法中的每一个都包括对非常灵活的WHERE子句的支持。每个方法都返回一个构建器对象( a builder object ),该对象要求您可以选择添加WHERE子句,然后完成构建器并执行该方法。
如果您不提供WHERE子句,则该语句仍然有效 - 但它将应用于表的所有行。 通过调用构建方法完成所有构建器,最后通过调用execute方法执行语句。
例如,您可以通过在没有WHERE子句的情况下调用count by example方法来检索表中的总行数。 该代码如下所示:
long totalRows = mapper.countByExample() .build() .execute();
您可以通过调用select by example而不使用WHERE子句来检索表中的所有行:
List<TableCode> allRecords = mapper.selectByExample()
.build()
.execute();
将WHERE子句添加到这些方法中会更有趣。要添加对WHERE子句的支持,您应该从support类导入静态元素,如上所示,您还应该导入SqlBuilder支持。然后你可以编码任意复杂的where子句和“ORDER BY”短语,如下所示:
import static example.TableCodeDynamicSqlSupport.*; // import the generated "support" items import static org.mybatis.dynamic.sql.SqlBuilder.*; // import MyBatis Dynamic SQL where support public class SomeService { public void simpleWhere { ... // Simple WHERE clause List<TableCode> records = mapper.selectByExample() .where(id, isEqualTo(3)) .build() .execute(); ... } public void complexWhere1 { ... // Simple WHERE clause with OR List<TableCode> records = mapper.selectByExample() .where(id, isEqualTo(3)) .or(description, isLike("f%")) .build() .execute(); ... } public void complexWhere2 { ... // complex WHERE and ORDER BY List<TableCode> records = mapper.selectByExample() .where(id, isLessThan(10), and(description, isEqualTo("foo"))) .or(description, isLike("b%")) .orderBy(id.descending()) .build() .execute(); ... } }
此运行时中的“by example”方法比其他运行时中的“by example”方法灵活得多。请获取MyBatis Dynamic SQL的文档以了解有关可用选项的更多信息。