标签:resultset 重用 策略 header 命名 概念 依赖 role rac
参考:《JavaEE 互联网轻量级框架整合开发》-第 4 章
<configuration><!--配置-->
<properties></properties><!--属性-->
<settings></settings><!--设置-->
<typeAliases></typeAliases><!--类型命名-->
<typeHandlers></typeHandlers><!--类型处理器-->
<objectFactory></objectFactory><!--对象工厂-->
<plugins></plugins><!--插件-->
<environments><!--配置环境-->
<environment><!--环境变量-->
<transactionManager></transactionManager><!--事务管理器-->
<dataSource></dataSource><!--数据源-->
</environment>
</environments>
<databaseIdProvider></databaseIdProvider><!--数据库厂商标识-->
<mappers></mappers><!--映射器-->
</configuration>
注意:MyBatis配置项的顺序不能颠倒,不然启动阶段会发生异常,导致程序无法运行。
properties可以给系统配置一些运行参数,可以放在xml、properties文件中,而不是放在Java代码中,便于参数的修改维护。3种使用properties的方式:
如下,在property子元素中定义:
<properties>
···
<property name="database.username" value="root"></property>
<property name="database.password" value="root"></property>
</properties>
使用如下:
<dataSource>
···
<property name="username" value="${database.username}"></property>
<property name="username" value="${database.password}"></property>
</dataSource>
跟xml方式同理,只不过我们的配置写在properties文件中,然后通过<properties>
的属性resource来引入,同样可以以${xxx}的方式引用,如下所示:
①jdbc.properties
database.driver=com.mysql.jdbc.Driver
database.url=jdbc:mysql://localhost:3306/demo
database.username=root
database.password=123456
②引入
<properties resource="jabc.properties"></properties>
适用于数据库用户密码加密的形式。
在生产环境环境中,一般会把数据库的用户名和密码生成密文配置到properties中。我们需要从配置文件上读取到加密过的用户名和密码,然后通过解密程序(工具类)进行解密,重置到properties属性中,然后正常连接数据库。演示代码如下:
String resource = "mybatis-config.xml"
InputStream inputStream;
InputStream in = Resources.getResourceAsStream("jdbc.properties");
Properties props = new Properties();
props.load(in);//加载从xml文件读取到的properties配置
String username = props.getProperty("database.username");
String password = props.getProperty("database.password");
//解密用户名和密码并在属性中重置
props.put("database.username",CodeUtis.decode(username));
props.put("database.password",CodeUtis.decode(password));
inputStream = Resources.getResourceAsStream(resource);
//使用程序传递的方式覆盖原有的properties属性参数
SqlSessionFactory =new SqlSessionFactoryBuilder().build(inputStream,props);
mybatis最复杂的配置,影响mybatis的底层运行。一般默认即可,大部分情况下不需要配置,只需要修改常用规则即可,如自动映射、驼峰命名映射、联级规则、是否启动缓存、执行器类型等。
设置参数 | 描述 | 有效值 | 默认值 |
---|---|---|---|
cacheEnabled | 该配置影响的所有映射器中配置的缓存的全局开关 | true | false | true |
lazyLoadingEnabled | 延迟加载的全局开关。当开启时,所有关联对象都会延迟加载。 特定关联关系中可通过设置fetchType属性来覆盖该项的开关状态 | true | false | false |
aggressiveLazyLoading | 当启用时,对任意延迟属性的调用会使带有延迟加载属性的对象完整加载;反之,每种属性将会按需加载。 | true | false | true |
multipleResultSetsEnabled | 是否允许单一语句返回多结果集(需要兼容驱动)。 | true | false | true |
useColumnLabel | 使用列标签代替列名。不同的驱动在这方面会有不同的表现, 具体可参考相关驱动文档或通过测试这两种不同的模式来观察所用驱动的结果。 | true | false | true |
useGeneratedKeys | 允许 JDBC 支持自动生成主键,需要驱动兼容。 如果设置为 true 则这个设置强制使用自动生成主键,尽管一些驱动不能兼容但仍可正常工作(比如 Derby)。 | true | false | False |
autoMappingBehavior | 指定 MyBatis 应如何自动映射列到字段或属性。 NONE 表示取消自动映射;PARTIAL 只会自动映射没有定义嵌套结果集映射的结果集。 FULL 会自动映射任意复杂的结果集(无论是否嵌套)。 | NONE, PARTIAL, FULL | PARTIAL |
defaultExecutorType | 配置默认的执行器。SIMPLE 就是普通的执行器;REUSE 执行器会重用预处理语句(prepared statements); BATCH 执行器将重用语句并执行批量更新。 | SIMPLE REUSE BATCH | SIMPLE |
defaultStatementTimeout | 设置超时时间,它决定驱动等待数据库响应的秒数。 | Any positive integer | Not Set (null) |
defaultFetchSize | Sets the driver a hint as to control fetching size for return results. This parameter value can be override by a query setting. | Any positive integer | Not Set (null) |
safeRowBoundsEnabled | 允许在嵌套语句中使用分页(RowBounds)。 | true | false | False |
mapUnderscoreToCamelCase | 是否开启自动驼峰命名规则(camel case)映射,即从经典数据库列名 A_COLUMN 到经典 Java 属性名 aColumn 的类似映射。 | true | false | False |
localCacheScope | MyBatis 利用本地缓存机制(Local Cache)防止循环引用(circular references)和加速重复嵌套查询。 默认值为 SESSION,这种情况下会缓存一个会话中执行的所有查询。 若设置值为 STATEMENT,本地会话仅用在语句执行上,对相同 SqlSession 的不同调用将不会共享数据。 | SESSION | STATEMENT | SESSION |
jdbcTypeForNull | 当没有为参数提供特定的 JDBC 类型时,为空值指定 JDBC 类型。 某些驱动需要指定列的 JDBC 类型,多数情况直接用一般类型即可,比如 NULL、VARCHAR 或 OTHER。 | JdbcType enumeration. Most common are: NULL, VARCHAR and OTHER | OTHER |
lazyLoadTriggerMethods | 指定哪个对象的方法触发一次延迟加载。 | A method name list separated by commas | equals,clone,hashCode,toString |
defaultScriptingLanguage | 指定动态 SQL 生成的默认语言。 | A type alias or fully qualified class name. | org.apache.ibatis.scripting.xmltags.XMLDynamicLanguageDriver |
callSettersOnNulls | 指定当结果集中值为 null 的时候是否调用映射对象的 setter(map 对象时为 put)方法,这对于有 Map.keySet() 依赖或 null 值初始化的时候是有用的。注意基本类型(int、boolean等)是不能设置成 null 的。 | true | false | false |
logPrefix | 指定 MyBatis 增加到日志名称的前缀。 | Any String | Not set |
logImpl | 指定 MyBatis 所用日志的具体实现,未指定时将自动查找。 | SLF4J | LOG4J | LOG4J2 | JDK_LOGGING | COMMONS_LOGGING | STDOUT_LOGGING | NO_LOGGING | Not set |
proxyFactory | 指定 Mybatis 创建具有延迟加载能力的对象所用到的代理工具。 | CGLIB | JAVASSIST | JAVASSIST (MyBatis 3.3 or above) |
别名分为两类:①系统别名、②自定义别名;
注意:mybatis中别名不区分大小写
基本数据类型都,并且支持数组,如int
的别名_int
;以及他们的包装类,Long
的别名long
。另外,系统还定义了集合类型的别名,但是不支持相应类型的数组形式。
别名 | Java类型 | 是否支持数组 |
---|---|---|
_byte | byte | y |
_long | long | y |
_short | short | y |
_int | int | y |
_integer | int | y |
_double | double | y |
_float | float | y |
_boolean | boolean | y |
string | String | y |
byte | Byte | y |
long | Long | y |
short | Short | y |
int | Integer | y |
integer | Integer | y |
double | Double | y |
float | Float | y |
boolean | Boolean | y |
date | Date | y |
decimal | BigDecimal | y |
bigdecimal | BigDecimal | y |
object | Object | y |
map | Map | n |
hashmap | HashMap | n |
list | List | n |
arraylist | ArrayList | n |
collection | Collection | n |
iterator | Iterator | n |
ResultSet | ResultSet | n |
有时候需要用代码来实现注册别名:
public TypeAliasRegistry(){
registerAlias("string",String.class);
registerAlias("JDBC",JdbcTransactionFactory.class);
···
//使用系统类型,不要重复命名;包含类别如下:
/*
1.事务方式别名
2.数据源类型别名
3.缓存策略别名
4.数据库标识别名
5.语言驱动类别名
6.日志类别名
7.动态代理别名
*/
}
①直接配置:
<typeAliases>
<typeAlias alias="user" type="com.example.mybatis.domain.User"></typeAlias>
<typeAlias alias="role" type="com.example.mybatis.domain.Role"></typeAlias>
</typeAliases>
②包扫描的方式,会自动将包下的类名首字母转小写作为类名,如FileManagement --> fileMangement,包扫描配置如下:
<typeAliases>
<package name="com.example.file.domain"></package>
</typeAliases>
直接配置,还配置包扫描或者不同包有相同类名,怎么办?
可以再类名上加注解@Alias("user")
来区分,这样别名就是我们所注释的别名了。
在JDBC中,需要在PreparedStatement对象中设置那些已经预编译过的SQL语句的参数。执行SQL后,会通过ResultSet对象获取到数据库的数据,而这些是MyBatis根据数据的类型通过typeHandler来实现。
而typeHandler是对两者进行转换的,一般不需要我们去配置typeHandler、jdbcType、javaType。因为MyBatis会自动探测并使用相应类型的typeHandler。
public TypeHandlerRegistry() {
register(Boolean.class, new BooleanTypeHandler());
register(boolean.class, new BooleanTypeHandler());
register(JdbcType.BOOLEAN, new BooleanTypeHandler());
register(JdbcType.BIT, new BooleanTypeHandler());
...
}
由系统定义的类型转换器可知,我们自定义typeHandler需要实现TypeHandler接口或者继承BaseTypeHandler类。我们可以仿造一个StringTypeHandler:
public class MyTypeHandler implements TypeHandler<String>{
...
@Override
public xxx
...
}
那么接下来配置typeHandler(注册)
<typeHandlers>
<typeHandler jdbcType="VARCHAR" javaType="string" handler="com.example.mybatis.typehandler.MyTypeHandler"></typeHandler>
</typeHandlers>
配置完成后,系统就会读取,当jdbcType和javaType能与MyTypeHandler对应起来的时候,就启动MyTypeHandler。也可以显示启用typeHandler:
(1)
<resultMap id="roleMapper" type="user">
<result property="userName" column="user_name" jdbcType="VARCHAR" javaType="string"
</resultMap>
<select id="selectUser" parameterType="string" resultMap="roleMapper">
select * from user where user_name like concat('%', #{userName,jdbcType=VARCHAR,javaType=string},'%')
</select>
(2)
<resultMap id="roleMapper" type="user">
<result property="userName" column="user_name" typeHandler="com.example.mybatis.typehandler.MyTypeHandler"
</resultMap>
<select id="selectUser" parameterType="string" resultMap="roleMapper">
select * from user where user_name like concat('%', #{userName,typeHandler=com.example.mybatis.typehandler.MyTypeHandler},'%')
</select>
注意:要么指定与自定义typeHandler一致的jdbcType和javaType【如(1)】,要么直接typeHandler指定具体的实现类【如(2)】。
有时候枚举类型多,或者我们自定义的typeHandler很多的时候,采用配置也会很麻烦,我们可以采用包扫描的方式:
<typeHandlertype>
<package name="com.example.mybatis.typehandler" />
</typeHandlertype>
但是这样就没法指定jdbcType和javaType,不过我们可以用注解来处理,把MyTypeHandler的声明修改一下:
@MappedTypes(String.class)
@MappedjdbcTypes(jdbcType.VARCHAR)
public class MyTypeHandler implements TypeHandler<String>{
...
}
mybatis已经帮我们定义好了两个类作为枚举类型的支持:
我们先定义一个枚举类型,来查看查看两者区别:
/**
* @author BastetCat
* @data 2019/7/23 23:31
*/
public enum SexEnum {
MALE(1,"男"),
FEMALE(0,"女");
private int id;
private String name;
SexEnum(int id, String name) {
this.id = id;
this.name = name;
}
public SexEnum getSexById(int id){
for (SexEnum sex:SexEnum.values()){
if(sex.getId() == id){
return sex;
}
}
return null;
}
public int getId() {
return id;
}
public String getName() {
return name;
}
}
(1)EnumOrdinalTypeHandler是MyBatis根据枚举数组下标索引的方式进行匹配的,也是枚举的默认转换类,使用:
<resultMap id="userMapper" type="user">
<result property="sex" column="sex" typeHandler="org.apache.ibatis.type.EnumOrdinalTypeHandler"
</resultMap>
(2)EnumTypeHandler会把名称转换成对应的枚举,使用:
<resultMap id="userMapper" type="user">
<result property="sex" column="sex" typeHandler="org.apache.ibatis.type.EnumTypeHandler"
</resultMap>
对于上(1)来说数据库存放的是 1或0,而(2)中存放的MALE或FEMALE
自定义枚举:
@MappedTypes(SexEnum.class)
@MappedjdbcTypes(jdbcType.INTEGER)
public class MyTypeHandler implements TypeHandler<SexEnum>{
...
}
更多时候文件流的方式:BlobInputStreamTypeHandler
但是性能不佳,我们都会有单独的文件服务器。
用来创建结果集
自定义需要实现org.apache.ibatis.reflection.factory.ObjectFactory接口,然后配置:
<objectFactory type="xxx(ObjectFactory的实现类)">
<property name="xx" value="xx"></property>
</objectFactory>
略
<environment default="development">
<environment id="development">
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<property name="dirver" value="${database.driver}"></property>
<property name="url" value="${database.url}"></property>
<property name="username" value="${database.username}"></property>
<property name="password" value="${database.password}"></property>
</dataSource>
</environment>
</environment>
public interface Transaction{
Connection getConnection() throws SQLException;
void commit() throws SQLException;//提交
void rollback() throws SQLException;//回滚
void close() throws SQLException;//关闭
Integer getTimeout() throws SQLException;
}
它有两个实现类,分别是JdbcTransaction、ManagedTransaction,可以把事务管理器配置成为一下两种方式:
<!--使用JdbcTransactionFactory生成jdbcTransaction对象,以JDBC的方式对数据进行提交和回滚操作-->
<transactionManager type="JDBC" />
<!--ManagedTransactionFactory生成ManagedTransaction 不进行任何操作,把事务交给容器处理;closeConnection="false"来阻止默认关闭行为,从而让容器处理-->
<transactionManager type="MANAGED" closeConnection="false" />
自定义的话就是:
<transactionManager type="com.example.mybatis.transaction.MyTransaction" />
environment 的主要作用是配置数据库,在 MyBatis 中, 数据库通过 PooledDataSourceFactory 、UnpooledDataSourceFactory 和 JndiDataSourceF actory 三个工厂类来提供,前两着对应产生 PooledDataSource 、UnpooledDataSource 类对象,而 JndiDataSourceFactory 则会根据则DI 信息拿到外部容器实现的数据库连接对象。无论如何这 个工厂类,最后生成的产品都会是一个实现了 DataSource 接口的数据库连接对象。
<dataSource type="UNPOOLED">
<dataSource type= "POOLED">
<dataSource type= "JNDI" >
UNPOOLED
UNPOOLED 采用非数据库池的管理方式,每次请求都会打开 个新的数据库连接,所以创建会比较慢。在 些对性能没有很高要求的场合可以使用它。对有些数据库而言,使用连接池井不重要,那么它也是一个比较理想的选择。 POOLED 类型的数据源可以配置以下几种属性:
传递属性给数据库驱动也是 个可选项,注意属性的前缀为“ driver. ”,例如driver.e ncoding=UTF8 。它会通过 DriverManager.getConnection(url,driverProperties 方法传递值为 UTF8 的encoding 属性给数据库驱动。
POOLED
数据源 POOLED 利用“池”的概念将 JDBC Connection 对象组织起来 它开始会有一些空置,并且已经连接好的数据库连接,所以请求时 无须再建立和验证,省去了创建新的连接实例时所必需的初始化和认证时间。它还控制最大连接数,避免过多的连接导致系统瓶颈。
除了 UNPOOLED 下的属性外,会有更多属性用来配置 POOLED 的数据源:
poolPingQuery 为发送到数据库的侦 查询,用来检验连接是否 在正常工作秩序中,并准备接受请求。默认是“NO PING QUERY SET ”,这会导致多数数据库驱动失败时带有一个恰当的错误消息。
poolPingConnectionsNotUsedFor 为配置 poo!PingQuery 使用频度。这可以被设置成匹配具体的数据库连接超时时间,来避免不必要的侦测,默认值为 0(即所有连接每一时刻都被侦测一一仅 poolPingEnabled为true 适用)。
JNDI
数据源 JNDI的 实现是为了能在如 EJB 或应用服务器这类容器中使用 容器可以集中或在外部配置数据源,然后放置一 JNDI 上下文的引用 。这种数据源配置只需要两个属性:
databaseldProvider 元素主要是支持多种不同厂 的数据 。
<databaseidProvider type="DBVENDOR" >
<!--connection.getMetaData().getDatabaseProductName()获取数据库别名-->
<property name= "Oracle" value= "oracle" />
<property name= "MySQL" value = "mysql"/>
<property name= "DB2" value= "db2"/>
</databaseidProvider>
改造映射器SQL,标识一条SQL应用于那个数据库中:
<select id= "getRole" parameterType="long" resultType= "role" databaseId="oracle" >
select id, role_name as roleName, note from t_role where id = # {id}
</select>
<select id="getRole" parameterType="long" resultType="role" databaseId="mysql" >
select id,role_name as roleName , note from t_role where 1=1 and id = #{id}
</select>
<mappers>
<mapper resource="com/learn/ssm/chapter4/mapper/roleMapper.xml"/>
</mappers>
<mappers>
<package name="com.learn.ssm.chapter4.mapper"/>
</mappers>
<mappers>
<mapper class="com.learn.ssm.chapter4.mapper.UserMapper"/>
<mapper class="com.learn.ssm.chapter4.mapper.RoleMapper"/>
</mapper>
<mappers>
<mapper url="file:///var/mappers/com/learn/ssm/chapter4/mapper/roleMapper.xml" />
<mapper url="file:///var/mappers/com/learn/ssm/chapter4/mapper/RoleMapper.xml" />
</mappers >
标签:resultset 重用 策略 header 命名 概念 依赖 role rac
原文地址:https://www.cnblogs.com/nm666/p/11247815.html