mybatis学习

基础组件

SqlSessionFactory

初始化

SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
绑定配置文件初始化sqlSessionFactory
XMLConfigBuilder parser = new XMLConfigBuilder(inputStream, environment, properties);
实例化 xml 文件解析类
parser.parse();使用该方法解析标签,返回Configuration
最终
return new DefaultSqlSessionFactory(config);
自此SqlSessionFactory 初始化结束

SqlSession

初始化

SqlSession sqlsession = sqlSessionFactory.openSession();
//Environment 类,包含数据源以及事务工厂
final Environment environment = configuration.getEnvironment();
final TransactionFactory transactionFactory = getTransactionFactoryFromEnvironment(environment);
//工厂模式初始化事务类,包含 数据源,隔离级别,自动提交
tx = transactionFactory.newTransaction(environment.getDataSource(), level, autoCommit);
//初始化执行器   
final Executor executor = configuration.newExecutor(tx, execType);
主要分为3类
if (ExecutorType.BATCH == executorType) {
  executor = new BatchExecutor(this, transaction);
} else if (ExecutorType.REUSE == executorType) {
  executor = new ReuseExecutor(this, transaction);
} else {
  executor = new SimpleExecutor(this, transaction);
}
//将拦截器链加入到执行器
executor = (Executor) interceptorChain.pluginAll(executor);
//返回sqlsession
 return new DefaultSqlSession(configuration, executor, autoCommit);

<T>Mapper

//获取mapper代理类
drawMapper = sqlsession.getMapper(DrawMapper.class);
public <T> T getMapper(Class<T> type) {
  return configuration.<T>getMapper(type, this);
}
public <T> T getMapper(Class<T> type, SqlSession sqlSession) {
  return mapperRegistry.getMapper(type, sqlSession);
}
final MapperProxyFactory<T> mapperProxyFactory = (MapperProxyFactory<T>) knownMappers.get(type);
return mapperProxyFactory.newInstance(sqlSession);
final MapperProxy<T> mapperProxy = new MapperProxy<T>(sqlSession, mapperInterface, methodCache);
最终返回代理类
return (T) Proxy.newProxyInstance(mapperInterface.getClassLoader(), new Class[] { mapperInterface }, mapperProxy);
该代理方式为jdbc 动态代理,代理增强逻辑为mapperProxy
调用mapper接口会直接路由到mapperProxy中的invoke函数中

public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
  try {
    if (Object.class.equals(method.getDeclaringClass())) {
      return method.invoke(this, args);
    } else if (isDefaultMethod(method)) {
      return invokeDefaultMethod(proxy, method, args);
    }
  } catch (Throwable t) {
    throw ExceptionUtil.unwrapThrowable(t);
  }
  final MapperMethod mapperMethod = cachedMapperMethod(method);
  return mapperMethod.execute(sqlSession, args);
}
最终进入jdbc 或者数据库连接池
public int update(Statement statement) throws SQLException {
  PreparedStatement ps = (PreparedStatement) statement;
  ps.execute();
  int rows = ps.getUpdateCount();
  Object parameterObject = boundSql.getParameterObject();
  KeyGenerator keyGenerator = mappedStatement.getKeyGenerator();
  keyGenerator.processAfter(executor, mappedStatement, ps, parameterObject);
  return rows;
}

Interceptor

拦截器工作原理

在xml中注册拦截器后,在XMLConfigBuilder中的 pluginElement()组件会解析拦截器并反射创建实例

拦截器被添加到 Configuration 对象的拦截器链中

在创建 Executor、StatementHandler、ParameterHandler 和 ResultSetHandler 时会使用 Plugin.wrap() 方法为这些对象创建代理

这些对象被创建时,会通过 InterceptorChain.pluginAll() 方法将所有配置的拦截器应用到目标对象上,形成代理链。

基础使用

mybatis-config.xml

<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>

    <!-- 数据库相关属性文件,这里不写的话,会自动加载 config.properties -->
    <properties resource="db.properties"></properties>
    <typeAliases>
        <typeAlias type="DruidDataSourceFactory"
                   alias="DRUID" />
    </typeAliases>
<!--        <typeAliases>-->
<!--            <typeAlias type="c3p0DataSourceFactory"-->
<!--                       alias="C3P0" />-->
<!--        </typeAliases>-->

    <plugins>
        <plugin interceptor="com.github.pagehelper.PageInterceptor">
            <property name="helperDialect" value="mysql"/>
        </plugin>
    </plugins>
    <!-- 环境配置 -->
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <!-- 数据库连接相关配置 ,这里动态获取config.properties文件中的内容-->
            <dataSource type="POOLED">
                <property name="driver" value="${driver}"/>
                <property name="url" value="${url}"/>
                <property name="username" value="${username}"/>
                <property name="password" value="${password}"/>
            </dataSource>
<!--            <dataSource type="C3P0">-->
<!--                <property name="driverClass" value="${driver}"/>-->
<!--                <property name="jdbcUrl" value="${url}"/>-->
<!--                <property name="user" value="${username}"/>-->
<!--                <property name="password" value="${password}"/>-->
<!--            </dataSource>-->
        </environment>
    </environments>
    <mappers>
        <mapper resource="Mapper/DrawMapper.xml"/>
    </mappers>
</configuration>

mapper.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="DrawMapper">

    <update id="mergeInto" parameterType="java.util.List">
        MERGE INTO DRAW t
        USING (
        <foreach collection="list" item="record" separator="UNION ALL">
            SELECT
            #{record.metid} AS METID,
            #{record.datatime} AS DATATIME,
            #{record.remark} AS REMARK
            FROM DUAL
        </foreach>
        ) s
        ON (t.METID = s.METID)
        WHEN MATCHED THEN
        UPDATE SET
        t.REMARK = s.REMARK
        WHEN NOT MATCHED THEN
        INSERT (METID, DATATIME,REMARK)
        VALUES (s.METID,  s.DATATIME,s.REMARK)
    </update>

<!--    <insert id="testinsert" parameterType="Draw">-->
<!--        insert into draw(metid,datatime,remark) values-->
<!--            (#{metid},#{datatime},#{remark})-->
<!--    </insert>-->
    <insert id="testinsert" >
        insert into draw(metid,datatime,remark)
        select * from (
        <foreach collection="list" item="item" separator=" union all ">
            SELECT
            #{item.metid},#{item.datatime},#{item.remark}
            FROM dual
        </foreach>
        )
    </insert>
    <insert id="foreachadd" >
        <foreach collection="list" item="item">
            insert into draw(metid,datatime,remark) values
            (#{item.metid},#{item.datatime},#{item.remark});
        </foreach>
    </insert>
    <select id="getAll" resultType="Draw">
        select  * from draw
    </select>
</mapper>

基础使用

public class test {
    private static SqlSessionFactory sf;
    private static SqlSession sqlsession;
    private static DrawMapper drawMapper;
    static String resource = "mybatis-config.xml";
    public static void main(String[] args) throws Exception{
        List  list = new ArrayList();
        for(int i=0;i<1;i++){
            list.add(new Draw(i,"2022-01-01 12:00:00", UUID.randomUUID().toString()));
        }
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        sqlsession = sqlSessionFactory.openSession();
        drawMapper = sqlsession.getMapper(DrawMapper.class);
        System.out.println("i= " + i);
        drawMapper.mergeInto(list);
        sqlsession.commit();
        sqlsession.close();
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值