Mybatis框架原理-江河计划

5.2.1 MyBatis简介和优势

在这里插入图片描述
代码:
在这里插入图片描述
在这里插入图片描述
dbutils:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
测试代码:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

5.2.2 手写MyBatis

在这里插入图片描述
在这里插入图片描述
JAR包引入:
在这里插入图片描述
代码:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

5.2.3 MyBatis核心源码分析

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
mybatis使用的设计模式:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

5.2.4 高级应用-分页插件

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
1.写一个mybatis的拦截器用来拦截sql请求

2.设置拦截类型

3.重写plugin setProperties intercept 方法
在这里插入图片描述
4.把pagesql赋给元BoundSql

import com.study.mybatis.utils.PageInfo;
import org.apache.ibatis.executor.parameter.ParameterHandler;
import org.apache.ibatis.executor.statement.StatementHandler;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.plugin.*;
import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.reflection.SystemMetaObject;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.Map;
import java.util.Properties;

/**
 * @ClassName AllenPagePlugin
 * @Description TODO
 * @Author 网易云课堂微专业-java高级开发工程师
 * @Date 2020/4/1 21:03
 * @Version 1.0
 */
@Intercepts(@Signature(
        type = StatementHandler.class,
        method = "prepare",
        args = {Connection.class, Integer.class}
))
public class AllenPagePlugin implements Interceptor {
    // 插件的核心业务
    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        /**
         * 1、拿到原始的sql语句
         * 2、修改原始sql,增加分页  select * from t_user limit 0,3
         * 3、执行jdbc去查询总数
         */
        // 从invocation拿到我们StatementHandler对象
        StatementHandler statementHandler = (StatementHandler) invocation.getTarget();
        // 拿到原始的sql语句
        BoundSql boundSql = statementHandler.getBoundSql();
        String sql = boundSql.getSql();
        System.out.println("原始sql:" + sql);

        // 分页参数
        Object paramObj = boundSql.getParameterObject();

        // statementHandler 转成 metaObject
        MetaObject metaObject = SystemMetaObject.forObject(statementHandler);

        // spring context.getBean("userBean")
        MappedStatement mappedStatement = (MappedStatement) metaObject.getValue("delegate.mappedStatement");
        // 获取mapper接口中的方法名称  selectUserByPage
        String mapperMethodName = mappedStatement.getId();
        if (mapperMethodName.matches(".*ByPage$")) {
            Map<String, Object> params = (Map<String, Object>) paramObj;

            PageInfo pageInfo = (PageInfo) params.get("page"); // map.put("page", PageInfo);
            //  select * from user;
            String countSql = "select count(0) from (" + sql + ") a";
            System.out.println("查询总数的sql : " + countSql);

            // 执行jdbc操作
            Connection connection = (Connection) invocation.getArgs()[0];
            PreparedStatement countStatement = connection.prepareStatement(countSql);
            ParameterHandler parameterHandler = (ParameterHandler) metaObject.getValue("delegate.parameterHandler");
            parameterHandler.setParameters(countStatement);
            ResultSet rs = countStatement.executeQuery();
            if (rs.next()) {
                pageInfo.setTotalNumber(rs.getInt(1));
            }
            rs.close();
            countStatement.close();

            // 改造sql limit
            String pageSql = this.generaterPageSql(sql, pageInfo);
            System.out.println("分页sql:" + pageSql);

            metaObject.setValue("delegate.boundSql.sql", pageSql);

        }
        // 把执行流程交给mybatis
        return invocation.proceed();
    }

    // 把自定义的插件加入到mybatis中去执行
    @Override
    public Object plugin(Object target) {
        return Plugin.wrap(target, this);
    }

    // 设置属性
    @Override
    public void setProperties(Properties properties) {
				String type = properties.getProperty("type");
    }

    // 根据原始sql 生成 带limit sql
    public String generaterPageSql(String sql, PageInfo pageInfo) {
        StringBuffer sb = new StringBuffer();
        sb.append(sql);
        if(type.equal("mysql")){
        	sb.append(" limit " + pageInfo.getStartIndex() + " , " + pageInfo.getTotalSelect());
        }else if(type.equal("oracle")){
        	sb.append("oracle 写法");
        }else{
        	throw new Exception("分页时,未获取到数据库类型!");
        }
        return sb.toString();
    }

}

5.最后在配置文件中添加拦截器配置
在这里插入图片描述

5.2.5 高级应用-读写分离插件

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2个数据源

5.2.6 高级应用-缓存

在这里插入图片描述
mybatis一级缓存和二级缓存实现都是用的hashMap.
作用域不一样,一级缓存作用域sqlSession,二级缓存作用域是namespace
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
开二级缓存,分2步
1.打开开关在这里插入图片描述
2.xxxMapper.xml打开开关
在这里插入图片描述
在这里插入图片描述
二级缓存 + Redis
在这里插入图片描述
方法一:
在这里插入图片描述

5.2.7 高级应用-自定义类型处理器

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
不是全集
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
1.自定义TypeHandler

import com.study.mybatis.utils.EncryptUtil;
import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.TypeHandler;

import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

/**
 * 自定义敏感字段加解密处理器
 *
 * @Author 网易云课堂微专业-java高级开发工程师【allen老师】
 * @Version 1.0
 */
public class AllenTypeHandle implements TypeHandler {

    //private static String KEY = "123456";

    /**
     * 通过preparedStatement对象设置参数,将T类型的数据存入数据库。
     *
     * @param ps
     * @param i
     * @param parameter
     * @param jdbcType
     * @throws SQLException
     */
    @Override
    public void setParameter(PreparedStatement ps, int i, Object parameter, JdbcType jdbcType) throws SQLException {
        try {
            String encrypt = EncryptUtil.encode(((String) parameter).getBytes());
            ps.setString(i, encrypt);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    // 通过列名或者下标来获取结果数据,也可以通过CallableStatement获取数据。
    @Override
    public Object getResult(ResultSet rs, String columnName) throws SQLException {
        String result = rs.getString(columnName);
        if (result != null && result != "") {
            try {
                return EncryptUtil.decode(result.getBytes());
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return result;
    }

    @Override
    public Object getResult(ResultSet rs, int columnIndex) throws SQLException {
        String result = rs.getString(columnIndex);
        if (result != null && result != "") {
            try {
                return EncryptUtil.decode(result.getBytes());
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return result;
    }

    @Override
    public Object getResult(CallableStatement cs, int columnIndex) throws SQLException {
        String result = cs.getString(columnIndex);
        if (result != null && result != "") {
            try {
                return EncryptUtil.decode(result.getBytes());
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return result;
    }
}

2.配置注册自定义处理器
在这里插入图片描述

3.使用自定义处理器
在这里插入图片描述
在这里插入图片描述

5.2.8-面试题分析

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
建议:
在这里插入图片描述
在这里插入图片描述
mybatis默认支持:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值