Mybatis的基础用法

一、Mybatis概述:
1、简介:

MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis 。2013年11月迁移到Github。

iBATIS一词来源于“internet”和“abatis”的组合,是一个基于Java的持久层框架。iBATIS提供的持久层框架包括SQL Maps和Data Access Objects(DAOs)。

MyBatis是一个支持普通SQL查询存储过程高级映射的优秀持久层框架。MyBatis消除了几乎所有的JDBC代码和参数的手工设置以及对结果集的检索封装。MyBatis可以使用简单的XML或注解用于配置和原始映射,将接口和Java的POJO(Plain Old Java Objects,普通的Java对象)映射成数据库中的记录。

2、官网:http://www.mybatis.org/mybatis-3/
      中文官方文档:http://www.mybatis.org/mybatis-3/zh/index.html
3、特点:
    1)支持自定义SQL、存储过程、及高级映射
    2)实现自动对SQL的参数设置
    3)实现自动对结果集进行解析和封装
    4)通过XML或者注解进行配置和映射
    5)实现Java对象与数据库表的映射转换
4、架构:
①MyBatis有两类配置文件:mybatis-condig.xml和xxxMapper.xml

       a)mybatis-condig.xml,是MyBatis的全局配置文件,包含全局配置信息,如数据库连接参数、插件等。整个框架中只需要一个即可。

       b)xxxMapper.xml,是映射文件,里面配置要执行的SQL语句,每个SQL对应一个Statement,可以有多个Mapper.xml文件。

②首先会通过SqlSessionFactoryBuilder来加载配置文件,生成一个SqlSessionFactor

       a)会加载mybatis-config.xml和mapper.xml

       b)加载mapper.xml的时候,顺便会对Sql进行编译,形成statement

③通过SqlSessionFactory建立连接,获取SqlSession对象
④MyBatis获取要执行的statement,进行自动参数设置
⑤SqlSession底层会通过Executor(执行器)来执行编译好的Statement,获取结果
⑥SQL的输入参数类型:POJO、HashMap、其他基本数据
⑦查询结果的输出形式:POJO、HashMap、其他基本数据

二、快速入门:
1、导入依赖:mybatis依赖包

       <dependency>
              <groupId>org.mybatis</groupId>
              <artifactId>mybatis</artifactId>
       </dependency>
2、编写全局配置文件:外部配置,运行环境,数据源,指定所有的mapper映射文件

<properties resource="jdbc.properties"/>

 <environments default="development">
    <environment id="development">
      <transactionManager type="JDBC"/>
      <dataSource type="POOLED">
        <property name="driver" value="${jdbc.driver}"/>
        <property name="url" value="${jdbc.url}"/>
        <property name="username" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
      </dataSource>
    </environment>
  </environments>

<mappers>
    <mapper resource="mapper.xml"/>
    <mapper resource="xxxMapper.xml"/>
    <!-- class指定接口的全路径,要求xml文件必须和接口处于同一包下,并且名称完全相同(后缀名不同) -->
    <!--     <mapper class="com.psm.mybatis.dao.UserDao"/> -->
    <!-- 要求xml文件必须和接口处于同一包下,并且名称完全相同(后缀名不同) -->
    <!--     <package name="com.psm.mybatis.dao"/> -->
    <!--     问题:  java代码和xml耦合在一起,没有分离,分离交给和spring整合后来解决-->
  </mappers>
3、编写Mapper.xml映射文件:因为mybatis动态代理的使用,书写时,要将namespace指定为接口的全路径

<mapper namespace="userMapper">

     <!-- select标签定义一个查询操作
            id是唯一标识,通常是接口的方法名称
            resultType返回类型,通常是类型别名
            resultMap返回类型,指向的是resultMap标签的id

      -->
      <select id="queryUserById" resultType="user">
            select * from tb_user where id = #{id} 
       </select>

</mapper>
4、编写测试代码:
    ①指定全局配置文件的路径:String resource = "mybatis-config.xml";
    ②获取输入流,关联全局配置文件:InputStream inputStream = Resources.getResourceAsStream(resource);
    ③构建SqlSessionFactory:SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
    ④获取SqlSession:SqlSession session = sqlSessionFactory.openSession();
    ⑤执行statement(动态代理),要指定两个参数:

     //1、通过Mapper.xml中的 namespace + statement的ID来确定要执行哪个statement

     // 2、SQL中需要接收的实际参数

         User user = session.selectOne("userMapper.queryUserById", 1L);
5、程序执行流程:

①编写配置文件(全局配置文件mybatis-config.xml和所有的mapper.xml映射文件)

            简单来说:就是准备JDBC连接参数以及要用到的Sql语句。

②加载配置,创建SqlSessionFactory

            这里获取连接参数,获取Sql,对Sql进行预编译,形成statement。

③通过SqlSessionFactory创建SqlSession

            这里就是调用了连接参数,连接数据库,形成会话。

④通过SqlSession执行statement,实现CRUD

            给前面编译好的statement设置Sql参数,然后执行。

⑤通过SqlSession提交事务

⑥通过SqlSession关闭会话

6、userName为Null问题:

解决方案:①对查询的结果列使用别名   as

                  ②开启自动驼峰匹配:<setting name="mapUnderscoreToCamelCase" value="true"/>

                  ③结果集映射

三、完整的CRUD:
1、定义UserDAO接口
2、编写SQL到mapper.xml中
3、编写DAO实现类
4、使用工具生成测试类
5、编写测试代码

四、动态代理实现DAO:
1、CRUD代码分析:都是通过SqlSession调用的。
2、思路分析:动态代理接口
3、mybatis动态代理实现DAO
①规则:
     1)每个DAO接口对应一个Mapper.xml文件
     2)mapper.xml的namespace必须是接口的全名称
     3)mapper.xml中的每个statement的id必须是接口中对应的方法名
     4)statement中定义的resultType必须和接口中对应方法的返回值一致(这一点即便不是动态代理也得遵守)
     5)在mybatis中,一般接口命名规则不是XxxDAO,而是XxxMapper,这一点不是必须的,但类似约定。
②新建Mapper
③修改UserMapper.xml文件
    注意:1)namespace改成接口全名称
               2)statement的id必须与方法名一致
④编写测试类
⑤总结:MyBatis动态代理生成DAO的步骤:
    1)编写数据管理的接口XxxMapper
    2)编写该接口对应的Mapper.xml
        a)namespace必须与Mapper接口全名一致
        b)statement的id必须和Mapper接口中的对应方法名一致
        c)statement的resultType必须和Mapper接口中对应方法返回值一致
    3)通过SqlSession的getMapper(XxxMapper.class)方法来获取动态代理的Mapper实现类对象
五、mybatis-config.xml全局配置文件详解:
1、Properties属性:引用外部的properties文件。

通过Properties引用外部属性文件后,可以通过${属性名}来引用外部文件中的属性值。

jdbc.properties:jdbc.username   编码规范,传参

2、settings设置:
    ①缓存全局开关:cacheEnabled
    ②延迟加载的全局开关:lazyLoadingEnabled、aggressiveLazyLoading
    ③是否开启自动驼峰命名规则:mapUnderscoreToCamelCase
3、typeAliases类型别名:
    ①单独定义:resultType=""
    ②扫描包:<package name="包路径" />

注意:Mybatis中的别名是不区分大小写的。但是一般建议大家严格按照类的简称来写。
4、typeHandler类型处理器
5、plugins插件:

MyBatis中的插件,其实类似于拦截器的效果,可以实现在MyBatis的整个运行流程中的 某些指定位置进行拦截:

Executor:对执行器进行拦截,上图括号内是可以拦截的方法

ParameterHandler:参数处理时进行拦截

ResultSetHandler:处理结果集,封装Java对象时进行拦截

StatementHandler:编译statement时进行拦截

6、Environment环境
7、Mappers映射器配置:
    ①使用项目资源路径:<mapper resource="xxxMapper.xml"/>
    ②使用url地址:<mapper url="file:///var/mappers/xxxMapper.xml"/>
    ③使用接口的全路径名称:<mapper class="接口全路径"/>
    ④配置扫描包:<package name="包名称"/>
六、Mapper.xml映射文件详解:
1、概述:映射语句
    insert\update\delete\select
    sql片段:sql
    结果集映射:resultMap
2、CRUD操作:
    ①select
    属性:id:这个statement的唯一标示
        parameterType:输入参数类型,可选参数,mybatis可以自动推断数据类型
        resultType:查询结果类型,如果结果是集合,请写集合内元素类型!
        resultMap:结果集映射,这个和resultType 只能存在1个,应对复杂的结果集
    ②insert、update和delete
    属性:id:这个statement的唯一标示
        parameterType:输入参数类型,可选参数,mybatis可以自动推断数据类型
    ③insert语句实现ID回写
    属性:useGenerateKeys:自增主键的回显功能,默认是false
    ④#{}的用法:预编译的占位符作用
        #{属性名} 表示占位,和参数名无关   用注解@Param时,和参数名有关。
        ${} 表示拼接,和参数类型无关
        一个参数时:基本类型或包装类、String类型、引用类型、HashMap类型
        多个参数时:如果有多个参数,请使用@Param注解来指定参数名称,代码可读性好
        #{0} #{1}、#{param1} #{param2}、#{userName} #{password} @Param
    ⑤${}的用法:${}底层其实使用的是OGNL表达式。

           a)${}获取参数的方式:无论是1个参数,还是多个参数,都使用@Param注解,然后通过注解的中指定的名称取值。

                一个参数时,MyBatis底层会把这个参数 以键为’value’的形式存入Map中,因此取值的时候,必须${value},或者通过@Param注解。

               多个参数时,此时必须以${param1}、${param2}方式或者@Param注解方式来获取参数。

           b)${}获取参数的问题:${}在取值时,并不会进行预编译,而是直接拼接SQL语句,无法防止SQL注入问题。

                                                ${}取值的时候,需要自己判断参数数据类型,如果是字符串,还得自己加引号:”${}”。
    ⑥面试题:#和$的区别与联系
        区别:
            1)#是占位符,会对SQL进行预编译,相当于?; $是做SQL拼接,有SQL注入的隐患
            2)#不需要关注数据类型,Mybatis自动实现类型转换。 $必须自己判断数据类型
        联系:
            两者都支持通过@Param注解 指定参数名称,来获取参数值。推荐这种方式!

3、ResultMap 结果集映射
    ①概述:定义SQL查询的结果与Java对象的映射关系。
    ②解决字段名与列名不一致问题方案3:column   property
    ③autoMapping自动映射:autoMapping="true"
4、SQL片段

七、动态SQL:
1、if
注意:
    在写SQL时,我们使用了”%${name}%”来拼接SQL,这样在传参数时,可以只写姓名
    这里也可以写#{name}来进行预编译,那么传参数时,就必须在参数中写上”%李%”了
2、choose,when,otherwise

        动态标签中有if,但是没有else,如果我们有多条件,就需要用choose标签

        choose中可以定义多个when和1个otherwise,所有状态中只能有一个成立:

        多个when类似与if 和 else if,otherwise类似于最后的else。

3、where增加条件
4、set修改时,判断字段非空和非null
5、foreach循环

八、缓存:
1、一级缓存:session级别缓存,作用于当前会话。
特点:
①mybatis的一级缓存默认就是开启的,并且无法关闭。
②mybatis的一级缓存作用域是当前session,一次openSession()后,如果相同的statement和相同参数,则不进行查询而是从缓存命中并且返回,如果没有命中则查询数据库。
③任何的增删改操作都会导致缓存被清空。
④缓存会使用 Least Recently Used(LRU,最近最少使用的)算法来收回。
2、二级缓存:SessionFactory级别缓存,作用于整个SessionFactory,多个会话之间可以共享缓存。
特点:
①二级缓存需要手动开启,开启的方式是在Mapper.xml中添加标签:<cache/>
②二级缓存的作用域是整个SessionFactory,如果namespace、statement和SQL参数一致,则缓存命中。

九、高级查询(表关联查询):
1、一对一查询
2、一对多查询
3、多对多查询
4、延迟加载:添加cglib依赖

十、有关xml中的特殊字符
1)使用特殊符合
2)使用CDATA

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值