zoukankan      html  css  js  c++  java
  • 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,愿同您为友

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

  • 相关阅读:
    Druid 使用 Kafka 将数据载入到 Kafka
    Druid 使用 Kafka 数据加载教程——下载和启动 Kafka
    Druid 集群方式部署 —— 启动服务
    Druid 集群方式部署 —— 端口调整
    Druid 集群方式部署 —— 配置调整
    Druid 集群方式部署 —— 配置 Zookeeper 连接
    Druid 集群方式部署 —— 元数据和深度存储
    Druid 集群方式部署 —— 从独立服务器部署上合并到集群的硬件配置
    Druid 集群方式部署 —— 选择硬件
    Druid 独立服务器方式部署文档
  • 原文地址:https://www.cnblogs.com/kiqi/p/14368085.html
Copyright © 2011-2022 走看看