在 mybatis 中配置文件次要分为两类,外围配置文件和映射配置文件。外围配置文件次要配置 mybatis 一些根底组件和加载资源,外围配置文件中的元素经常能影响 mybatis 的整个运行过程,比方节点中的内容; 映射配置文件次要配置了 sql 语句和类型转换相干的一些信息,也就是说映射文件领导着 MyBatis 如何进行数据库增删改查,映射配置文件通常和 Mapper 接口绝对应,当然采纳注解开发时候只有 Mapper 接口没有映射配置文件。
1、SqlMapConfig.xml 是 mybatis 的全局配置文件,配置内容如下:
- properties(属性)
settings(全局配置参数)typeAliases(类型别名)typeHandlers(类型处理器)objectFactory(对象工厂)plugins(插件)environments(环境汇合属性对象)–environment(环境子属性对象)—-transactionManager(事务管理)—-dataSource(数据源)mappers(映射器)
案例实操
- properties
==============
将数据库连贯参数独自配置在 db.properties 中,放在类门路下。这样只须要在 SqlMapConfig.xml 中加载 db.properties 的属性值。这样在 SqlMapConfig.xml 中就不须要对数据库连贯参数硬编码。
将数据库连贯参数只配置在 db.properties 中,起因:不便对参数进行对立治理,其它 xml 能够援用该 db.properties。
应用示例:
<property name="driver" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://127.0.0.1:3306/mybatis" />
<property name="username" value="root" />
<property name="password" value="root" />
其中的属性就能够在整个配置文件中应用来替换须要动静配置的属性值。比方:
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
如何配?
在 config.xml 文件中 <configuration> 引入子标签
<properties resource="jdbc.properties"></properties>
并批改原有数据源连贯相干配置如下:
<environments default="development">
<environment id="development">
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<property name="driver" value="${driver}" />
<property name="url" value="${url}" />
<property name="username" value="${username}" />
<property name="password" value="${password}" />
</dataSource>
</environment>
</environments>
即可实现。
- settings(理解)
================
mybatis 全局配置参数,全局参数将会影响 mybatis 的运行行为。比方:开启二级缓存、开启提早加载。具体可配置状况如下:
这是 MyBatis 批改操作运行过程细节的重要的步骤。下方这个表格形容了这些设置项、含意和默认值。个别咱们用默认即可(具体解释见官网文档)
对应 xml 配置如下(开发中个别采纳默认配置即可):
<settings>
<setting name="cacheEnabled" value="true"/>
<setting name="lazyLoadingEnabled" value="true"/>
<setting name="multipleResultSetsEnabled" value="true"/>
<setting name="useColumnLabel" value="true"/>
<setting name="useGeneratedKeys" value="false"/>
<setting name="autoMappingBehavior" value="PARTIAL"/>
<setting name="autoMappingUnknownColumnBehavior" value="WARNING"/>
<setting name="defaultExecutorType" value="SIMPLE"/>
<setting name="defaultStatementTimeout" value="25"/>
<setting name="defaultFetchSize" value="100"/>
<setting name="safeRowBoundsEnabled" value="false"/>
<setting name="mapUnderscoreToCamelCase" value="false"/>
<setting name="localCacheScope" value="SESSION"/>
<setting name="jdbcTypeForNull" value="OTHER"/>
<setting name="lazyLoadTriggerMethods" value="equals,clone,hashCode,toString"/>
</settings>
3.typeAliases
类型别名是为 Java 类型设置一个短的名字。它只和 XML 配置无关,存在的意义仅在于用来缩小类齐全限定名的冗余。例如:
Configuration 标签下增加
<typeAliases>
<typeAlias alias="customer" type="com.xxx.pojo.Customer" />
</typeAliases>
批改 CustomerMapper.xml 文件
<!-- 查问客户 -->
<select id="queryCustomerById" parameterType="int" resultType="customer">
SELECT id,user_name 'userName' FROM yg_customer WHERE id=#{id}
</select>
也能够指定一个包名(大家最喜爱的形式),MyBatis 会在包名上面搜寻须要的 Java Bean,比方:
<typeAliases>
<!-- <typeAlias alias="customer" type="com.xxx.pojo" /> -->
<package name="com.xxx.pojo"/>
</typeAliases>
每一个在包com.xxx.pojo 中的 Java Bean,在没有注解的状况下,会应用 Bean 的首字母小写的非限定类名来作为它的别名。比方 com.xxx.pojo.Customer 的别名为 customer;
若有注解,则别名为其注解值。注解名 @Alias(value=“user”)
同样 mybatis 曾经为咱们构建了相应的类型别名,它们都是大小写不敏感的,须要留神的是由根本类型名称反复导致的非凡解决。
别名映射的类型_byteByte_longLong_shortShort_intInt_integerInt_doubleDouble_floatFloat_booleanBooleanstringStringbyteBytelongLongshortShortintIntegerintegerIntegerdoubleDoublefloatFloatbooleanBooleandateDatedecimalBigDecimalbigdecimalBigDecimalobjectObjectmapMaphashmapHashMaplistListarraylistArrayListcollectionCollectioniteratorIterator
4.typeHandlers 类型处理器(面试有可能会问)
无论是 MyBatis 在预处理语句(PreparedStatement)中设置一个参数时,还是从后果集中取出一个值时,都会用类型处理器将获取的值以适合的形式转换成 Java 类型。下表形容了一些默认的类型处理器。
BooleanTypeHandlerjava.lang.Boolean, boolean 数据库兼容的 BOOLEANByteTypeHandlerjava.lang.Byte, byte 数据库兼容的 NUMERIC 或 BYTEShortTypeHandlerjava.lang.Short, short 数据库兼容的 NUMERIC 或 SHORT INTEGERIntegerTypeHandlerjava.lang.Integer, int 数据库兼容的 NUMERIC 或 INTEGERLongTypeHandlerjava.lang.Long, long 数据库兼容的 NUMERIC 或 LONG INTEGERFloatTypeHandlerjava.lang.Float, float 数据库兼容的 NUMERIC 或 FLOATDoubleTypeHandlerjava.lang.Double, double 数据库兼容的 NUMERIC 或 DOUBLEBigDecimalTypeHandlerjava.math.BigDecimal 数据库兼容的 NUMERIC 或 DECIMALStringTypeHandlerjava.lang.StringCHAR, VARCHARClobReaderTypeHandlerjava.io.Reader-ClobTypeHandlerjava.lang.StringCLOB, LONGVARCHARNStringTypeHandlerjava.lang.StringNVARCHAR, NCHARNClobTypeHandlerjava.lang.StringNCLOBBlobInputStreamTypeHandlerjava.io.InputStream-ByteArrayTypeHandlerbyte[]数据库兼容的字节流类型 BlobTypeHandlerbyte[]BLOB, LONGVARBINARYDateTypeHandlerjava.util.DateTIMESTAMPDateOnlyTypeHandlerjava.util.DateDATETimeOnlyTypeHandlerjava.util.DateTIMESqlTimestampTypeHandlerjava.sql.TimestampTIMESTAMPSqlDateTypeHandlerjava.sql.DateDATESqlTimeTypeHandlerjava.sql.TimeTIMEObjectTypeHandlerAnyOTHER 或未指定类型 EnumTypeHandlerEnumeration TypeVARCHAR- 任何兼容的字符串类型,存储枚举的名称(而不是索引)EnumOrdinalTypeHandlerEnumeration Type 任何兼容的 NUMERIC 或 DOUBLE 类型,存储枚举的索引(而不是名称)。
你能够重写类型处理器或创立你本人的类型处理器来解决不反对的或非规范的类型。具体做法为:实现 org.apache.ibatis.type.TypeHandler 接口,或继承一个很便当的类 org.apache.ibatis.type.BaseTypeHandler,而后能够选择性地将它映射到一个 JDBC 类型。
5. 对象工厂(objectFactory)(理解)
MyBatis 每次创立后果对象的新实例时,它都会应用一个对象工厂(ObjectFactory)实例来实现。默认的对象工厂须要做的仅仅是实例化指标类,要么通过默认构造方法,要么在参数映射存在的时候通过参数构造方法来实例化。默认状况下,咱们不须要配置,mybatis 会调用默认实现的 objectFactory。从这个类的内部看,这个类的次要作用就是依据一个类的类型失去该类的一个实体对象,比方,咱们给他一个 User 的 type,他将会给咱们一个 Tiger 的实体对象,咱们给他一个 java.lang.List 对象,他将会给咱们一个 List 的实体对象。相似于 spring 工厂实例化 bean
6. plugins 插件
MyBatis 容许你在已映射语句执行过程中的某一点进行拦挡调用。默认状况下,MyBatis 容许应用插件来拦挡的办法调用包含:
· Executor (sql 执行时, update, query, flushStatements, commit, rollback, getTransaction, close, isClosed)
· ParameterHandler (参数的解决, getParameterObject, setParameters)
· ResultSetHandler (后果集的解决, handleResultSets, handleOutputParameters)
· StatementHandler (申明语句的解决, prepare, parameterize, batch, update, query)
这些类中办法的细节能够通过查看每个办法的签名来发现,或者间接查看 MyBatis 的发行包中的源代码。假如你想做的不仅仅是监控办法的调用,那么你应该很好的理解正在重写的办法的行为。因为如果在试图批改或重写已有办法的行为的时候,你很可能在毁坏 MyBatis 的外围模块。这些都是更低层的类和办法,所以应用插件的时候要特地当心。
通过 MyBatis 提供的弱小机制,应用插件是非常简单的,只需实现 Interceptor 接口,并指定了想要拦挡的办法签名即可。
总配置增加
<!-- 插件 -->
<plugins>
<plugin interceptor="com.xxx.plugins.ExamplePlugin">
<property name="someProperty" value="100" />
</plugin>
</plugins>
插件 demo:
@Intercepts({
@Signature(
type=Executor.class,
/**
* 拦挡所有办法
*/
method="query",
/**
* 参数定义
*/
args={MappedStatement.class,Object.class,RowBounds.class,ResultHandler.class} )
})
public class ExamplePlugin implements Interceptor {
/**
* 每个插件必须实现以下三个办法
*/
/**
* Object intercept(Invocation invocation)是实现拦挡逻辑的中央,* 外部要通过 invocation.proceed()显式地推动责任链后退,也就是调用下一个拦截器拦挡指标办法。*/
public Object intercept(Invocation invocation) throws Throwable {System.out.println("intercept");
return invocation.proceed();}
/**
* Object plugin(Object target) 就是用以后这个拦截器生成对指标 target 的代理,* 理论是通过 Plugin.wrap(target,this) 来实现的,把指标 target 和拦截器 this 传给了包装函数。*/
public Object plugin(Object target) {return Plugin.wrap(target, this);
}
/**
* setProperties(Properties properties)用于设置额定的参数,参数配置在拦截器的 Properties 节点里。*/
public void setProperties(Properties properties) {System.out.println(properties.get("hello"));
}
}
- 配置环境(environments)(相熟 配多个数据源)
=================================
MyBatis 能够配置成适应多种环境,这种机制有助于将 SQL 映射利用于多种数据库之中,现实情况下有多种理由须要这么做。例如,开发、测试和生产环境须要有不同的配置;或者共享雷同 Schema 的多个生产数据库,想应用雷同的 SQL 映射。许多相似的用例。
不过要记住:只管能够配置多个环境,每个 SqlSessionFactory 实例只能抉择其一。
所以,如果你想连贯两个数据库,就须要创立两个 SqlSessionFactory 实例,每个数据库对应一个。而如果是三个数据库,就须要三个实例,依此类推,记起来很简略:
· 每个数据库对应一个 SqlSessionFactory 实例
<environments default="development">
<environment id="development">
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<property name="driver" value="${driver}" />
<property name="url" value="${url}" />
<property name="username" value="${username}" />
<property name="password" value="${password}" />
</dataSource>
</environment>
<environment id="test">
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<property name="driver" value="${driver2}" />
<property name="url" value="${url2}" />
<property name="username" value="${username2}" />
<property name="password" value="${password2}" />
</dataSource>
</environment>
</environments>
## development
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://127.0.0.1:3306/mybatis?useUnicode=true&characterEncoding=utf8
username=root
password=root
## test
driver2=com.mysql.jdbc.Driver
url2=jdbc:mysql://127.0.0.1:3306/mybatis2?useUnicode=true&characterEncoding=utf8
username2=root
password2=root
测试 sqlSessionFactory
public void test02() {
InputStream in;
try {in = Resources.getResourceAsStream(this.getClass().getClassLoader()
, "config.xml");
// 默认开发库
//SqlSessionFactory sqlSessionFactory= new SqlSessionFactoryBuilder().build(in); // 测试库
SqlSessionFactory sqlSessionFactory= new SqlSessionFactoryBuilder().build(in,"test");
UserDao userDao=new UserDaoImpl(sqlSessionFactory);
User user= userDao.queryUserById(1);
System.out.println(user);
} catch (IOException e) {e.printStackTrace();
}
}
- 事务管理器(transactionManager)(理解)
=================================
在 MyBatis 中有两种类型的事务管理器(也就 type=”[JDBC|MANAGED]”):
- JDBC – 这个配置就是间接应用了 JDBC 的提交和回滚设置,它依赖于从数据源失去的连贯来治理事务范畴。
- MANAGED – 这个配置简直没做什么。它从来不提交或回滚一个连贯,而是让容器来治理事务的整个生命周期。默认状况下它会敞开连贯,然而一些容器并不心愿这样,因而须要将 closeConnection 属性设置为 false 来阻止它默认的敞开行为。例如:
<transactionManager type="MANAGED">
<property name="closeConnection" value="false"/>
</transactionManager>
如果你正在应用 Spring + MyBatis,则没有必要配置事务管理器,因为 Spring 模块会应用自带的管理器来笼罩后面的配置。(集成时会讲到)
9.dataSource 数据源(理解)
dataSource 元素应用规范的 JDBC 数据源接口来配置 JDBC 连贯对象的资源。
数据源类型有三种:UNPOOLED,POOLED,JNDI
UNPOOLED
这个数据源的实现只是 每次被申请时关上和敞开连贯。尽管有一点慢,它对在及时可用连贯方面没有性能要求的简略应用程序是一个很好的抉择。不同的数据库在这方面体现也是不一样的,所以对某些数据库来说应用连接池并不重要,这个配置也是现实的。
- driver – 这是 JDBC 驱动的 Java 类的齐全限定名(并不是 JDBC 驱动中可能蕴含的数据源类)。
- url – 这是数据库的 JDBC URL 地址。
- username – 登录数据库的用户名。
- password – 登录数据库的明码。
- defaultTransactionIsolationLevel – 默认的连贯事务隔离级别。
作为可选项,你也能够传递属性给数据库驱动。要这样做,属性的前缀为“driver.”,例如:
- driver.encoding=UTF8
这将通过 DriverManager.getConnection(url,driverProperties)办法传递值为 UTF8 的 encoding 属性给数据库驱动。
POOLED
这种数据源的实现利用“池”的概念将 JDBC 连贯对象组织起来,防止了创立新的连贯实例时所必须的初始化和认证工夫。这是一种使得并发 Web 利用疾速响应申请的风行解决形式。(个别选用这种)
- poolMaximumActiveConnections – 在任意工夫能够存在的流动(也就是正在应用)连贯数量,默认值:10
- poolMaximumIdleConnections – 任意工夫可能存在的闲暇连接数。
- poolMaximumCheckoutTime – 在被强制返回之前,池中连贯被检出(checked out)工夫,默认值:20000 毫秒(即 20 秒)
- poolTimeToWait – 这是一个底层设置,如果获取连贯破费的相当长的工夫,它会给连接池打印状态日志并从新尝试获取一个连贯(防止在误配置的状况下始终宁静的失败),默认值:20000 毫秒(即 20 秒)。
- poolPingQuery – 发送到数据库的侦测查问,用来测验连贯是否处在失常工作秩序中并筹备承受申请。默认是“NO PING QUERY SET”,这会导致少数数据库驱动失败时带有一个失当的谬误音讯。
- poolPingEnabled – 是否启用侦测查问。若开启,也必须应用一个可执行的 SQL 语句设置 poolPingQuery 属性(最好是一个十分快的 SQL),默认值:false。
- poolPingConnectionsNotUsedFor – 配置 poolPingQuery 的应用频度。这能够被设置成匹配具体的数据库连贯超时工夫,来防止不必要的侦测,默认值:0(即所有连贯每一时刻都被侦测 — 当然仅当 poolPingEnabled 为 true 时实用)。
JNDI
这个数据源的实现是为了能在如 EJB 或应用服务器这类容器中应用,容器能够集中或在内部配置数据源,而后搁置一个 JNDI 上下文的援用。
- initial_context – 这个属性用来在 InitialContext 中寻找上下文(即 initialContext.lookup(initial_context))。这是个可选属性,如果疏忽,那么 data_source 属性将会间接从 InitialContext 中寻找。
- data_source – 这是援用数据源实例地位的上下文的门路。提供了 initial_context 配置时会在其返回的上下文中进行查找,没有提供时则间接在 InitialContext 中查找。和其余数据源配置相似,能够通过增加前缀“env.”间接把属性传递给初始上下文。比方:
- env.encoding=UTF8
这就会在初始上下文(InitialContext)实例化时往它的构造方法传递值为 UTF8 的 encoding 属性。
10.mappers 映射器(四种配置)(相熟)
这里是通知 mybatis 去哪寻找映射 SQL 的语句。能够应用类门路中的资源援用,或者应用字符,输出确切的 URL 援用。
!— sqlmapper 配置文件门路 -->
<mappers>
<mapper resource="org/mybatis/builder/AuthorMapper.xml"/>
<mapper resource="org/mybatis/builder/BlogMapper.xml"/>
<mapper resource="org/mybatis/builder/PostMapper.xml"/>
</mappers>
<!—url 绝对路径模式 -->
<mappers>
<mapper url="file:///var/mappers/AuthorMapper.xml"/>
<mapper url="file:///var/mappers/BlogMapper.xml"/>
<mapper url="file:///var/mappers/PostMapper.xml"/>
</mappers>
<!—接口 列表配置模式 注解 sql-->
<mappers>
<mapper class="org.mybatis.builder.AuthorMapper"/>
<mapper class="org.mybatis.builder.BlogMapper"/>
<mapper class="org.mybatis.builder.PostMapper"/>
</mappers>
<!—映射包下所有接口 -->
<mappers>
<package name="org.mybatis.builder"/>
</mappers>
这些配置会通知了 MyBatis 去哪里找映射文件,剩下的细节就应该是每个 SQL 映射文件。
扩大
封装 Dao
1 新建接口 CustomerDao
接口定义:
public interface CustomerDao {Customer queryCustomerByName(String userName);
}
2 xml 映射文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.xxx.dao.CustomerDao">
<!-- 查问客户 -->
<select id="queryCustomerByName" parameterType="string" resultType="com.xxx.pojo.Customer">
SELECT id,user_name 'userName',user_balance 'userBalance' FROM yg_customer WHERE user_name=#{userName}
</select>
</mapper>
3 mappers 映射器配置
<mappers>
<!-- <mapper resource="com/xxx/mapper/CustomerDao.xml" />-->
<package name="com.xxx.dao"/>
</mappers>
4 测试
public class App {public static void main( String[] args ) throws IOException {
//1 加载配置文件
InputStream is = Resources.getResourceAsStream("mybatis.xml");
//2 创立 sqlsessionfactor 工厂
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);
//3 构建数据库会话
SqlSession session = factory.openSession();
/* Customer customer = session.selectOne("com.xxx.mapper.customerMapper.queryCustomerById", 2);
System.out.println(customer);*/
CustomerDao customerDao = session.getMapper(CustomerDao.class);
Customer customer = customerDao.queryCustomerByName("zhaoliying");
System.out.println(customer);
session.close();}
}