一、Mybatis的核心配置文件详解
1、qlMapConfig.xml中配置的内容和顺序如下:
properties(属性)
settings(全局配置参数)
typeAliases(类型别名)
typeHandlers(类型处理器)
objectFactory(对象工厂)
plugins(插件)
environments(环境集合属性对象)
environment(环境子属性对象)
transactionManager(事务管理)
dataSource(数据源)
mappers(映射器)
【注意,这里既然明确规定了标签的书写顺序,如果你倒换了顺序就会报错哦】
2、properties属性:加载外部的文件,并且通过获取变量${xxx}的方式,得到其值。
举个例子来说,2.1 在src下创建一个jdbc.properties
<!--在这里写数据库配置信息-->
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8
username=root
password=
2.2 在核心配置文件mybatis-config.xml中,使用preperties标签,加载jdbc.properties文件
//这里要注意jdbc的路径,我放在src目录下,故可以直接加载改文件哦
<properties resource="jdbc.properties">
3.3 可以使用${ }获取配置文件的信息
//省略.........
<!-- 数据库连接池 -->
<dataSource type="POOLED">
<!--通过${driver}会把配置文件定义的driver的value值注入-->
<property name="driver" value="${driver}" />
<property name="url"
value="${url}" />
<property name="username" value="${username}" />
<property name="password" value="${password}" />
</dataSource>
//省略.........
3、settings属性:这是MyBatis中极为重要的调整设置,会改变MyBatis运行时的行为
<!--需要使用的可以参考一下的设置-->
<settings>
<!-- 该配置影响的所有映射器中配置的缓存的全局开关。默认值true -->
<setting name="cacheEnabled" value="true"/>
<!--延迟加载的全局开关。当开启时,所有关联对象都会延迟加载。 特定关联关系中可通过设置fetchType属性来覆盖该项的开关状态。默认值false -->
<setting name="lazyLoadingEnabled" value="true"/>
<!-- 是否允许单一语句返回多结果集(需要兼容驱动)。 默认值true -->
<setting name="multipleResultSetsEnabled" value="true"/>
<!-- 使用列标签代替列名。不同的驱动在这方面会有不同的表现, 具体可参考相关驱动文档或通过测试这两种不同的模式来观察所用驱动的结果。默认值true -->
<setting name="useColumnLabel" value="true"/>
<!-- 允许 JDBC 支持自动生成主键,需要驱动兼容。 如果设置为 true 则这个设置强制使用自动生成主键,尽管一些驱动不能兼容但仍可正常工作(比如 Derby)。 默认值false -->
<setting name="useGeneratedKeys" value="false"/>
<!-- 指定 MyBatis 应如何自动映射列到字段或属性。 NONE 表示取消自动映射;PARTIAL 只会自动映射没有定义嵌套结果集映射的结果集。 FULL 会自动映射任意复杂的结果集(无论是否嵌套)。 -->
<!-- 默认值PARTIAL -->
<setting name="autoMappingBehavior" value="PARTIAL"/>
<setting name="autoMappingUnknownColumnBehavior" value="WARNING"/>
<!-- 配置默认的执行器。SIMPLE 就是普通的执行器;REUSE 执行器会重用预处理语句(prepared statements); BATCH 执行器将重用语句并执行批量更新。默认SIMPLE -->
<setting name="defaultExecutorType" value="SIMPLE"/>
<!-- 设置超时时间,它决定驱动等待数据库响应的秒数。 -->
<setting name="defaultStatementTimeout" value="25"/>
<setting name="defaultFetchSize" value="100"/>
<!-- 允许在嵌套语句中使用分页(RowBounds)默认值False -->
<setting name="safeRowBoundsEnabled" value="false"/>
<!-- 是否开启自动驼峰命名规则(camel case)映射,即从经典数据库列名 A_COLUMN 到经典 Java 属性名 aColumn 的类似映射。 默认false -->
<setting name="mapUnderscoreToCamelCase" value="false"/>
<!-- MyBatis 利用本地缓存机制(Local Cache)防止循环引用(circular references)和加速重复嵌套查询。
默认值为 SESSION,这种情况下会缓存一个会话中执行的所有查询。
若设置值为 STATEMENT,本地会话仅用在语句执行上,对相同 SqlSession 的不同调用将不会共享数据。 -->
<setting name="localCacheScope" value="SESSION"/>
<!-- 当没有为参数提供特定的 JDBC 类型时,为空值指定 JDBC 类型。 某些驱动需要指定列的 JDBC 类型,多数情况直接用一般类型即可,比如 NULL、VARCHAR 或 OTHER。 -->
<setting name="jdbcTypeForNull" value="OTHER"/>
<!-- 指定哪个对象的方法触发一次延迟加载。 -->
<setting name="lazyLoadTriggerMethods" value="equals,clone,hashCode,toString"/>
</settings>
4、typeAliases类型别名:可以为Java类型设置一个短的名字,它只和XML配置有关,存在的意义就是减少类完全限定名的冗余
举个例子来说,4.1 、在上一篇文章中,插入数据的sql语句中,传入的参数类型是User。但是我们在写的时候,需要写全路径,才能映射到该podo
<!--上篇文章的代码,不懂回去看一下-->
<insert id="save" parameterType="dgut.xiaozheng.podo.User" useGeneratedKeys="true">
insert into tb_user(username,sex,age) values (#{username},#{sex},#{age})
</insert>
4.2、 此时dgut.xiaozheng.podo.User。名字太长了,可以给其取一个别名叫user
<typeAliases>
<typeAlias type="dgut.xiaozheng.podo.User" alias="user"/>
</typeAliases>
4.3、 然后我们就可以直接在sql的传入参数中,直接使用user
<insert id="save" parameterType="user" useGeneratedKeys="true">
insert into tb_user(username,sex,age) values (#{username},#{sex},#{age})
</insert>
4.4、这样直接写user就方便得多了。
4.5、mybatis提供的直接支持的简单数据类型的别名,无须自己配置
5、typeHandlers(类型处理器):很少用到,这里不讲
6、objectFactory(对象工厂):很少用到,这里不讲
7、plugins(插件):用到的话,我补充上来
8、environments:环境配置实际上就是数据源的配置。Mybatis可以配置多种环境,这种机制可以将SQL映射应用于多种数据库。
【尽管配置了多个环境,但是每个SqLSessionFactory只能选择实例一个环境,即每个数据库对应一个SqlSessionFactory。如果你想要连接两个数据库,就需要创建两个SqlSessionFactory】
<!-- 和spring整合后 environments配置将废除 -->
<environments default="development">
<environment id="development">
<!-- 使用jdbc事务管理 -->
<transactionManager type="JDBC" />
<!-- 数据库连接池 -->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver" />
<property name="url"
value="jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8" />
<property name="username" value="root" />
<property name="password" value="root" />
</dataSource>
</environment>
</environments>
//说明1:environments的defalue 和 environment的id值是可以任意定义的,
//但是:environment的id 一定要在default已经定义过的。这样子就是将每种数据库跟每种数据库的配置信息关联起来了
//命名尽量简洁有意义,易懂。例如development就挺好的
<environments default="development">
<environment id="development">
//下面省略.........
//说明:事务管理器transactionManager的配置,在myBatis中有JDBC和MANAGED两种
// JDBC:这个配置就是直接使用了JDBC的提交和回滚设置,它依赖于从数据源得到的连接来管理事物范围
// MANAGED:这个配置几乎不做什么,从来不提交,也不回滚。默认情况下它会关闭连接。
//....上面代码省略
//使用jdbc事务管理
<transactionManager type="JDBC" />
//....下面代码省略
<!--如果你使用的是MANAGED,而且在某些特殊的情况下你需要它不自动关闭连接。可以设置closeConnection为false,组织自动关闭。代码如下-->
<transactionManager type="MANAGED">
<property name="closeConnection" value="false">
</transactionManager>
//说明3 数据库连接池的type属性
//UNPOOLED:每次请求时打开连接和关闭连接,它对性能没什么要求的时候使用,但是实际很少使用
//POOLEN:采用“连接池”的方式去请求。符合我们的要求,挺好的
//JNDI:这个数据源的实现是为了能在EJB或者应用服务器这类的容器中使用
//数据库连接池
<dataSource type="POOLED">
//一下这四个是数据库连接信息必备的。就不累赘讲了
<property name="driver" value="com.mysql.jdbc.Driver" />
<property name="url"
value="jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8" />
<property name="username" value="root" />
<property name="password" value="root" />
</dataSource>
9、mappers(映射器):告诉核心配置文件到哪里去找映射文件
<!--<mapper resource=" " />-->
<!--使用相对于类路径的资源(现在的使用方式)-->
<mapper resource="sqlmap/User.xml" />
<!--<mapper class=" " />-->
<!--使用mapper接口类路径-->
<mapper class="cn.itcast.mybatis.mapper.UserMapper"/>
注意:此种方法要求mapper接口名称和mapper映射文件名称相同,且放在同一个目录中。
<!--<package name=""/>-->
<!--注册指定包下的所有mapper接口-->
如:<package name="cn.itcast.mybatis.mapper"/>
注意:此种方法要求mapper接口名称和mapper映射文件名称相同,且放在同一个目录中。
那么,我个人习惯的话,就是使用第一和第三种方式
二:映射文件Mapper XML映射配置
1、引入约束
<?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">
<!-- namespace:命名空间,用于隔离sql,还有一个很重要的作用,通过命名空间+sql的id去调用sql语句-->
<mapper namespace="user">
<!--主要是在这里写sql语句-->
</mapper>
2、在mapper中可以配置的属性有哪些?
select : 映射查询语句
insert: 映射插入语句
update:映射更新语句
delete:映射查询语句
sql:可被其他语句引用的可重用语句
cache:给命名空间的缓存配置(不用了)
cache-ref:其他命名空间缓存配置的引用(已经不用了)
resultMap:最复杂也是最强大的元素,用来描述如何从结果集中加载对象
parameterMap:已经废弃,老式风格的参数映射
3、select:用来映射查询语句
属性描述:
1)id:命名空间中唯一的标识符,可以来引用该条语句
2)parameterType:这里设置传入该条语句的参数类的完全限定名或者别名
3)resultType:返回结果的类的完全限定名或者别名
4)resultMap:外部resultMap的命名引用,结果集的映射是Mybatis最强大的特性
5)flushCache:如果设置为true,则任何时候该语句被条用,都会导致本地缓存和耳机缓存都被清空。默认是false
6)useCache:如果设置为true,将会导致本条语句的结果被二级缓存。默认是true
7)timeout:抛出异常之前,驱动程序等待数据库返回请求结果的秒数
8)……..除此之外还有6个左右,但是很少很少用到。我们只需要掌握上面的前四个就可以了、
//举个例子
//定义一个id叫sava的sql语句,传入参数为user,无传出参数。可通过命名空间user.save调用该语句
<insert id="save" parameterType="user">
insert into tb_user(username,sex,age) values (#{username},#{sex},#{age})
</insert>
测试案例:测试有点麻烦,请结合下一篇讲。因为测试需要用到SqlSessionFactory等类,这个还没有讲。可以浏览一下这一篇文章,里面的结论都是正确的。下一篇把测试案例全部补齐,也可以模范第一篇的测试案例
#{}表示一个占位符号,通过#{}可以实现preparedStatement向占位符中设置值,自动进行java类型和jdbc类型转换。
#{}可以有效防止sql注入。
#{}可以接收简单类型值或pojo属性值。 如果parameterType传输单个简单类型值,#{}括号中可以是value或其它名称。
4、insert:用来映射插入语句,属性跟select差不多,这里写个案例就可以了
<select id="selectUserById" parameterType="Integer" resultType="user">
select * from tb_user where id = #{id}
</select>
<!--这里返回值使用的是别名-->
<select id="selectUserByLikeName" parameterType="string" resultType="user">
select * from tb_user where username like #{like}
</select>
5、update:用来映射修改语句,属性跟select差不多,这里写个案例就可以了
<update id="updateUser" parameterType="user">
update tb_user set username = #{username},sex = #{sex},age = #{age} where id = #{id}
</update>
6、delete:用来映射删除语句,属性跟select差不多,这里写个案例就可以了
<delete id="deleteUserById" parameterType="int">
delete from tb_user where id = #{vvvv}
</delete>
6、sql:用来定义可重用的SQL片段,可以包含在其他语句中
几个例子来说,在查询的时候,经常会有select * from 语句,可以把这个语句抽取出来,定义成一个SQL片段
//例如这里把select * from 定义成 名字为 selectUser,在下面的查询语句中可以这样写
<sql id="selectUser">
select * from
</sql>
<select id="selectUserById" parameterType="Integer" resultType="user">
<include refid="selectUser"></include>
tb_user where id = #{id}
</select>
7、resultMap:是MyBatis中最大的元素,它的作用就是告诉MyBatis将从结果集中取出的数据转换成开发者所需要的对象
举个例子,比如我数据库中有一个字段叫id,而我的podo中写的是uid,这时候如果直接返回结果集,uid是null,因为在数据库中找不到映射的uid。这时候就可以使用resultMap自定义转化类型。当然更常见的例子就是多表查询,需要手动帮忙映射
/*
type:返回类型
id : 起个名字,等会可以被调用
*/
<resultMap type="user" id="MyUser">
<!--column 表示数据库的字段,id
property:表示podo的成员变量
意思是:把数据库的id映射到user中的uid字段上
-->
<id column="id" property="uid"/>
<result column="username" property="username"/>
</resultMap>
<select id="selectUserById" parameterType="Integer" resultMap="MyUser">
<include refid="selectUser"></include> tb_user where id = #{id}
</select>
【注意:】这里除了id跟uid不一样之外,其他都一样,故可以偷懒,其他属性不写,也是可以。但是在多表查询的情况,其他计算是一样的情况下,也是不能够省略的
8、cache,cache-ref,,parameterMap这些已经不用的标签就不讲了。
【总结:】那么从上面的配置来看,我们已经掌握了所有文件的配置。其实都不难,最总要的是要把握select语句的返回值!!后面总结。下一篇介绍一下Mybatis常用的类和方法,学完这个,综合这一篇,我们就能够去测试上述代码是否正确了。