浅谈 mybatis

一、什么是Mybatis

Mybatis 是一个持久层的框架(dao),他是一个半自动ORM(对象关系映射)框架,它是对jdbc操作的一次封装

ORM: Object Relational Mapping,简称ORM

​ O:对象

​ R:关系(对象和表关系)

​ M:映射(就是把表中的字段的值 映射到 对象的属性中)

半自动:就是需要自己书写sql语句

如何使用:

1、导入Mybatis的架包

2、配置Mybatis中的核心配置文件(有两种):1:核心配置文件(mybatis-config.xml):配置数据源(数据库),配置缓存、日志、别名 2:映射文件(xxxxMapper.xml):配置对象与表之间的关系。然后通过sql语句来映射字段和对象属性的值

二.mybatis config文件

typeAliases 类型别名是为 Java 类型设置一个短的名字。它只和 XML 配置有关,存在的意义仅在于用来减少类完全限定名的冗余。例如:

<typeAliases>
  <typeAlias alias="Author" type="domain.blog.Author"/>
  <typeAlias alias="Blog" type="domain.blog.Blog"/>
  <typeAlias alias="Comment" type="domain.blog.Comment"/>
  <typeAlias alias="Post" type="domain.blog.Post"/>
  <typeAlias alias="Section" type="domain.blog.Section"/>
  <typeAlias alias="Tag" type="domain.blog.Tag"/>
</typeAliases>

三.插件(plugins)

MyBatis 允许你在已映射语句执行过程中的某一点进行拦截调用。默认情况下,MyBatis 允许使用插件来拦截的方法调用包括:

  • Executor (update, query, flushStatements, commit, rollback,getTransaction, close, isClosed)
  • ParameterHandler (getParameterObject, setParameters)
  • ResultSetHandler (handleResultSets, handleOutputParameters)
  • StatementHandler (prepare, parameterize, batch, update, query)
    下面通过自定义插件来打印出查询的sql语句:
@Intercepts({@Signature(type = Executor.class,
        method = "query",
        args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class})})
public class JunliPlugin  implements Interceptor {

   @Override
    public Object intercept(Invocation invocation) throws Throwable {
        MappedStatement mappedStatement = (MappedStatement) invocation.getArgs()[0];
        BoundSql boundSql = mappedStatement.getBoundSql(invocation.getArgs()[1]);
        System.out.println(String.format("plugin output sql = %s , param=%s", boundSql.getSql(),boundSql.getParameterObject()));
        return invocation.proceed();
    }
    @Override
    public Object plugin(Object o) {
        return Plugin.wrap(o,this);
    }
    @Override
    public void setProperties(Properties properties) {

    }

配置插件:

 <plugins>
      <plugin interceptor="com.junli.mybatis.demo.mybatis.JunliPlugin"/>
  </plugins>

四.映射器(mappers)

既然 MyBatis 的行为已经由上述元素配置完了,我们现在就要定义 SQL 映射语句了。但是首先我们需要告诉 MyBatis 到哪里去找到这些语句。 Java 在自动查找这方面没有提供一个很好的方法,所以最佳的方式是告诉 MyBatis 到哪里去找映射文件。你可以使用相对于类路径的资源引用, 或完全限定资源定位符(包括 file:/// 的 URL),或类名和包名等。例如:

<mappers>
    <mapper resource="xml/TestMapper.xml"/>
    <mapper resource="xml/PostsMapper.xml"/>
</mappers>

五.Mapper XML 文件 解读

MyBatis 的真正强大在于它的映射语句,也是它的魔力所在。由于它的异常强大,映射器的 XML 文件就显得相对简单。如果拿它跟具有相同功能的 JDBC 代码进行对比,你会立即发现省掉了将近 95% 的代码。MyBatis 就是针对 SQL 构建的,并且比普通的方法做的更好。
SQL映射文件有很少的几个顶级元素(按照它们应该被定义的顺序):
cache – 给定命名空间的缓存配置。
cache-ref – 其他命名空间缓存配置的引用。

resultType:是用来处理简单对象的一种方式
resultMap:是最复杂也是最强大的元素,用来描述如何从数据库结果集中来加载对象。
sql – 可被其他语句引用的可重用语句块。
insert – 映射插入语句
update – 映射更新语句
delete – 映射删除语句
select – 映射查询语句

resultMap
constructor - 用于在实例化类时,注入结果到构造方法中
idArg - ID 参数;标记出作为 ID 的结果可以帮助提高整体性能
arg - 将被注入到构造方法的一个普通结果
id – 一个 ID 结果;标记出作为 ID 的结果可以帮助提高整体性能
result – 注入到字段或 JavaBean 属性的普通结果
association – 一个复杂类型的关联;许多结果将包装成这种类型
嵌套结果映射 – 关联可以指定为一个 resultMap 元素,或者引用一个
collection – 一个复杂类型的集合嵌套结果映射 – 集合可以指定为一个 resultMap 元素,或者引用一个
discriminator – 使用结果值来决定使用哪个 resultMap.

resultMap 关联查询.

关联的嵌套结果实现:

<resultMap id="commodityBeanMap" type="com.lovo.supplier.bean.sales.CommodityBean">
        <id property="goodsId" column="goodsId"></id>
        <result property="goodsSales" column="goodsSales"></result>
        <result property="goodsMoney" column="goodsMoney"></result>
        <result property="goodsState" column="goodsState"></result>
        <association property="supplyBean" javaType="com.lovo.supplier.bean.offerAndSupply.SupplyBean">
            <id property="supplyId" column="supplyId"></id>
            <result property="supplyType" column="supplyType"></result>
            <result property="srttlemeentTime" column="srttlemeentTime"></result>
            <result property="indentId" column="indentId"></result>
            <association property="targetGoodsBean" javaType="com.lovo.supplier.bean.supplierManager.TargetGoodsBean">
                <id property="id" column="id"></id>
                <result property="goodsName" column="goodsName"></result>
                <result property="goodsNum" column="goodsNum"></result>
                <result property="goodsProce" column="goodsProce"></result>
                <result property="goodsTotalPrice" column="goodsTotalPrice"></result>
                <result property="supplier_name" column="supplierName"></result>
            </association>

        </association>

    </resultMap>

   
    <select id="findByGoodsId" resultMap="commodityBeanMap">
        select comm.goods_id as goodsId,
        		  sup.indent_id as indentId,
                  comm.goods_sales as goodsSales,
                  comm.goods_state as goodsState,
                  comm.goods_money as goodsMoney,
                  sup.supply_id as supplyId,
                  ta.id as id,
                  ta.goodsName as goodsName,
                  ta.goodsNum as goodsNum,
                  ta.goodsProce as goodsProce,
                  ta.goodsTotalPrice as goodsTotalPrice
        from t_commodity as comm
                 left join t_supply as sup on comm.indent_id=sup.indent_id
                 left join target as ta on ta.id=sup.id 
        where goods_id=#{goodsId}
    </select>

缓存:

Mybatis中有一级缓存和二级缓存,默认情况下一级缓存是开启的,而且是不能关闭的。一级缓存是指SqlSession级别的缓存,当在同一个SqlSession中进行相同的SQL语句查询时,第二次以后的查询不会从数据库查询,而是直接从缓存中获取,一级缓存最多缓存1024条SQL。二级缓存是指可以跨SqlSession的缓存。
Mybatis中进行SQL查询是通过org.apache.ibatis.executor.Executor接口进行的,总体来讲,它一共有两类实现,一类是BaseExecutor,一类是CachingExecutor。前者是非启用二级缓存时使用的,而后者是采用的装饰器模式,在启用了二级缓存时使用,当二级缓存没有命中时,底层还是通过BaseExecutor来实现的。

一级缓存

一级缓存是默认启用的,在BaseExecutor的query()方法中实现,底层默认使用的是PerpetualCache实现,PerpetualCache采用HashMap存储数据。一级缓存会在进行增、删、改操作时进行清除。

二级缓存

二级缓存是默认是关闭的,如想取消,则可以通过Mybatis配置文件中的元素下的子元素来指定cacheEnabled为false。

<settings>

      <setting name="cacheEnabled" value="false" />

   </settings>

我们要想使用二级缓存,是需要在对应的Mapper.xml文件中定义其中的查询语句需要使用哪个cache来缓存数据的。这有两种方式可以定义,一种是通过cache元素定义,一种是通过cache-ref元素来定义。但是需要注意的是对于同一个Mapper来讲,它只能使用一个Cache,当同时使用了和时使用定义的优先级更高。Mapper使用的Cache是与我们的Mapper对应的namespace绑定的,一个namespace最多只会有一个Cache与其绑定。

六.动态 SQL

MyBatis 的强大特性之一便是它的动态 SQL。如果你有使用 JDBC 或其它类似框架的经验,你就能体会到根据不同条件拼接 SQL 语句的痛苦。例如拼接时要确保不能忘记添加必要的空格,还要注意去掉列表最后一个列名的逗号。利用动态 SQL 这一特性可以彻底摆脱这种痛苦。动态 SQL 元素和 JSTL 或基于类似 XML 的文本处理器相似.MyBatis 采用功能强大的基于 OGNL 的表达式来淘汰其它大部分元素。

if

  <if test="title != null">
    AND title like #{title}
  </if>

choose (when, otherwise)

 <choose>
    <when test="title != null">
      AND title like #{title}
    </when>
    <when test="author != null and author.name != null">
      AND author_name like #{author.name}
    </when>
    <otherwise>
      AND featured = 1
    </otherwise>
  </choose>

trim (where, set)

  <where> 
    <if test="state != null">
         state = #{state}
    </if> 
    <if test="title != null">
        AND title like #{title}
    </if>
    <if test="author != null and author.name != null">
        AND author_name like #{author.name}
    </if>
  </where>

  <trim prefix="WHERE" prefixOverrides="AND |OR ">
  ... 
 </trim>

  <set>
      <if test="username != null">username=#{username},</if>
      <if test="password != null">password=#{password},</if>
      <if test="email != null">email=#{email},</if>
      <if test="bio != null">bio=#{bio}</if>
    </set>

foreach

 <foreach item="item" index="index" collection="list"
      open="(" separator="," close=")">
        #{item}
  </foreach>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值