• Mybatis


    Mybatis框架 - 半自动的对象关系映射ORM框架

    1. 资源管理
    2. 封装样板代码
    3. 实现对象关系映射(参数处理和结果集处理)
    4. SQL语句与业务代码解耦,通过xml配置实现sql的统一管理
    5. 动态SQL
    6. 缓存机制和插件机制

    Mybatis 架构
    mybatis中文官方文档

    Mybatis使用案例:

        public static void mapperTest(){
            // 核心对象1: SqlSessionFactoryBuilder:用于读取配置文件并构建出SqlSessionFactory
            // 核心对象2: SqlSessionFactory:用于创建sqlSession的工厂对象,单例
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
    
            // 核心对象3: SqlSession:会话,用于一次sql请求,是线程不安全的。
            SqlSession sqlSession = sqlSessionFactory.openSession();
            try {
                // 核心对象4:mapper代理对象:作用 - 采集调用方法名和参数,映射成mybatis中的statementId和params,在invocationHanlder.invoke()方法中实现sql的调用
                KiqiMapper kiqiMapper = sqlSession.getMapper(KiqiMapper.class);
                
                Kiqi kiqi = new Kiqi(1,"kiqi","123456",18,"kiqi$123");
                kiqiMapper.insert(kiqi);
                System.out.println(kiqi);
            } catch (Exception e){
                e.printStackTrace();
            } finally {
                sqlSession.close();
            }
        }
    

    PS:对象关系映射ORM框架(Object Relational Mapping),用于解决对象与关系数据库元数据之间互不匹配的问题。

    mybatis-config.xml

    <!-- 在SqlSessionFactoryBuilder.build()方法中完成解析,解析后会构成Configuration对象,存在于SqlSessionFactory中 -->
    <configuration>
        <!-- 配置文件路径 通过${}符号引用其中的数据 -->
        <properties resource="db.properties"/>
    
        <!-- 核心配置 -->
        <settings>
            <!-- 打印查询语句 -->
            <setting name="logImpl" value="STDOUT_LOGGING" />
    
            <!-- 1. 开启全局缓存(二级缓存),默认 true -->
            <!-- 一级缓存是基于session的,在同一个session中两次同样的select语句会触发缓存操作,而update类语句会则会清空缓存 -->
            <!-- 二级缓存是基于namespace的,还需在具体的mapper.xml文件中配置缓存才能使对应的namespace应用缓存,与事务(cache是跨事务可见的)相关,只有事务提交后才会设置缓存 -->
    
            <setting name="cacheEnabled" value="true"/>
    
            <!-- 2. 延迟加载的全局开关,当开启时,所有关联对象都会延迟加载。默认 false.  1 + N关联查询,使后面的N在需要时(对应属性被使用)才执行 -->
            <setting name="lazyLoadingEnabled" value="true"/>
            <!-- 与lazyLoadingEnabled一同使用,aggressiveLazyLoading = true代表:对象在被调用任何方法时均触发延迟加载动作 -->
            <setting name="aggressiveLazyLoading" value="true"/>
            <!--  Mybatis 创建具有延迟加载能力的对象所用到的代理工具,默认JAVASSIST -->
            <!--<setting name="proxyFactory" value="CGLIB" />-->
    
            <!--设置执行器类型,默认SIMPLE普通执行器,REUSE重用与处理语句,BATCH重用语句且批量执行-->
            <setting name="defaultExecutorType" value="SIMPLE"/>
    
            <!-- STATEMENT级别的缓存,使一级缓存,只针对当前执行的这一statement有效 -->
            <!-- <setting name="localCacheScope" value="STATEMENT"/> -->
            <setting name="localCacheScope" value="SESSION"/>
        </settings>
    
        <!-- 别名,用于简化一些全类名的拼写 - mybatis提供了很多预制的别名,如String -->
        <typeAliases>
            <typeAlias alias="kiqi" type="top.kiqi.mybatis.entity.Kiqi" />
        </typeAliases>
    
        <!-- 类型转换器,jdbc类型和java类型的相互映射转换,允许自定义,应用时在具体的statement语句或resultMap中设置 -->
        <typeHandlers>
            <typeHandler handler="top.kiqi.mybatis.handler.MyTypeHandler"></typeHandler>
        </typeHandlers>
    
        <!--四大插件: ①Executor(执行器) ②ParameterHandler(参数处理) ③ResultSetHandler(结果集处理) ④StatementHandler(语句执行) -->
        <plugins>
            <plugin interceptor="top.kiqi.mybatis.intercept.MyPageInterceptor">
                <property name="kiqi" value="123456" />
            </plugin>
    
            <plugin interceptor="top.kiqi.mybatis.intercept.SQLInterceptor">
            </plugin>
        </plugins>
    
        <!-- 配置环境 一个environment代表一个数据库 -->
        <environments default="development">
            <environment id="development">
                <transactionManager type="JDBC"/>    <!-- 事务配置 - 在Spring中,该项配置会被Spring覆盖 -->
                <dataSource type="POOLED">
                    <property name="driver" value="${dataSource.driver}"/>
                    <property name="url" value="${dataSource.url}"/>
                    <property name="username" value="${dataSource.username}"/>
                    <property name="password" value="${dataSource.password}"/>
                </dataSource>
            </environment>
        </environments>
    
        <!-- Mapper.xml 映射文件配置 -->
        <mappers>
            <mapper resource="mapping/KiqiMapper.xml"/>
            <!--<mapper package="top.kiqi.mybatis.dao"/>-->
            <!--<mapper class="top.kiqi.mybatis.dao.KiqiMapper"/>-->
        </mappers>
    
    </configuration>
    

    mapper.xml

    <mapper namespace="top.kiqi.mybatis.dao.KiqiMapper">
      <!-- 1, 只有当namespace中存在cache标签,该namespace才使用二级缓存-->
      <cache type="org.apache.ibatis.cache.impl.PerpetualCache" size="1024" eviction="LRU" flushInterval="120000" readOnly="false"/>
      
      <!-- 2. 重用语句块 -->
      <sql id="Base_Column_List">
        id, username, password, age, addr
      </sql>
    
      <!-- 3. 结果集,用于结果集映射到java对象-->
      <resultMap id="BaseResultMap" type="top.kiqi.mybatis.entity.Kiqi">
        <id column="id" jdbcType="INTEGER" property="id" />
        <result column="username" jdbcType="VARCHAR" property="username" />
        <result column="password" jdbcType="VARCHAR" property="password" />
        <result column="age" jdbcType="INTEGER" property="age" />
        <result column="addr" jdbcType="VARCHAR" property="addr" />
      </resultMap>
    
      <!-- 4. 增删改查标签 -->
      <select id="selectByPrimaryKey" parameterType="java.lang.Integer" resultMap="BaseResultMap">
        select 
        <include refid="Base_Column_List" />
        from kiqi
        where id = #{id,jdbcType=INTEGER}
      </select>
      <delete id="deleteByPrimaryKey" parameterType="java.lang.Integer">
        delete from kiqi
        where id = #{id,jdbcType=INTEGER}
      </delete>
    
      <insert id="insert" useGeneratedKeys="true" parameterType="top.kiqi.mybatis.entity.Kiqi">
        insert into kiqi (username, password,
          age, addr)
        values (#{username,jdbcType=VARCHAR}, #{password,jdbcType=VARCHAR},
          #{age,jdbcType=INTEGER}, #{addr,jdbcType=VARCHAR})
      </insert>
    
      <insert id="insertSelective" parameterType="top.kiqi.mybatis.entity.Kiqi">
        insert into kiqi
        <trim prefix="(" suffix=")" suffixOverrides=",">
          <if test="id != null">
            id,
          </if>
          <if test="username != null">
            username,
          </if>
          <if test="password != null">
            password,
          </if>
          <if test="age != null">
            age,
          </if>
          <if test="addr != null">
            addr,
          </if>
        </trim>
        <trim prefix="values (" suffix=")" suffixOverrides=",">
          <if test="id != null">
            #{id,jdbcType=INTEGER},
          </if>
          <if test="username != null">
            #{username,jdbcType=VARCHAR},
          </if>
          <if test="password != null">
            #{password,jdbcType=VARCHAR},
          </if>
          <if test="age != null">
            #{age,jdbcType=INTEGER},
          </if>
          <if test="addr != null">
            #{addr,jdbcType=VARCHAR},
          </if>
        </trim>
      </insert>
      <update id="updateByPrimaryKeySelective" parameterType="top.kiqi.mybatis.entity.Kiqi">
        update kiqi
        <set>
          <if test="username != null">
            username = #{username,jdbcType=VARCHAR},
          </if>
          <if test="password != null">
            password = #{password,jdbcType=VARCHAR},
          </if>
          <if test="age != null">
            age = #{age,jdbcType=INTEGER},
          </if>
          <if test="addr != null">
            addr = #{addr,jdbcType=VARCHAR},
          </if>
        </set>
        where id = #{id,jdbcType=INTEGER}
      </update>
      <update id="updateByPrimaryKey" parameterType="top.kiqi.mybatis.entity.Kiqi">
        update kiqi
        set username = #{username,jdbcType=VARCHAR},
          password = #{password,jdbcType=VARCHAR},
          age = #{age,jdbcType=INTEGER},
          addr = #{addr,jdbcType=VARCHAR}
        where id = #{id,jdbcType=INTEGER}
      </update>
    </mapper>
    

    动态Sql - 详见Mybatis官方文档

    tips

    1. 逻辑翻页和物理翻页:

      • 逻辑翻页(将数据全部查询到java中,再根据offset丢弃范围之外的数据) - Mybatis RowBounds对象
      • 物理翻页(Sql中采用limit字段实现定向查询) - PageHelper插件,通过拦截StatmentHandler完成SQL语句修改,实现物理翻页
    2. #{}和${}

      • #{}代表预编译,参数部分用?代替,可以防止注入(可缓存,性能高),而${}只是简单的字符串替换,并不能防止sql注入 -> 在能使用#{}的地方均使用#{}
    3. 实现模糊查询:
      ① 字符串拼接:Like %${name}% --- 存在注入风险
      ② CONCAT表达式:Like CONCAT('%',#{name})

    4. 批量更新
      ① foreach动态sql语句
      ② BatchExecutor


    欢迎疑问、期待评论、感谢指点 -- kiqi,愿同您为友

    -- 星河有灿灿,愿与之辉

  • 相关阅读:
    os.path.join()
    图像旋转后出现黑点
    surging 微服务引擎 1.0 正式发布
    基于docker 如何部署surging分布式微服务引擎
    剥析surging的架构思想
    如何使用thrift 服务引擎组件
    谈谈surging 与多语言混合微服务构思
    surging 社区版本支持.net core 3.1
    surging 微服务引擎 -协议主机的Behavior特性
    谈谈surging 微服务引擎 2.0的链路跟踪和其它新增功能
  • 原文地址:https://www.cnblogs.com/kiqi/p/14368085.html
Copyright © 2020-2023  润新知