mybatis详细介绍

1.Mybatis解决jdbc编程的问题

1、  数据库链接创建、释放频繁造成系统资源浪费从而影响系统性能,如果使用数据库链接池可解决此问题。

       解决:在SqlMapConfig.xml中配置数据链接池,使用连接池管理数据库链接。

2、  Sql语句写在代码中造成代码不易维护,实际应用sql变化的可能较大,sql变动需要改变java代码。

     解决:将Sql语句配置在XXXXmapper.xml文件中与java代码分离。

3、  向sql语句传参数麻烦,因为sql语句的where条件不一定,可能多也可能少,占位符需要和参数一一对应。

      解决:Mybatis自动将java对象映射至sql语句,通过statement中的parameterType定义输入参数的类型。

4、  对结果集解析麻烦,sql变化导致解析代码变化且解析前需要遍历,如果能将数据库记录封装成pojo对象解析比较方便。

    解决:Mybatis自动将sql执行结果映射至java对象,通过statement中的resultType定义输出结果的类型。

2. Mybatis与hibernate区别

    1.  Mybatis和hibernate不同,它不完全是一个ORM框架,因为MyBatis需要程序员自己编写Sql语句,

        不过mybatis可以通过      XML或注解方式灵活配置要运行的sql语句,并将java对象和sql语句映射生成最终执行的sql,

        最后将sql执行的结果再映射生成java对象。

    2.  Mybatis学习门槛低,简单易学,程序员直接编写原生态sql,可严格控制sql执行性能,灵活度高,

        非常适合对关系数据模型  要求不高的软件开发,例如互联网软件、企业运营类软件等,因为这类软件需求变化频繁,

        一但需求变化要求成果输出迅速。但是灵活的前提是mybatis无法做到数据库无关性,如果需要实现支持多种数据库的软件

        则需要自定义多套sql映射文件,工作量大。

 

   3. Hibernate对象/关系映射能力强,数据库无关性好,对于关系模型要求高的软件(例如需求固定的定制化软件)

        如果用 hibernate开发可以节省很多代码,提高效率。但是Hibernate的学习门槛高,要精通门槛更高,

        而且怎么设计O/R映射,在性能和对象模型之间如何权衡,以及怎样用好Hibernate需要具有很强的经验和能力才行。

   4. 总之按照用户的需求在有限的资源环境下只要能做出维护性、扩展性良好的软件架构都是好架构,所以框架只有适合才是最好

3.Mybatis中重要类介绍

      1  SqlSessionFactoryBuilder

        SqlSessionFactoryBuilder用于创建SqlSessionFacotySqlSessionFacoty一旦创建完成就不需要SqlSessionFactoryBuilder

         因为SqlSession是通过SqlSessionFactory生产,所以可以将SqlSessionFactoryBuilder当成一个工具类使用,

         最佳使用范围是方法范围即方法体内局部变量。

    2. SqlSessionFactory

         SqlSessionFactory是一个接口,接口中定义了openSession的不同重载方法,SqlSessionFactory的最佳使用范围是整个

         应用运行期间,一旦创建后可以重复使用,通常以单例模式管理SqlSessionFactory。

         并且数据库连接池是在SqlSessionFactory中设置的,还可以设置多种拦截器,比如说 分页拦截器

  3.SqlSession

       SqlSession是一个面向用户的接口, sqlSession中定义了数据库操作方法。

       每个线程都应该有它自己的SqlSession实例。SqlSession的实例不能共享使用,它也是线程不安全的。因此最佳的范围是

       请求 或方法范围。绝对不能将SqlSession实例的引用放在一个类的静态字段或实例字段中。

       打开一个 SqlSession;使用完毕就要关闭它。通常把这个关闭操作放到 finally 块中以确保每次都能执行关闭。如下:

         SqlSession session =sqlSessionFactory.openSession();

         try {

                  // do work

         } finally {

                session.close();

         }

     使用范围:

         SqlSession中封装了对数据库的操作,如:查询、插入、更新、删除等。

          通过SqlSessionFactory创建SqlSession,而SqlSessionFactory是通过SqlSessionFactoryBuilder进行创建。

4.SqlMapConfig.xml

    SqlMapConfig.xml是mybatis核心配置文件,上边文件的配置内容为数据源、事务管理。并且定义的映射文件也需要添加在这里面

    SqlMapConfig.xml中配置的内容和顺序如下:

properties(属性)

settings(全局配置参数)

typeAliases(类型别名)

typeHandlers(类型处理器)

objectFactory(对象工厂)

plugins(插件)

environments(环境集合属性对象)

environment(环境子属性对象)

transactionManager(事务管理)

dataSource(数据源)

mappers(映射器)

5  输入映射和输出映射

       Mapper.xml映射文件中定义了操作数据库的sql,每个sql是一个statement,映射文件是mybatis的核心。

     1.  parameterType:定义输入到sql中的映射类型,#{id}表示使用preparedstatement设置占位符号并将输入变量id传到sql。       

                                     传递pojo对象,Mybatis使用ognl表达式解析对象字段的值,#{}或者${}括号中的值为pojo属性名称。

                                      ${value}表示使用参数将${value}替换,做字符串的拼接。如果是取简单数量类型的参数,

                                       括号中的值必须为value名称

 

    2. reulstType:  输出简单类型必须查询出来的结果集有一条记录,最终将第一个字段的值转换为输出类型。

    3. resultMap:

          resultType可以指定pojo将查询结果映射为pojo,但需要pojo的属性名和sql查询的列名一致方可映射成功。

               如果sql查询字段名和pojo的属性名不一致,可以通过resultMap将字段名和属性名作一个对应关系 ,

         resultMap实质上还需要将查询结果映射到pojo对象中。

        resultMap可以实现将查询结果映射为复杂类型的pojo,比如在查询结果映射对象中包括pojo和list实现一对一查询和一对多查询。

    4. 自定义resultMap:可以在type里面写出要映射的类,字段名对应类的成员属性

    <id />:此属性表示查询结果集的唯一标识,非常重要。如果是多个字段为复合唯一约束则定义多个<id />。

    Property:表示User类的属性。

   Column:表示sql查询出来的字段名。

   Column和property放在一块儿表示将sql查询出来的字段映射到指定的pojo类属性上。

   <result />:普通结果,即pojo的属性。

 

   5. #{}和${}区别

      #{}表示一个占位符号,通过#{}可以实现preparedStatement向占位符中设置值,自动进行java类型和jdbc类型转换,#{}可以有效防止

       sql注入。 #{}可以接收简单类型值或pojo属性值。如果parameterType传输单个简单类型值,#{}括号中可以是value或其它名称。

 

     ${}表示拼接sql串,通过${}可以将parameterType 传入的内容拼接在sql中且不进行jdbc类型转换, ${}可以接收简单类型值或

      pojo属性值如果parameterType传输单个简单类型值,${}括号中只能是value。

     #{} 的参数替换是发生在 DBMS 中,而 ${} 则发生在动态解析过程中。

 

6. Mybatis的常用功能:

      1. mysql自增主键返回: 

添加selectKey实现将主键返回

keyProperty:返回的主键存储在pojo中的哪个属性

order:selectKey的执行顺序,是相对与insert语句来说,由于mysql的自增原理执行完insert语句之后才将主键生成,

            所以这里selectKey的执行顺序为after

resultType:返回的主键是什么类型

LAST_INSERT_ID():是mysql的函数,返回auto_increment自增列新记录id值。

 

      2. 使用UUID作为主键

           注意这里使用的order是“BEFORE”

<selectKeyresultType="java.lang.String" order="BEFORE" keyProperty="id">

   select uuid()

</selectKey>

     3. 通过mybatis提供的各种标签方法实现动态拼接sql。

  例如:

   <if test="username!=null and username!=''">

       and username like '%${username}%'

    </if>

    <where />可以自动处理第一个and。

       select * from user

       <where>

       <if test="username!=null and username!=''">

       and username like '%${username}%'

       </if>

       </where>

  向sql传递数组或List,mybatis使用foreach解析,如下:

    <if test="ids!=null andids.size>0">

            <foreach collection="ids" open=" and idin(" close=")"item="id" separator=",">

               #{id}

            </foreach>

     </if>

 

 

      4. sql片段

Sql中可将重复的sql提取出来,使用时用include引用即可,最终达到sql重用的目的,如下:

例子:

    <sql id="query_user_where">

       <if test="id!=null and id!=''">

          and id=#{id}

       </if>

       <if test="username!=null and username!=''">

       and username like '%${username}%'

    </if>

</sql>

           使用include引用:

       <selectid="findUserList" parameterType="user"resultType="user">

          select * from user

           <where>

            <include refid="query_user_where"/>

          </where>

        </select>

 

    注意:如果引用其它mapper.xml的sql片段,则在引用时需要加上namespace,如下:

   <include refid="namespace.sql片段”/>

    5.关联查询

    ①.关联查询中 : 简单做法定义一个pojo类: 包含两个表内的信息

    ②.  一对一关联查询可以使用association完成关联查询,将关联查询信息映射到pojo对象中。

        association表示进行关联查询单条记录

        property表示关联查询的结果存储在cn.itcast.mybatis.po.Orders的user属性中

        javaType表示关联查询的结果类型

        <id property="id" column="user_id"/>查询结果的user_id列对应关联对象的id属性,

         这里是<id />表示user_id是关联查询对象   的唯一标识。

       <result property="username"column="username"/>查询结果的username列对应关联对象的username属性。

             ③ 一对多查询

    collection部分定义了用户关联的订单信息。表示关联查询结果集

   property="orders"关联查询的结果集存储在User对象的上哪个属性。

   ofType="orders"指定关联查询的结果集中的对象类型即List中的对象类型。此处可以使用别名,也可以使用全限定名。

   <id />及<result/>的意义同一对一查询。

      <!-- 一对多关联映射 -->

           <collection property="orders" ofType="orders">

                 <id property="id" column="oid"/> 

                 <!--用户id已经在user对象中存在,此处可以不设置-->

                 <!-- <result property="userId" column="id"/> -->

                 <result property="number" column="number"/>

                 <result property="createtime" column="createtime"/>

                 <result property="note" column="note"/>

           </collection>

  

案例:查询所有用户信息及用户关联的订单信息。

7.Mapper动态代理方式     

       1. Mapper接口开发方法只需要程序员编写Mapper接口(相当于Dao接口),由Mybatis框架根据接口定义创建接口的动态代理对象,

             代理对象的方法体同上边Dao接口实现类方法。

      2.动态代理对象调用sqlSession.selectOne()和sqlSession.selectList()是根据mapper接口方法的返回值决定,如果返回list则调用    

           selectList方法,如果返回单个对象则调用selectOne方法。

 

8.判断重复区间的,mybatis的大于等于

     SELECT *  FROM YourTable b  WHERE (a.开始 <= b.结束  AND a.开始     > =b.开始) 

                                                                     OR (a.结束    >= b.开始  AND a.结束    <= b.结束) 

第一种写法(1):

原符号       <        <=      >       >=       &        '        "
替换符号    &lt;    &lt;=   &gt;    &gt;=   &amp;   &apos;  &quot;
例如:sql如下:
create_date_time &gt;= #{startTime} and  create_date_time &lt;= #{endTime}

第二种写法(2):
大于等于
<![CDATA[ >= ]]>
小于等于
<![CDATA[ <= ]]>
例如:sql如下:
create_date_time <![CDATA[ >= ]]> #{startTime} and  create_date_time <![CDATA[ <= ]]> #{endTime}

9. mybatis支持别名: typeAliases(类型别名) 也可以自定义

别名

映射的类型

_byte

byte

_long

long

_short

short

_int

int

_integer

int

_double

double

_float

float

_boolean

boolean

string

String

byte

Byte

long

Long

short

Short

int

Integer

integer

Integer

double

Double

float

Float

boolean

Boolean

date

Date

decimal

BigDecimal

bigdecimal

BigDecimal

map

Map

10.mybatis的缓存  转载:https://www.cnblogs.com/moongeek/p/7689683.html

  ​ 1、一级缓存   

         MyBatis 默认开启了一级缓存,一级缓存是在SqlSession 层面进行缓存的。即,同一个SqlSession ,

         多次调用同一个Mapper和同一个方法的同一个参数,只会进行一次数据库查询,然后把数据缓存到缓冲中,

         以后直接先从缓存中取出数据, 不会直接去查数据库。 比如: 一个方法内,多次进行相同查询

 2. 但是不同的SqlSession对象,因为不用的SqlSession都是相互隔离的,所以相同的Mapper、参数和方法,

    他还是会再次发送到SQL到数据库去执行,返回结果。

     为了克服这个问题,需要开启二级缓存,是的缓存zaiSqlSessionFactory层面给各个SqlSession 对象共享。

     默认二级缓存是不开启的,需要手动进行配置。

<cache/>

​    如果这样配置的话,很多其他的配置就会被默认进行,如:

  • 映射文件所有的select 语句会被缓存
  • 映射文件的所有的insert、update和delete语句会刷新缓存
  • 缓存会使用默认的Least Recently Used(LRU,最近最少使用原则)的算法来回收缓存空间
  • 根据时间表,比如No Flush Interval,(CNFI,没有刷新间隔),缓存不会以任何时间顺序来刷新
  • 缓存会存储列表集合或对象(无论查询方法返回什么)的1024个引用
  • 缓存会被视为是read/write(可读/可写)的缓存,意味着对象检索不是共享的,而且可以很安全的被调用者修改,不干扰其他调用者或县城所作的潜在修改

   可以在开启二级缓存时候,手动配置一些属性

<cache eviction="LRU" flushInterval="100000" size="1024" readOnly="true"/>

 各个属性意义如下:

  • eviction:缓存回收策略
    - LRU:最少使用原则,移除最长时间不使用的对象
    - FIFO:先进先出原则,按照对象进入缓存顺序进行回收
    - SOFT:软引用,移除基于垃圾回收器状态和软引用规则的对象
    - WEAK:弱引用,更积极的移除移除基于垃圾回收器状态和弱引用规则的对象
  • flushInterval:刷新时间间隔,单位为毫秒,这里配置的100毫秒。如果不配置,那么只有在进行数据库修改操作才会被动刷新缓存区
  • size:引用额数目,代表缓存最多可以存储的对象个数
  • readOnly:是否只读,如果为true,则所有相同的sql语句返回的是同一个对象(有助于提高性能,但并发操作同一条数据时,可能不安全),如果设置为false,则相同的sql,后面访问的是cache的clone副本。

可以在Mapper的具体方法下设置对二级缓存的访问意愿:

  • useCache配置

    ​ 如果一条语句每次都需要最新的数据,就意味着每次都需要从数据库中查询数据,可以把这个属性设置为false,如:

  <select id="selectAll" resultMap="BaseResultMap" useCache="false">
  • 刷新缓存(就是清空缓存)

    ​ 二级缓存默认会在insert、update、delete操作后刷新缓存,可以手动配置不更新缓存,如下:

  <update id="updateById" parameterType="User" flushCache="false" />

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值