美文网首页
MyBatis之学习总结

MyBatis之学习总结

作者: 叫我不矜持 | 来源:发表于2019-01-28 13:16 被阅读9次

    一.MyBatis是什么?

    MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis 。2013年11月迁移到Github。MyBatis是一个 半自动化的ORM框架(Object Relational Mapping对象关系映射--解决面向对象和数据库发展不一致的问题)

    ①根据MyBatis官方的定义,MyBatis是支持定制化SQL语句,存储过程,高级映射的持久层框架.

    ②MyBatis避免了几乎所有的JDBC代码和手动设置参数以及获取结果集的过程.

    ③MyBatis可以对配置和原生Map使用简单的XML或注解,将接口和Java的实体类映射成数据库的对应的记录.

    二.MyBatis的使用流程总结

    1.导入Jar包

    asm-3.3.1.jar (java文件解析包,spring需要用到这个包)

    cglib-2.2.2.jar(动态代理包,MyBatis通过动态代理,不需要编写Mapper接口的实现类)

    commons-loggin-1.1.1.jar (日志包,spring需要用到这个包)

    javassist-3.17.1-GA.jar (字节码解析助手包,处理.class文件)

    log4j-1.2.17.jar、logj-api-2.0-rc1.jar、log4j-core-2.0-rc1.jar(这三个包都是log4j日志包)

    mybatis-3.2.7.jar(mybatis核心包)

    slf4j-api-1.7.5.jar(日志包)

    slf4j-log4j12-1.7.5.jar(日志包)

    2.构建实体类pojo包下的实体类构建

    3.创建和配置mybatis.xml文件

    ①定义DTD文档约束(使用一系列合法的元素来定义文档结构)

    <!--DTD是提高书写代码的速度,提供了快捷提示  -->
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE configuration
     PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
    "http://mybatis.org/dtd/mybatis-3-config.dtd">

    ②配置configuration标签(根标签)

    ③配置其子标签,各子标签的作用如下

    <!-- 配置 -->
    <configuration>
     <!-- 配置属性文件路径 -->
     <properties resource="config.properties">
     </properties>
     <!-- 开启log4j的 -->
     <settings >
     <setting name="logImpl" value="LOG4J"/>
    <setting name="cacheEnabled" value="true"/>
     </settings>
     <!-- 设置实体类别名 -->
     <typeAliases>
     <!-- 别名 -->
     <!--<typeAlias type="com.bjsxt.pojo.Flower" alias="a"/> -->
     <!-- 声明包 resultType值为类名就行 (不区分大小写)-->
     <package name="com.bjsxt.pojo"></package>
     </typeAliases>
     <!-- 配置数据库 default属性表示要使用哪个数据库环境,值为environment 标签的id-->
     <environments default="mysql">
     <environment id="mysql">
     <!-- 配置数据库的事务管理 -->
     <transactionManager type="JDBC">
     <!-- type(JDBC|MANAGED) -->
     <!-- JDBC表示使用原生的事务管理器 -->
     <!-- MANAGED表示将事务管理交给容器管理,比如spring -->
     </transactionManager>
     <!-- 配置具体数据库参数 -->
     <dataSource type="POOLED">
     <!-- type为POOLED表示开启数据库连接池 -->
     <property name="url" value="${url}"/>
     <property name="username" value="${username}"/>
     <property name="password" value="${password}"/>
     <property name="driver" value="${driver}"/>
     </dataSource>
    </environment>
    </environments>
     <!-- 配置mapper文件 -->
    <mappers>
     <!-- resource mapper文件的路径,便于同一加载解析 -->
    引用url地址
    <mapper url="file:///e:/..../.../mybatis.xml"  />
    resource 切记:"/"的目录
    <mapper resource="com/bjsxt/mapper/FlowerDMLMapper.xml"  />
     <package name="com.bjsxt.mapper"/>
     </mappers>
    </configuration>

    4.创建和配置mapper.xml标签

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE mapper
    PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
    "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

    <mapper namespace="包名.接口的名称">
    <!-- id: 方法名称 resultType:返回值类型 如果返回的是一个对象,就写对象的实体即可 如果返回的是一个集合。书写集合的泛型的类型即可 parameterType:参数的类型 -->
    <!--如果configuration中配置了typeAlias写别名即可,如果配置了package只写类名即可,不区分大小写-->
    <select id="selectAll" resultType="com.bjsxt.pojo.Flower"> select * from flower </select>
    </mapper> 

    5.使用SqlSession的对象完成数据库操作

    ①获取读取mybatis.xml文件,获得配置文件输入流对象
    InputStream is = Resources.getResourceAsStream("mybatis.xml");

    ②获取SqlSessionFactory工厂对象(通过实例化SqlSessionFactoryBuilder调用Builder方法,传入配置文件输入流对象,获取)
    SqlSessionFactroy factory = new SqlSessionFactroyBuilder().build(is);

    ③获取SqlSession对象
    SqlSession sqlSession = factory.openSession();

    ④使用sqlSession对象完成对数据库的操作
    insert/update/delete
    -----select的方法有很多----------------
    MyBatis最初提供的API的方法有
    selectOne("namespace+statementId",parameter)
    selectList("namespace+statementId",parameter)
    selectMap("namespace+statementId",parameter,key) 需要指定key为数据库的哪一个字段

    ⑤commit或者rollback,最后close关闭SqlSession

    6.配置setting开启log4j的支持

    MyBatis使用日志的最大的作用:
    ①就是为了方法的输出后台执行的sql语句和参数传递的变化过程,方便开发人员的调试
    ②可以把指定的日志信息按照规定的格式保存到本地文件中

    log4j的五种级别
    ①FATAL
    ②ERROR
    ③WARN
    ④INFO
    ⑤DEBUG

    在log4j.properties配置文件中配置
    log4j.logger.com.xxxx.mapper=debug/trace         (log4j.logger+包名---即以该包名开头的所有的命名空间都用debug或者trace级别记录日志)

    8.注意事项

    ①#{ }相当于展位操作
    ②${ }相当于拼接,无法应对sql注入攻击
    ③#{0}  #{param1}  获得下标为0的参数
    ④如果传入的参数只有一个,且类型为引入数据类型,非包装类或者String,不能使用#{0.name} #{param1.name}获取值,可以直接#{name},或者给该      参数在接口中添加注解,声明别名如:  List<Flower> select(@Param("f")Flower flower)
    ⑤select必须要声明返回值类型及resultMap或者resultType,DML语句不需要再标签中声明,因为返回的都是int
    ⑥标签中的parameterType可以省略,在底层会自动匹配参数类型,如果写了但写错了,会报错
    ⑦resultType如果为Map,sqlSession调用了selectMap()的方法,会自动生成一个类去存放所对应的数据库的字段值,和你声明的实体类无关,因此不能强转,否则会报错,但如果resultType为实体类如Flower,调用了selectMap()生成的value值得真实类型就是Flower了,可以强转,select底层都是调用了selectList方法

    三.MyBatis的SQL动态拼接

    1.if标签

    <if test="param1!=null and param1!='' ">
    </if>

    2.where标签

    自动在前面加上where,同时去除第一个and
    <where>
    </where>

    3.choose when otherwise标签

    相当于else if()只执行一个,后续都不执行
    <choose>
            <when test="">

            </when>
            <otherwise>

            </otherwise>

    </choose>

    4.set标签
    自动补充set关键字,并且把最后逗号去掉(只能用于update标签中)

    <set>
        <if>
        </if>
    </set>

    5.trim标签

    去除前缀后缀及添加前缀后缀----------功能十分强大
    <trim prefix="set" suffixOverrides=",">
    </trim>
    prefix增加前缀  prefixOverrides去除前缀
    suffix增加后缀   sufffixOverrides去除后缀

    6.foreach标签

    open开始  close结束  separator分割 item把每一个值赋予item
    <foreach collection="list/array" open="(" close=")" separator="," item="it">
        #{it}
    </foreach>

    7.bind标签

    用于模糊查询
    <bind name="pa" value="'%'+param1+'%'"></bind>

    8.sql标签

    sql使用*效率非常低  可以使用sql配置替代*    ------------把相同的代码的内容提取出来
    <sql id="..">
    id,name,price
    </sql>

    9.include

    INCLUDE引入SQL片段使用的标签
    <include refid="sql的id"></include>

    四.多表联合查询

    1.resultMap的三个使用场景

    ①数据库的字段名和实体中的属性名

    ②N+1查询的时候 (注意:书写的两个表中的公共字段不可以省去)

    ③多表查询的sql语句的时候 (注意:即使字段名称一致也不可以省去)

    2.什么时候使用 resultType 什么时候使用resultMap

    ①单表的查询的时候resultType

    ②数据库的字段和实体的属性不一致resultMap

    ③多表查询的sql语句的时候resultMap

    3.业务代码方式和N+1方式的区别和联系

        联系:

              无论使用哪一种方式执行的sql语句都是N+1条

        不同点:

              业务代码:两个表的联系是使用java代码的方式进行关联的 

              N+1方式:mybatis标签的配置

    4.示例

    多对一的多表查询的sql语句
    <resultMap id="rm1" type="student">
    <id column="id" property="id"></id>
    <result column="name" property="name"></result>
    <result column="password" property="password"></result>
    <result column="clazz" property="clazz"></result>
    <association property="cla" javaType="Clazz" >
    <id column="cid" property="id"></id>
    <result column="cname" property="name"></result>
    </association>
    </resultMap>

    一对多的多表查询sql语句
    <resultMap type="clazz" id="rm2">
     <id column="id" property="id"></id>
     <result column="name" property="name"></result>
     <collection property="stuList" ofType="student">
     <id column="sid" property="id"></id>
     <result column="sname" property="name"/>
     <result column="sage" property="age"/>
     <result column="sclazz" property="clazz"/>
     </collection>
     </resultMap>
    注意:即使字段名称一致也不可以省去 

    N+1方式的多表查询
    如果是N+1方式跟上面两种方式差不多,但是在collection中和association中需要指定select(namespace+statementId或者自己写sql语句) ,还有要指定column,以指定的column为参数进行查询;column和你执行的sql语句要有关系;
    注意:书写的两个表中的公共字段不可以省去  

    五.mybatis中的注解

    mubatis中的注解:

    注解的出现就是为了简化XML 的操作

          @Select("select *  from student")

    public  List<Student>  findAll();

    @Select("select *  from  student  where  sid =#{0}")

    public  Student  findOne(int  sid);

    @Insert("insert into  student  values(default,#{sname},#{pwd},#{clazzno})")

    public  int  insert(Student stu);

    @Update("update  student  set  sname = #{sname}  where  sid=#{sid}")

    public  int update(Student  stu);

    @Delete("delete  from  student  where sid =#{0}")

        public  int  delete(int sid);

    注解的缺点:

      [1]多表的查询支持操作不完善

      [2]使用XML的目的是实现java和SQL语句的问题

      [3]使用注解的使用必须保证  实体中的属性和数据库的字段必须一致

    六.Mybatis的运行原理

    1. 运行过程中涉及到的类


    1.1 Resources MyBatis中IO流的工具类

    1.1 加载配置文件

    1.2 SqlSessionFactoryBuilder() 构建器

    1.2.1 作用:创建SqlSessionFactory接口的实现类

    1.3 XMLConfigBuilder  MyBatis全局配置文件内容构建器类

    1.3.1 作用负责读取流内容并转换为JAVA代码.

    1.4 Configuration 封装了全局配置文件所有配置信息.

    1.4.1 全局配置文件内容存放在Configuration中

    1.5 DefaultSqlSessionFactory 是SqlSessionFactory接口的实现类

    1.6 Transaction 事务类

    1.6.1 每一个SqlSession会带有一个Transaction对象.

    1.7 TransactionFactory 事务工厂

    1.7.1 负责生产Transaction

    1.8 Executor  MyBatis执行器

    1.8.1 作用:负责执行SQL命令

    1.8.2 相当于JDBC中statement对象(或PreparedStatement或CallableStatement)

    1.8.3 默认的执行器SimpleExcutor

    1.8.4 批量操作BatchExcutor

    1.8.5 通过openSession(参数控制)

    1.9 DefaultSqlSession 是SqlSession接口的实现类

    1.10 ExceptionFactory MyBatis中异常工厂

    2.流程解释

    在MyBatis运行开始时需要先通过Resources加载全局配置文件.下面需要实例化SqlSessionFactoryBuilder构建器.帮助SqlSessionFactory接口实现类DefaultSqlSessionFactory.

    在实例化DefaultSqlSessionFactory之前需要先创建XmlConfigBuilder解析全局配置文件流,并把解析结果存放在Configuration中.之后把Configuratin传递给DefaultSqlSessionFactory.到此SqlSessionFactory工厂创建成功.

    由SqlSessionFactory工厂创建SqlSession.

    每次创建SqlSession时,都需要由TransactionFactory创建Transaction对象,同时还需要创建SqlSession的执行器Excutor,最后实例化DefaultSqlSession,传递给SqlSession接口.

    根据项目需求使用SqlSession接口中的API完成具体的事务操作.

    如果事务执行失败,需要进行rollback回滚事务.

    如果事务执行成功提交给数据库.关闭SqlSession

    -------------------------------------------------------------------------------------------
    ps:下一节会对mybatis的缓存机制进行总结

    相关文章

      网友评论

          本文标题:MyBatis之学习总结

          本文链接:https://www.haomeiwen.com/subject/hyunjqtx.html