企业🤖AI智能体构建引擎,智能编排和调试,一键部署,支持私有化部署方案 广告
[TOC] # 配置内容 SqlMapConfig.xml中配置的内容和顺序如下: * properties(属性) * settings(全局配置参数) * typeAliases(类型别名) * typeHandlers(类型处理器) * objectFactory(对象工厂) * plugins(插件) * environments(环境集合属性对象) * environment(环境子属性对象) * transactionManager(事务管理) * dataSource(数据源) * mappers(映射器) 每个标签都是个接口,允许对这些接口自定义处理 # databaseIdProvider 多数据库支持 ~~~ </environments> <!-- databaseIdProvider: 支持多数据库厂商, type="DB_VENDOR": VendorDatabaseIdProvider作用得到数据库厂商的标识(驱动getDatabaseProductName()), mybatis就能根据不同的数据厂商发送不同sql, 支持mysql, oracle, sqlServer, xxx --> <databaseIdProvider type="DB_VENDOR"> <!-- 为不同的数据库厂商起别名 --> <property name="MySQL" value="mysql"/> <property name="Oracle" value="oracle"/> <property name="SQL Server" value="sqlserver"/> </databaseIdProvider> ~~~ 在xml那 ~~~ <!-- 这个sql是在mysql环境下才使用的 --> <insert id="saveUser" parameterType="com.jdxia.domain.User" databaseId="mysql"> insert into user(username, address, sex, birthday) values (#{username}, #{address}, #{sex}, #{birthday}) </insert> <!-- 这个sql是在oracle环境下才使用的 --> <insert id="saveUser" parameterType="com.jdxia.domain.User" databaseId="oracle"> insert into user(username, address, sex, birthday) values (#{username}, #{address}, 1, #{birthday}) </insert> ~~~ sql语句databaseId属性应用这边的id **sql的支持** ~~~ <select id="findAll" resultType="com.jdxia.domain.User"> <if test="_databaseId=='mysql'"> select * from user limit 0, 5 </if> <if test="_databaseId=='oracle'"> select * from (select *, rownum as r1 from user where rownum &lt;=5) where r1 &gt;=1; </if> </select> ~~~ **匹配规则** 1. 如果没有配置databaseIdProvider标签,那么`databaseId=null` 2. 如果配置了databaseIdProvider标签,使用标签配置的name去匹配数据库信息, 匹配上设置databaseId=配置指定的值,否则依旧为 null 3. 如果databaseId不为null,他只会找到配置databaseId的sql语句 4. MyBatis 会加载不带 databaseId 属性和带有匹配当前数据库 databaseId 属性的所有语句。如果同时找到带有 databaseId 和不带 databaseId 的相同语句,则后者会被舍弃。 # properties(属性) SqlMapConfig.xml可以引用java属性文件中的配置信息如下 在src下定义jdbc.properties 配置文件内容如下: ~~~ jdbc.driver=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/app?characterEncoding=utf-8 jdbc.username=root jdbc.password=root ~~~ SqlMapConfig.xml引用如下: ![](https://box.kancloud.cn/50931051b56ad28bbff74f6f2f160d85_916x480.png) 也可以在properties中设置 ~~~ <properties resource="db.properties"> <property name="jdbc.password" value="123" /> </properties> ~~~ 注意: MyBatis 将按照下面的顺序来加载属性: * 在 properties 元素体内定义的属性首先被读取。 * 然后会读取properties 元素中resource或 url 加载的属性,它会覆盖已读取的同名属性 # environments指定环境 可以指定多个环境一键切换 ~~~ <!--配置环境--> <environments default="development"> <!-- 配置2个环境--> <environment id="test"> <!-- 配置事务 --> <transactionManager type="JDBC"/> <!--配置连接池--> <dataSource type="POOLED"> <property name="driver" value="${jdbc.driver}" /> <property name="url" value="${jdbc.url}" /> <property name="username" value="${jdbc.username}" /> <property name="password" value="${jdbc.password}" /> </dataSource> </environment> <environment id="development"> <!-- 配置事务 --> <transactionManager type="JDBC"/> <!--配置连接池--> <dataSource type="POOLED"> <property name="driver" value="${jdbc.driver}" /> <property name="url" value="${jdbc.url}" /> <property name="username" value="${jdbc.username}" /> <property name="password" value="${jdbc.password}" /> </dataSource> </environment> </environments> ~~~ 根据id来实例化出不同的 ~~~ //实例化Mysql Session工厂 mysqlSessionFactory=new SqlSessionFactoryBuilder().build(Resources.getResourceAsStream("mybatis/mybatis-config.xml")); //实例化SqlServer Session 工厂 sqlserverSessionFactory=new SqlSessionFactoryBuilder().build(Resources.getResourceAsStream("mybatis/mybatis-config.xml"), "test"); //实例化Oracle Session工厂 oracleSessionFactory=new SqlSessionFactoryBuilder().build(Resources.getResourceAsStream("mybatis/mybatis-config.xml"), "development"); ~~~ # seetings 用来配置MyBatis中的一些设置 http://www.mybatis.org/mybatis-3/zh/configuration.html#settings ~~~ <settings> <setting name="" value="true" /> </settings> ~~~ 关注这些 * lazyLoadingEnabled延迟加载的全局开关 * cacheEnabled缓存全局开关 * mapUnderscoreToCamelCase自动驼峰命名规则,数据库的A_COLUMN到java的aCloumn转换 * defaultStatementTimeout: 设置超时时间,决定驱动等待数据库响应的秒数 * autoMappingBehavior:默认是PRATIAL自动映射,要求列名和javaBean属性名一致.如果为null会取消自动映射 日志 ~~~ <!--开启日志打印--> <setting name="logImpl" value="STDOUT_LOGGING"/> ~~~ # typeAliases(类型别名) ## mybatis支持别名: 别名 映射的类型 ~~~ _byte byte _long long _short short _int int _integer int _double double _float float _boolean boolean string String byte Byte long Long short Short int Integer integer Integer double Double float Float boolean Boolean date Date decimal BigDecimal bigdecimal BigDecimal map Map ~~~ ## 自定义别名 在SqlMapConfig.xml中配置如下 typeAlias只能配置domain包中的别名,type属性是全路径类名,alias是别名.指定后不再区分大小写. ![](https://box.kancloud.cn/eb41634be1ad61fee7e9a536a4d5d213_896x357.png) package用于要指定配置别名的包,当指定后,该包下的**实体类**都会注册别名,并且类名就是别名,不再区分大小写 或者在类上面使用注解 ~~~ @Alias("user") public class User { ~~~ 然后在User.xml中 ~~~ <mapper namespace="mapper.UserMapper"> <select id="findUserById" parameterType="Integer" resultType="User"> select * from user where id = #{v} </select> </mapper> ~~~ ## 单个别名 使用typeAliases标签,定义别名;将cn.jdxia.mybatis.po.User 起别名为user; ~~~ <!-- 别名定义 --> <typeAliases> <!-- 针对单个别名定义 type:类型的路径 alias:别名 --> <typeAlias type="cn.jdxia.mybatis.po.User" alias="user"/> </typeAliases> ~~~ ## 批量别名 mybatis自动扫描包中的po类,自动定义别名,别名是类名(首字母大写或小写都可以,一般用小写) 例如:cn.jdxia.mybatis.po.User起别名为User或者user; ~~~ <!-- 别名定义 --> <typeAliases> <!-- 批量别名定义,指定包名,mybatis自动扫描包中的po类,自动定义别名,别名是类名(首字母大写或小写都可以,一般用小写) --> <package name="cn.jdxia.mybatis.po" /> </typeAliases> ~~~ # typeHandlers类型处理器 无论是MyBatis在预处理语句(PreparedStatement)中设置一个参数时,还是从结果集中取出一个值时,都会用类型处理器将获取的值以合适的方式转换为java类型 http://www.mybatis.org/mybatis-3/zh/configuration.html#typeHandlers 在3.4.1之前需要手动注册,现在不需要了 ![](https://box.kancloud.cn/5c9b55363fb036e9d1093fbba706e50d_780x347.png) ## 自定义类型处理器 每当mybatis设置参数到PreparedStatement或者从ResultSet结果集中取得值时,就会使用TypeHandler来处理数据库类型与java类型之间转换 我们可以重写类型处理器或创建自己的类型处理器来处理不支持的或非标准的类型 步骤 1. 实现org.apache.ibatis.type.TypeHandler接口或者继承org.apache.ibatis.type,BaseTypeHandler 2. 指定其映射某个JDBC类型(可选操作) 3. 在mybatis全局配置文件中注册 # 传递中文需要注意的 xml中是 ~~~ jdbc:mysql://127.0.0.1:3306/test_db?useUnicode=true&amp;characterEncoding=utf8 ~~~ 在xml写的时候,因为是在字符串里面,需要写`&amp;`表示`&`,但是在文件中应该是不用的,所以配置properties应为: ~~~ jdbc:mysql://127.0.0.1:3306/test_db?useUnicode=true&characterEncoding=utf8 ~~~ # mappers(映射器) Mapper配置的几种方法: ~~~ <mapper resource=" " /> ~~~ 使用相对于类路径的资源(现在的使用方式) ~~~ <mapper resource="sqlmap/User.xml" /> ~~~ --- ~~~ <mapper class=" " /> ~~~ 使用mapper接口类路径,不是指定xml文件了,是指定类 如: ~~~ <mapper class="mapper.UserMapper" /> ~~~ 注意:此种方法要求mapper接口名称和mapper映射文件名称相同,且放在同一个目录中。 在一个包下并且名字相同 --- 这个是指定**dao接口**所在包,当指定后就不需要在写mapper以及resource或者class了 ~~~ <package name="" /> ~~~ 注册指定包下的所有mapper接口 ~~~ <package name="mapper" /> ~~~ 注意:此种方法要求mapper接口名称和mapper映射文件名称相同,且放在同一个目录中。 意思就是包下扫描 # 连接池 连接池就是存储连接的一个容器. 容器其实就是一个集合对象,该集合必须是线程安全的,不能两个线程拿到同一连接. 该集合必须实现队列的特性:先进先出 mybatis提供了三种配置方式 **SqlMapConfig.xml里dataSource标签** type属性就是采用何种连接池方式 type属性取值: * POOLED: 传统的javax.sql.DataSource规范中的连接池 * UNPOOLED: 传统的获取连接方式,也实现了javax.sql.DataSource接口,但是没有实现池的思想 * JNDI: 采用服务器提供的JNDI技术实现,来获取DataSource对象,不同的服务器所能拿到的DataSource是不一样的,注意:如果不是web或者maven的war功能是不能使用的 * 自定义: 实现DataSourceFactory接口,定义数据源的获取方式 实际中使用spring管理数据源 POOLED和UNPOOLED的区别,看日志输出 POOLED,会还连接到池中 ~~~ Closing JDBC Connection [com.mysql.jdbc.JDBC4Connection@1a1d6a08] Returned connection 438135304 to pool. ~~~ UNPOOLED不会把连接还到池中 ~~~ Resetting autocommit to true on JDBC Connection [com.mysql.jdbc.JDBC4Connection@42f93a98] Closing JDBC Connection [com.mysql.jdbc.JDBC4Connection@42f93a98] ~~~ mybatis内部分别定义了java.sql.DataSource接口的UnpooledDataSource,PooledDataSource类来表示UNPOOLED,POOLED类型的数据源 ![](https://img.kancloud.cn/a1/fe/a1fe518ca0ebfb3fb4a5670705fccf27_1068x465.png) # 事务 **自动提交** ~~~ sqlSession.commit(); ~~~ 或者 ~~~ //默认是false factory.openSession(true); ~~~ # transactionManager type: `JDBC|MANAGED|自定义` * JDBC: 使用了jdbc的提交和回滚设置,依赖于从数据源得到的连接来管理事务范围jdbcTransactionFactory * MANAGED: 不提交或回滚一个连接,让容器来管理事务的整个生命周期(比如JEE应用服务器的上下文).ManagedTransactionFactory * 自定义: 实现TransactionFactory接口,type=全类名/别名