MyBatis 提供了基于数据库厂商标识(DatabaseIdProvider)来执行不同数据库的动态 SQL 功能,这对于需要支持多数据库的应用非常有用。
首先需要在 MyBatis 配置文件中配置数据库厂商标识:
<databaseIdProvider type="DB_VENDOR">
<property name="MySQL" value="mysql"/>
<property name="Oracle" value="oracle"/>
<property name="PostgreSQL" value="postgresql"/>
<property name="SQL Server" value="sqlserver"/>
</databaseIdProvider>
在 XML 映射文件中,可以使用 databaseId
属性来指定特定数据库的 SQL:
<select id="findUser" resultType="User">
<if test="_databaseId == 'mysql'">
SELECT * FROM users WHERE id = #{id}
</if>
<if test="_databaseId == 'oracle'">
SELECT * FROM users WHERE ROWID = #{id}
</if>
</select>
或者更简洁的方式:
<select id="findUser" resultType="User" databaseId="mysql">
SELECT * FROM users WHERE id = #{id}
</select>
<select id="findUser" resultType="User" databaseId="oracle">
SELECT * FROM users WHERE ROWID = #{id}
</select>
在动态 SQL 中,可以通过 _databaseId
变量来判断当前数据库:
<select id="findUsers" resultType="User">
SELECT * FROM users
<where>
<if test="name != null">
AND name like #{name}
</if>
<if test="_databaseId == 'oracle'">
AND ROWNUM <= 10
</if>
<if test="_databaseId == 'mysql'">
LIMIT 10
</if>
</where>
</select>
在注解方式中,可以使用 @SelectProvider
配合自定义的 SQL 提供类来实现:
public class UserSqlProvider {
public String findUser(Map<String, Object> params) {
String dbId = (String) params.get("_databaseId");
if ("mysql".equals(dbId)) {
return "SELECT * FROM users WHERE id = #{id}";
} else if ("oracle".equals(dbId)) {
return "SELECT * FROM users WHERE ROWID = #{id}";
}
return "SELECT * FROM users WHERE id = #{id}";
}
}
@SelectProvider(type = UserSqlProvider.class, method = "findUser")
User findUserById(Long id);
databaseId
的默认 SQL 语句通过合理使用数据库厂商标识,可以轻松实现多数据库支持,同时保持代码的整洁和可维护性。