mybatis基本使用以及加载配置文件学习总结

一:mybatis的使用

mybatis使用有2种方式:

1:老版本ibatis中直接使用sqlsession的api,具体如下

在这里插入图片描述
在这里插入图片描述
引入mybatis的pom坐标

<dependency>
  <groupId>org.mybatis</groupId>
  <artifactId>mybatis</artifactId>
  <version>x.x.x</version>
</dependency>

mybatis主要通过一个SqlSessionFactoryBulder,在解析mybatis的配置下,创建SqlSessionFactory,然后通过SqlSessionFactory创建SqlSqlssion来操作数据库

获取SqlSessionFactory(两种方式:使用xml和使用代码方式)

方式一:通过mybatisConfig.xml获取

创建mybatisConfig.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>

    <!-- 数据库连接信息配置 -->
    <properties resource="mybatis/mybatis.properties"></properties>

    <!--mybatis运行时的一些配置-->
    <settings>
        <setting name="" value=""/>
    </settings>

    <!-- 针对单个别名定义type:类型的路径 alias:别名 -->
    <!-- <typeAlias type="cn.itcast.mybatis.po.User" alias="user"/> -->
    <!-- 批量别名定义 指定包名,mybatis自动扫描包中的po类,自动定义别名,别名就是类名(类名小写)-->
    <!-- 别名定义 -->
    <typeAliases>
        <package name="com.test.model"/>
    </typeAliases>

    <environments default="${defaultActive}">
        <!--开发环境:事务处理器以及数据源-->
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="${driver}"/>
                <property name="url" value="${dev_url}"/>
                <property name="username" value="${dev_username}"/>
                <property name="password" value="${dev_password}"/>
            </dataSource>
        </environment>

        <!--测试环境-->
        <environment id="test">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="${driver}"/>
                <property name="url" value="${test_url}"/>
                <property name="username" value="${test_username}"/>
                <property name="password" value="${test_password}"/>
            </dataSource>
        </environment>
    </environments>

    <!--引入mapper.xml文件-->
    <mappers>
        <mapper resource="mybatis/mapper/testMapper.xml"/>
    </mappers>
</configuration>

testMapper.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="mybatis.mapper">
	<!--简单查询-->
	<select id="selectById"  resultType="com.test.model.User"
		parameterType="java.lang.String" >
	    select * from user where id = #{pid}
	</select>

</mapper>  

TestMybatis.java

        String resource = "mybatis/mybatisConfig.xml";
		InputStream inputStream = Resources.getResourceAsStream(resource);
		SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
		SqlSession session = sqlSessionFactory.openSession();
		String pid = "1";
		List<User> selectList = session.selectList("mybatis.mapper.selectById", pid);
		System.out.println(selectList.size());

2:面向接口编程,使用mapper

使用mapper接口,必须保证接口全类名和mapper.xml的namespace一样,方法名和mapper.xml中对应sql的id相同。
在这里插入图片描述
在这里插入图片描述

二:配置解析

mybatis的所有配置都会解析到Configuration类中。
在这里插入图片描述
mybatis的配置解析代码在SqlSessionFactoryBuilder的build方法。
在这里插入图片描述
重点显然在解析配置到Configuration过程。
parseConfiguration(parser.evalNode(“/configuration”));
在这里插入图片描述

1:properties

有3种方式配置

  1. property子元素:<properties> <property name="" value=""/> </properties>
  2. 配置文件(resource对应本地文件,url网络文件):<properties resource="jdbc.properties"/>
  3. XMLConfigBuilder构造方法参数传递配置

加载顺序:
首先加载property子元素,然后加载resource或者url指定的配置文件(key重名则覆盖),最后加载方法参数传递的属性(key重名则覆盖(方法参数传递:XMLConfigBuilder的构造方法private XMLConfigBuilder(XPathParser parser, String environment, Properties props)。

后加载的覆盖前面加载的,所以相同配置优先级。代码 > 配置文件 > property子元素

org.apache.ibatis.builder.xml.XMLConfigBuilder#propertiesElement

在这里插入图片描述

2:typeAliases:类型别名配置

在这里插入图片描述
在这里插入图片描述
如何设置别名?
typeAliasRegistry.registerAlias(clazz);
在这里插入图片描述在这里插入图片描述
typeAliasRegistry在Configuiration中。内部包含默认的一些别名。

3:plugins:插件配置

在这里插入图片描述
插件配置解析,实例化
在这里插入图片描述

4:settings:全局运行参数

在这里插入图片描述
都是一些键值对,在Configuration类中有对应字段保存。能够改变mybatis的运行行为
在这里插入图片描述
下面是setting的各个配置项说明
参考:https://www.cnblogs.com/LingCoder/p/9063730.html

5:environments:数据源和事务处理器

<environments default="development">
    <environment id="development">
        <!-- 配置事务处理器 -->
        <transactionManager type="JDBC" />
        <!-- 配置数据库连接信息 -->
        <dataSource type="POOLED">
            <property name="driver" value="${derby.driver}" />
            <property name="url" value="${derby.url}" />
            <property name="username" value="${derby.user}" />
            <property name="password" value="${derby.pwd}" />
        </dataSource>
    </environment>
</environments>

environment 的id唯一标识运行环境,environments的default指定默认运行环境。可以切换开发测试环境。
在这里插入图片描述

事务处理器怎么创建的呢?
在这里插入图片描述
在Configuration的构造器中设置别名,都是事务工厂的实现:
在这里插入图片描述
在这里插入图片描述
数据源又是怎么创建的呢?
在这里插入图片描述
在Configuration中的构造器设置的datasource别名,都是数据源工厂的实现:
在这里插入图片描述
在这里插入图片描述

6:mapper:映射器配置

<mappers>
     <!--<package name=""></package>-->
    <mapper resource="testMapper.xml"></mapper>
    <mapper resource="testMapper2.xml"></mapper>
</mappers>

有2种方式:

  1. 统一配置:package
  2. 单独配置:mapper

那么通过pakage配置,如何解析呢?
配置package的话,就是mapper接口所在的包名。并且对应的mapper.xml要和接口名同名,且在同一个包下。

加载后mapper存放在映射器注册器中:MapperRegistry (在Configuration中初始化),然后解析对应的mapper.xml

在这里插入图片描述

1. mapper开启二级缓存引用:cache-ref

在这里插入图片描述
配置完成后,在使用的时候,能根据Configuration中的namespace引用关系,拿到缓存引用的对象,进而引用其它映射器的缓存。

2.mapper开启二级缓存:cache

在这里插入图片描述
缓存配置解析逻辑:

private void cacheElement(XNode context) throws Exception {
    if (context != null) {
       // 如果自定义缓存实现,就需要指定type字段,否则使用默认实现(Configuration中指定:typeAliasRegistry.registerAlias("PERPETUAL", PerpetualCache.class);)
      String type = context.getStringAttribute("type", "PERPETUAL");
      Class<? extends Cache> typeClass = typeAliasRegistry.resolveAlias(type);
      // 确定缓存回收策略的实现
      String eviction = context.getStringAttribute("eviction", "LRU");
      Class<? extends Cache> evictionClass = typeAliasRegistry.resolveAlias(eviction);
      Long flushInterval = context.getLongAttribute("flushInterval");
      Integer size = context.getIntAttribute("size");
      boolean readWrite = !context.getBooleanAttribute("readOnly", false);
      boolean blocking = context.getBooleanAttribute("blocking", false);
      //读入额外的配置信息,易于第三方的缓存扩展,例:
//    <cache type="com.domain.something.MyCustomCache">
//      <property name="cacheFile" value="/tmp/my-custom-cache.tmp"/>
//    </cache>
      Properties props = context.getChildrenAsProperties();
      //调用builderAssistant.useNewCache
      builderAssistant.useNewCache(typeClass, evictionClass, flushInterval, size, readWrite, blocking, props);
    }
  }
  1. 确定缓存处理的实现类:
    默认使用:PERPETUAL (别名在Configuration配置)
    typeAliasRegistry.registerAlias(“PERPETUAL”, PerpetualCache.class);
  2. 后面分别确认cache的几个属性
  3. 关键部分:
    builderAssistant.useNewCache(typeClass, evictionClass, flushInterval, size, readWrite, blocking, props);

在这里插入图片描述

3. resultMap解析

这个元素很重要,此处简单了解,留待后面重点分析。

<resultMap id="trrr" type="txd.test.model.Blog">
  <id column="id" javaType="string" property="id"></id>
    <result column="author_id" javaType="string" property="authorId"></result>
    <result column="title" javaType="string" property="title"></result>
</resultMap>

相应解析逻辑:
在这里插入图片描述
以id子节点为例,看看如何解析?

 List<ResultFlag> flags = new ArrayList<ResultFlag>();
        if ("id".equals(resultChild.getName())) {
          flags.add(ResultFlag.ID);
        }
        //调5.1.1 buildResultMappingFromContext,得到ResultMapping
        resultMappings.add(buildResultMappingFromContext(resultChild, typeClass, flags));

跟进代码,其实就是把id子节点的各个属性解析出来。传入 ,通过构造者模式得到ResultMapping。所有节点解析完就是一个List,然后构建ResultMap。最后加入到Configuration中 (key是resultmap的id)
protected final Map<String, ResultMap> resultMaps = new StrictMap(“Result Maps collection”);

4.sql片段解析和select节点解析

在这里插入图片描述
首先放入XMLMapperBuilder的 Map<String, XNode> sqlFragments;中,具体解析是在select|insert|update|delete的解析过程中使用

那么select|insert|update|delete怎么解析的呢?
看一个简单例子:

<select id="selectById"  resultMap="trrr" >
    select * from BLOG where id = #{id}
</select>
  1. 首先是获取select节点的各种属性值,以下这些
    在这里插入图片描述
  2. 看一下缓存相关的
    boolean isSelect = sqlCommandType == SqlCommandType.SELECT;
    boolean flushCache = context.getBooleanAttribute(“flushCache”, !isSelect);
    //是否要缓存select结果
    boolean useCache = context.getBooleanAttribute(“useCache”, isSelect);

如果是select语句,默认是不清理缓存的,除非flushCache指定true(默认false)
而且select默认是使用缓存的,除非(useCache指定为false)

  1. sql片段应用
    参考一篇博客:https://my.oschina.net/zudajun/blog/687326

  2. sql解析
    最终解析成MappedStatement,此过程会用到SqlSource(动态sql解析),BoundSql
    具体参考网上的2篇博客:
    https://my.oschina.net/zudajun/blog/735553
    https://my.oschina.net/zudajun/blog/735731

三:参考博客

https://my.oschina.net/zudajun?tab=newest&catalogId=3532897

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值