【Mybatis从0到1-007】深入MyBatis的配置文件
来源:互联网 发布:中药材产业大数据 编辑:程序博客网 时间:2024/06/03 23:48
根据前面学过的内容,可知,mybatis的持久化离不开sqlsessionfactory对象,这个对象是整个数据库映射关系经过编译后的内存镜像,该对象的openSession()方法可以打开SqlSession对象。该对象由SqlSessionFactoryBuilder加载mybatis的配置文件产生。再来回顾下之前的代码:
// mybatis配置文件String resource = "SqlMapConfig.xml";// 得到配置文件流InputStream inputStream = Resources.getResourceAsStream(resource);// 创建会话工厂,传入mybatis的配置文件信息SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);// 通过工厂得到SqlSessionSqlSession sqlSession = sqlSessionFactory.openSession();
上面这段代码的功能是根据配置文件SqlMapConfig.xml,创建SqlSessionFactory 对象,然后产生SqlSession对象,执行SQL语句。而mybatis的初始化就发生在第三句:SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
现在,来看下,这句代码到底发生了什么?MyBatis初始化的基本过程:
SqlSessionFactoryBuilder根据传入的数据流生成Configuration对象,然后根据Configuration对象创建默认的SqlSessionFactory实例。
初始化的基本过程如下所示:
简述初始化的过程:
1.调用SqlSessionFactoryBuilder对象的build(inputStream)方法;
2.SqlSessionFactoryBuilder会根据输入流inputStream等信息创建XMLConfiguration对象;
3.SqlSessionFactoryBuilder调用XMLConfiguration对象的parse()方法;
4.XMLConfiguration对象解析XML配置文件并返回Configuration对象;
5.SqlSessionFactoryBuilder根据Configuration对象创建一个DefaultSessionFactory对象;
6.SqlSessionFactoryBuilder返回DefaultSessionFactory对象给客户端,供客户端使用。
由此可见,SqlSessionFactory是根据mybatis的配置文件创建的。下面开始简单介绍全局配置文件SQLMapConfig.xml
配置内容如下:
properties(属性)
settings(全局配置参数)
typeAliases(类型别名)
typeHandlers(类型处理器)
objectFactory(对象工厂)
plugins(插件)
environments(环境集合属性对象)
environment(环境子属性对象)
transactionManager(事务管理)
dataSource(数据源)
mappers(映射器)
【1】properties(属性)
由xml文件内容可以发现,文件中存在很多硬编码,现在我们的需求如下:
将数据库连接参数单独配置在db.properties中(原因:方便对参数进行统一管理,其它xml可以引用该db.properties),只需要在SqlMapConfig.xml中加载db.properties的属性值。在SqlMapConfig.xml中就不需要对数据库连接参数硬编码。
下面,开始修改全局配置文件,创建文件db.properties(路径:src\main\resources\db.properties),添加内容如下:
jdbc.driver =com.mysql.jdbc.Driverjdbc.url = jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8jdbc.username = rootjdbc.password = 123
修改SqlMapConfig.xml文件,如下:
修改完成后,可以将上一章【Mybatis从0到1-006】mybatis开发DAO之基于mapper代理的测试程序再次运行下,看是否还能正常运行,测试结果表明,配置正确。
总结:
MyBatis 将按照下面的顺序来加载属性:
在 properties 元素体内定义的属性首先被读取。
然后会读取properties 元素中resource或 url 加载的属性,它会覆盖已读取的同名属性。
最后读取parameterType传递的属性,它会覆盖已读取的同名属性。所以这里可能就会存在一个问题:假如UserMapper.xml中的有一个statement的入参名为name,
<select id="findUserByUsername" parameterType="java.lang.String" resultType="po.User"> SELECT *FROM user WHERE username LIKE '%${name}%'</select>
而db.properties中也有一个参数名叫name。name = rootjdbc.password = 123
那最终UserMapper.xml中的select会读取到name=root,而不是用户传入的值。
建议:不要在properties元素体内添加任何属性值,只将属性值定义在properties文件中。在properties文件中定义属性名要有一定的特殊性,如:XXXXX.XXXXX.XXXX
【2】typeAliases(别名)
在mapper.xml中,定义了很多的statement,statement需要parameterType指定输入参数的类型、需要resultType指定输出结果的映射类型。
如果在指定类型时输入类型全路径,不方便进行开发,可以针对parameterType或resultType指定的类型定义一些别名,在mapper.xml中通过别名定义,方便开发。
mybatis有一些默认的别名,这里不再罗列,主要说一下自定义别名。类型别名是为了java类型设置的一些短的名字,它只和xml配置有关,存在的意义仅在于用来减少类完全限定名的冗余。
<typeAliases> <!--创建单个别名--> <typeAlias type="po.User" alias="user"></typeAlias></typeAliases>
这样配置时,user可以使用在任何使用po.User的地方。
<select id ="findUserById" parameterType="int" resultType="user"> SELECT *FROM user WHERE id=#{id}</select>
除此外,还可以批量定义别名(常用), 指定一个包名,mybatis会在包下面扫描需要的java bean。
<typeAliases> <!--创建单个别名--> <!--<typeAlias type="po.User" alias="usersong"></typeAlias>--> <!--批量别名--> <package name="po"/></typeAliases>
每一个在包po中的java bean,在没有注解的情况下,会使用Bean的首字母小写的非限定类名来作为它的别名。比如po.User的别名为user;若有注解的话,则它的别名为其注解值。@Alias("user")public class User {…………}
【3】mapper映射器
mybatis需要开发者自己书写SQL语句,mapper映射器正是告诉MyBatis到哪里去找映射文件(在SqlMapConfig.xml文件中修改),进而找到这些SQL语句。实际开发中,可以使用相对于类路径的资源引用或完全限定资源定位符(包括file:///的URL),以及类名和包名等。例如:
3.1 通过resource加载单个映射文件(我们之前开发的都是基于此加载方式)
<!-- 加载 映射文件 --><mappers> <!--<mapper resource="sqlmap/User.xml"/>--> <mapper resource="mapper/UserMapper.xml"/></mappers>
3.2 通过本地文件
<mappers> <mapper url="file:///C:/mapper/UserMapper.xml"/></mappers>
3.3 通过mapper接口加载单个映射文件(使用这种方法的前提是:使用的是mapper代理方法)
这种方法开发还需要遵循一些规范:需要将mapper接口类名和mapper.xml映射文件名称保持一致,且在同一个目录中!!!
<!-- 加载 映射文件 --><mappers> <!--<mapper resource="sqlmap/User.xml"/>--> <!--通过resource加载单个映射文件--> <!--<mapper resource="mapper/UserMapper.xml"/>--> <!--加载本地文件--> <!--<mapper url="file:///C:/mapper/UserMapper.xml"/>--> <!-- 通过mapper接口加载单个 映射文件 遵循一些规范:需要将mapper接口类名和mapper.xml映射文件名称保持一致,且在一个目录中 上边规范的前提是:使用的是mapper代理方法 --> <mapper class="mapper.UserMapper"/></mappers>
通过idea开发,在测试mapper接口过程中,出现了一个问题,就是当把resources\mapper文件夹下的UserMapper.xml文件移动到src\main\java\mapper后,两个文件虽在同一目录了,但是运行测试程序,报错。
出现这个问题的原因是idea中我将mapper类型默认是source类型,而xml文件在发布时不会编译,同时也不会发布到target中(所以在发布之后target目录中并没有xml,路径:target\classes\mapper\),导致项目运行时找不到mapper.xml文件。
然而,当只遵循部分规范(需要将mapper接口类名和mapper.xml映射文件名称保持一致),不遵循且在同一个目录中!!!,运行程序,居然没有报错,真的很奇怪!!
…………………………………………………………………………………………………………………………………………………………………………………………………………………………………………
对于这个问题,网友解释如下:
解决方案:
将UserMapper.xml文件提取到指定文件夹mapper中,设置mapper文件夹类型为resources,在SqlMapConfig.xml配置文件中添加图片中框选的代码对mapper文件进行扫描,问题解决。【这个问题在学习完Spring与mybatis结合之后将更容易解决。】
3.4 批量加载mapper(推荐使用)
批量加载与3.3所说的加载单个映射文件原理相似,只不过是一个用了class,一个用了package,这里先贴出代码。
<!-- 批量加载mapper指定mapper接口的包名,mybatis自动扫描包下边所有mapper接口进行加载遵循一些规范:需要将mapper接口类名和mapper.xml映射文件名称保持一致,且在一个目录 中上边规范的前提是:使用的是mapper代理方法 --><package name="mapper"/>
以上就是mybatis的配置文件的最主要内容。接下来章节将介绍输入映射、输出映射。
- 【Mybatis从0到1-007】深入MyBatis的配置文件
- [MyBatis]深入MyBatis的配置文件(二)
- 【Mybatis】从JDBC到Mybatis的改进
- MyBatis配置文件深入
- 【Mybatis从0到1-001】开篇
- 从 iBatis 到 MyBatis
- 从ibatis到mybatis
- 从 iBatis 到 MyBatis
- 从IBatis到MyBatis
- 从 iBatis 到 MyBatis
- 从 iBatis 到 MyBatis
- 从 iBatis 到 MyBatis
- 从 iBatis 到 MyBatis
- 从 iBatis 到 MyBatis
- 从jdbc到mybatis
- 从 iBatis 到 MyBatis
- Mybatis源码研究1:从JDBC到Mybatis
- Mybatis源码研究1:从JDBC到Mybatis
- 秒杀系统架构分析与实战 for java
- iptables firewalld
- VIM树形目录插件-NERDTree的安装与使用
- Struts2学习第四天:struts模块配置、默认Action、Action总结
- Callable和Future
- 【Mybatis从0到1-007】深入MyBatis的配置文件
- Android 注册媒体按键监听(MediaSession 兼容 Android 5.0+)
- random
- 轻松学JVM(四)——垃圾回收算法
- CC2541调试异常及解决方法
- HTTP相关的知识点
- java 内存流(ByteArrayInputStream,ByteArrayOutputStreaem)
- Linux
- 最短路径问题的概述