構成プロパティを定義する、プロパティが参照され、設定ファイル全体の他の場所に配置することができます
<プロパティリソース= "db.properties"> </プロパティ>
指定MyBatisの構成プロパティを設定するいくつかのグローバル設定、実行時の動作変更MyBatisの
<設定> <! -この設定は、グローバルマッパーを有効または無効にできますキャッシュ- > <設定名=値=「trueに」/「cacheEnabled」> <! -グローバル遅延ロードを有効または無効にします。無効にした場合、すべてのオブジェクトは、リアルタイムの負荷に関連付けられている- > <設定名=「lazyLoadingEnabled」値=「trueに」/> <! -結果セットは単一のステートメントからのより多くの(互換性の返却を許可または禁止ドライバ) - > 「真の」<設定名=「multipleResultSetsEnabled」値= /> <! -代わりに、列名を使用して、カラムのタグ。これは、異なる別のドライブの振る舞いに便利です。リファレンステストドキュメント、またはドライブを決定するために使用される二つの方法を運転- > <設定名=「trueに」「useColumnLabel」値= /> <! - JDBCのサポートが可能に生成された鍵を。互換性のあるドライバ。設定した場合、真この設定軍生成されたキーが使用されている、いくつかのドライバが(例えば、互換性が、まだ有効拒否した ダービー) - > <! -アクチュエータのデフォルトの設定。SIMPLEアクチュエータ何も特別な。プリペアドステートメントの再利用REUSEアクチュエータ。文とバッチ更新を再利用BATCHアクチュエータ- > <設定名= "defaultExecutorType"値= "SIMPLE" /> <! -设置超时时间、它决定驱动等待一个数据库响应的时间- > <設定名= "defaultStatementTimeout"値= "100" /> <設定名=値= "偽" / "safeRowBoundsEnabled"> <設定名= "mapUnderscoreToCamelCase"値= "偽" /> <設定名= "localCacheScope"値= "SESSION" /> <設定名= "jdbcTypeForNull"値を= "その他" /> <設定名= "lazyLoadTriggerMethods"値= "イコール、クローン、のhashCode、のtoString" /> </設定>
Java型の設定、などtypeAliasesエイリアス、別名ときの別名に使いやすいマップ、およびカスタムシステムエイリアス
<typeAliases> <typeAlias別名= "著者"タイプ= "domain.blog.Author" /> <typeAlias別名= "ブログ"タイプ= "domain.blog.Blog" /> <typeAlias別名= "コメント"タイプ= "ドメイン.blog.Comment "/> </ typeAliases>
また、MyBatisの下のパッケージ名でのJava Beanオブジェクトは、ニーズを検索する、パッケージ名を指定することができます。
<typeAliases> <! -指定された走査型パッケージの下にあるすべてのエンティティ- > <パッケージ名= "com.gw.facade.account.entity" /> <パッケージ名= "com.gw.facade.account.vo" /> </ typeAliases>
typeHandlers jdbcTypeとのJavaType切り替えます
プロセッサの種類 | Java型 | JDBCタイプ |
---|---|---|
BooleanTypeHandler | java.lang.Booleanの、 ブール | データベースの互換性 BOOLEAN |
Byte型のハンドラ | がjava.lang.Byte、 交換 | データベースの互換性 NUMERIC または BYTE |
ShortTypeHandler | java.lang.Shortの、 短いです | データベースの互換性 NUMERIC または SHORT INTEGER |
IntegerTypeHandler | java.lang.Integerの、 int型 | データベースの互換性 NUMERIC または INTEGER |
LongTypeHandler | java.lang.Longの、 ドラゴン | データベースの互換性 NUMERIC または LONG INTEGER |
FloatTypeHandler | java.lang.Floatの、 フロート | データベースの互換性 NUMERIC または FLOAT |
DoubleTypeHandler | java.lang.Doubleの、 ダブル | データベースの互換性 NUMERIC または DOUBLE |
BigDecimalTypeHandler | java.math.BigDecimalの | データベースの互換性 NUMERIC または DECIMAL |
StringTypeHandler | java.lang.Stringで | CHAR、 VARCHAR |
ClobReaderTypeHandler | するjava.io.Reader | - |
ClobTypeHandler | java.lang.Stringで | CLOB、 LONGVARCHAR |
NStringTypeHandler | java.lang.Stringで | NVARCHAR、 NCHAR |
NClobTypeHandler | java.lang.Stringで | NCLOB |
BlobInputStreamTypeHandler | java.io.InputStreamを | - |
ByteArrayTypeHandler | バイト[] | バイトストリームタイプは、データベースと互換性があります |
BlobTypeHandler | バイト[] | BLOB、 LONGVARBINARY |
日付を入力ハンドラ | java.util.Date | TIMESTAMP |
DateOnlyTypeHandler | java.util.Date | 日付 |
TimeOnlyTypeHandler | java.util.Date | 時間 |
SqlTimestampTypeHandler | java.sql.Timestamp | TIMESTAMP |
SqlDateTypeHandler | java.sql.Date | 日付 |
SqlTimeTypeHandler | たjava.sql.Time | 時間 |
ObjectTypeHandler | どれか | 他の 不特定のタイプ |
EnumTypeHandler | 列挙型 | VARCHAR - 任意の文字列互換タイプ、ストレージ列挙(ないインデックス)の名前 |
EnumOrdinalTypeHandler | 列挙型 | 任意の適合性 NUMERIC または DOUBLE (名前ではなく)列挙格納されたインデックスの種類、。 |
InstantTypeHandler | java.time.Instant | TIMESTAMP |
localdatetimetypehand上 | java.time.LocalDateTime | TIMESTAMP |
localdatetypehand上 | java.time.LocalDate | 日付 |
LocalTimeTypeHandler | java.time.LocalTime | 時間 |
OffsetDateTimeTypeHandler | java.time.OffsetDateTime | TIMESTAMP |
OffsetTimeTypeHandler | java.time.OffsetTime | 時間 |
ZonedDateTimeTypeHandler | java.time.ZonedDateTime | TIMESTAMP |
YearTypeHandler | java.time.Year | 整数 |
MonthTypeHandler | java.time.Month | 整数 |
YearMonthTypeHandler | java.time.YearMonth | VARCHAR または LONGVARCHAR |
JapaneseDateTypeHandler | java.time.chrono.JapaneseDate | 日付 |
可以重写类型处理器或创建你自己的类型处理器来处理不支持的或非标准的类型。 具体做法为:实现 org.apache.ibatis.type.TypeHandler 接口, 或继承一个很便利的类 org.apache.ibatis.type.BaseTypeHandler, 然后可以选择性地将它映射到一个 JDBC 类型。
@MappedTypes(Boolean.class) @MappedJdbcTypes(JdbcType.SMALLINT) public class BooleanTypeHandler implements TypeHandler<Boolean>{ public Object getResult(ResultSet arg0, int arg1) throws SQLException { int num = arg0.getInt(arg1); Boolean rt = Boolean.FALSE; if (num == 1){ rt = Boolean.TRUE; } return rt; } public Object getResult(ResultSet arg0, String arg1) throws SQLException { int num = arg0.getInt(arg1); Boolean rt = Boolean.FALSE; if (num == 1){ rt = Boolean.TRUE; } return rt; } public Object getResult(CallableStatement arg0, int arg1) throws SQLException { Boolean b = arg0.getBoolean(arg1); return b == true ? 1 : 0; } public void setParameter(PreparedStatement arg0, int arg1, Boolean arg2,JdbcType arg3) throws SQLException { Boolean b = (Boolean) arg2; int value = (Boolean) b == true ? 1 : 0; arg0.setInt(arg1, value); } }
上面代码中可以按照我们的要求将java的Boolean和jdbc的SMALLINT进行转换,对于这两种数据类型的声明有两种方式:一种是如上在类加上注解进行声明;另外也可以在typeHandler类声明中说明,如下图。
<typeHandlers> <typeHandler javaType="Boolean" jdbcType="SMALLINT" handler="com.gw.common.core.mybatis.BooleanTypeHandler" /> </typeHandlers>
objectFactory mybatis每次创建结果对象的新实例时,它都会使用对象工厂模式去构建pojo
在 MyBatis 中,当其 sql 映射配置文件中的 sql 语句所得到的查询结果,被动态映射到 resultType 或其他处理结果集的参数配置对应的 Java 类型,其中就有 JavaBean 等封装类。而 objectFactory 对象工厂就是用来创建实体对象的类。
在 MyBatis 中,默认的 objectFactory 要做的就是实例化查询结果对应的目标类,有两种方式可以将查询结果的值映射到对应的目标类,一种是通过目标类的默认构造方法,另外一种就是通过目标类的有参构造方法。
有时候在 new 一个新对象(构造方法或者有参构造方法),在得到对象之前需要处理一些逻辑,或者在执行该类的有参构造方法时,在传入参数之前,要对参数进行一些处理,这时就可以创建自己的 objectFactory 来加载该类型的对象。
在这个类中有6个方法:
1⃣️create(Class<T> type):这个方法我认为是创建结果集的方法,但它其实是直接调用了第二个create方法,只不过后两个参数传的是null,所以直接看下面的方法;
2⃣️create(Class<T> type, List<Class<?>> constructorArgTypes, List<Object> constructorArgs):这个方法中传了三个参数,分别应该是返回的结果集类型、此类构造函数参数类型、此类构造函数参数值。从它的内部实现来看,首先调用了下面的resolveInterface方法获取返回类型,其次调用instantiateClass方法实例化出我们所需的结果集;
3⃣️setProperties(Properties properties):这个方法是用来设置一些配置信息,比如我们给objectFactory定义一个property子元素时,就是通过这个方法进行配置的;
4⃣️instantiateClass(Class<T> type, List<Class<?>> constructorArgTypes, List<Object> constructorArgs):此方法是用来实例化一个类,需要实例化的类型是通过下面的resolveInterface方法决定,从内部实现来看,这个实例化过程是通过反射实现的;
5⃣️resolveInterface(Class<?> type):此方法是用来对集合类型进行处理,即如果我们定义一个resultType为集合类型,那么它就会根据这个类型决定出即将创建的结果集类型;
6⃣️isCollection(Class<T> type):这个方法是用来判断我们配置的类型是不是一个集合。比如如果返回多条数据,但是我们配置resultType是个普通类,那么在执行过程中就会报错;
以上就是MyBatis默认objectFactory中的具体实现,通过它来创建我们配置的结果集,一般情况下都会使用默认的对象工厂,但是我们也可以自定义一个,只要继承DefaultObjectFactory.java即可。
plugins 插件 mybatis 允许在已映射的语句执行过程中的某一点进行拦截调用
- Executor (update, query, flushStatements, commit, rollback, getTransaction, close, isClosed)
- ParameterHandler (getParameterObject, setParameters)
- ResultSetHandler (handleResultSets, handleOutputParameters)
- StatementHandler (prepare, parameterize, batch, update, query)
只需实现Interceptor接口同时指明需要拦截的方法签名,并在mybatis的配置文件中声明该签名:
@Intercepts({ @Signature (type = Executor.class, method = "query", args = { MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class } ) }) public class ExecutorInterceptor extends AbstractInterceptor { public Object intercept(Invocation invocation) throws Throwable { return invocation.proceed(); } public Object plugin(Object target) { return Plugin.wrap(target, this); } public void setProperties(Properties properties) { } }
<!-- mybatis-config.xml配置 --> <plugins> <plugin interceptor="com.gw.common.core.mybatis.interceptor.ExecutorInterceptor"> </plugin> </plugins>
mappers 配置引入映射器的方法 可以使用相对路径的资源引用 或完全限定资源定位符(包括file://URL) 或类名和包名等
<mappers>
<!--直接映射到相应的mapper文件 -->
<mapper resource="mapper/userMapper.xml"/>
<!--通过类扫描mapper文件-->
<mapper class="cn.qin.mapper.userMapper"/>
<!--扫描包下所有的mapper文件-->
<package name="cn.qin.mapper"/>
</mappers>
environments 用于配置多个数据源 ,每个数据源分为数据库源和事务的配置
<configuration>
<!--引入外部资源 -->
<properties resource="./mybatis-mysql.properties">
</properties>
<settings>
<setting name="cacheEnabled" value="true"/>
</settings>
<objectFactory type="com.zzz.mybatis.object.MyObjectFacotry">
<property name="env" value="test"/>
</objectFactory>
<!--设置默认的环境为开发环境 -->
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="UNPOOLED">
<property name="driver" value="${dev.driver}"/>
<property name="url" value="${dev.url}"/>
<property name="username" value="${dev.username}"/>
<property name="password" value="${dev.password}"/>
</dataSource>
</environment>
<!--测试环境用 -->
<environment id="test">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${test.driver}"/>
<property name="url" value="${test.url}"/>
<property name="username" value="${test.username}"/>
<property name="password" value="${test.password}"/>
</dataSource>
</environment>
<!--生产环境用 -->
<environment id="prod">
<transactionManager type="MANAGED"/>
<dataSource type="JDBC">
<property name="driver" value="${prod.driver}"/>
<property name="url" value="${prod.url}"/>
<property name="username" value="${prod.username}"/>
<property name="password" value="${prod.password}"/>
</dataSource>
</environment>
</environments>
</configuration>
databaseldProvider 根据不同数据库厂商执行不同的语句,用于一个系统内多个厂商数据源支持
<databaseIdProvider type="DB_VENDOR"> <property name="MySQL" value="mysql" /> <property name="Oracle" value="oracle" /> </databaseIdProvider>
<select id="SelectTime" resultType="String" databaseId="mysql"> SELECT NOW() FROM dual </select> <select id="SelectTime" resultType="String" databaseId="oracle"> SELECT 'oralce'||to_char(sysdate,'yyyy-mm-dd hh24:mi:ss') FROM dual </select>