MyBatis基本使用

作者: So_ProbuING | 来源:发表于2019-11-24 01:20 被阅读0次

    MyBatis

    MyBatis简介

    MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis,实质上Mybatis对ibatis进行一些改进。 MyBatis是一个优秀的持久层框架,它对jdbc的操作数据库的过程进行封装,使开发者只需要关注 SQL 本身,而不需要花费精力去处理例如注册驱动、创建connection、创建statement、手动设置参数、结果集检索等jdbc繁杂的过程代码。

    MyBatis是一个优秀的持久层框架,它对jdbc的操作数据库的过程进行封装,使开发者只需要关注 SQL 本身,而不需要花费精力去处理例如注册驱动、创建connection、创建statement、手动设置参数、结果集检索等jdbc繁杂的过程代码。

    MyBatis原理

    原理:Mybatis通过xml或注解的方式将要执行的各种statement(statement、preparedStatemnt、CallableStatement)配置起来,并通过java对象和statement中的sql进行映射生成最终执行的sql语句,最后由mybatis框架执行sql并将结果映射成java对象并返回。

    MyBatis的框架核心

    • MyBatis配置文件,包括 Mybatis全局配置文件和Mybatis映射文件,其中全局配置文件配置了数据源、事务等信息,映射文件配置了SQL执行相关的信息

    • MyBatis通过读取配置文件信息(全局配置文件和映射文件),构造出SqlSessionFactory(会话工厂)

    • 通过SqlSessionFactory,可以创建SqlSession即会话。Mybatis是通过SqlSession来操作数据库的。

    • SqlSession本身不能直接操作数据库,它是通过底层的Excutor执行器接口来操作数据库。

    • Executor执行器要处理的SQL信息是封装到一个底层对象MappedStatement中。该对象包括:SQL语句、输入参数映射信息、输出结果映射信息。输入参数和输出结果的映射类型包括HashMap集合对象、POJO对象类型

    Mybatis入门

    下载MyBatis

    下载地址:https://github.com/mybatis/mybatis-3/releases

    • 导包

    • 创建全局配置文件SqlMapConfig.xml

    • 编写映射文件

    • 在SqlMapConfig.xml中加载映射文件

    • 编写测试程序

    • 配置文件

    <?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>
    <!-- 配置mybatis的环境信息 -->
    <environments default="development">
     <environment id="development">
     <!-- 配置JDBC事务控制,由mybatis进行管理 -->
     <transactionManager type="JDBC"></transactionManager>
     <!-- 配置数据源,采用dbcp连接池 -->
     <dataSource type="POOLED">
     <property name="driver" value="com.mysql.jdbc.Driver"/>
     <property name="url" value="jdbc:mysql://localhost:3306/mybatis?useUnicode=true&amp;characterEncoding=utf8"/>
     <property name="username" value="root"/>
     <property name="password" value="123456"/>
     </dataSource>
     </environment>
    </environments>
    </configuration>
    
    • 映射文件
    <?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">
    <!-- 
     namespace:命名空间,它的作用就是对SQL进行分类化管理,可以理解为SQL隔离
     注意:使用mapper代理开发时,namespace有特殊且重要的作用
     -->
    <mapper namespace="test">
     <!-- 
     [id]:statement的id,要求在命名空间内唯一
     [parameterType]:入参的java类型
     [resultType]:查询出的单条结果集对应的java类型
     [#{}]: 表示一个占位符?
     [#{id}]:表示该占位符待接收参数的名称为id。注意:如果参数为简单类型时,#{}里面的参数名称可以是任意定义
     -->
     <select id="findUserById" parameterType="int" resultType="com.gyf.domain.User">
     SELECT * FROM USER WHERE id = #{id}
     </select>
    </mapper>
    
    • 配置文件加载映射文件 在配置文件中添加<mappers>标签 子标签<mapper resource指定映射文件地址

    • 测试程序

    /读取配置文件
        InputStream is = Resources.getResourceAsStream("SqlMapConfig.xml");
        //通过SqlSessionFactoryBuilder创建SqlSessionFactory会话工厂
        SqlSessionFactory ssf = new SqlSessionFactoryBuilder().build(is);
        //通过SqlSessionFactory创建SqlSession
        SqlSession session = ssf.openSession();
        //调用SqlSession的操作数据库方法
        User user = session.selectOne("findUserById",2);
        //关闭sqlsession 释放资源
        session.close();
    

    查询案例

    模糊查询

    <!-- 
     [${}]:表示拼接SQL字符串
     [${value}]:表示要拼接的是简单类型参数。
     注意:
     1、如果参数为简单类型时,${}里面的参数名称必须为value 
     2、${}会引起SQL注入,一般情况下不推荐使用。但是有些场景必须使用${},比如order by ${colname}
     -->
     <select id="findUserByName" parameterType="String" resultType="com.gyf.domain.User">
     SELECT * FROM USER WHERE username like '%${value}%'
     </select>
    
    • 查询
    List<User> list = session.selectList("findUserByName","t");
    

    插入

    <insert id="insertUser" parameterType="com.xxx.xxx.User">
     INSERT INTO USER(username,sex,birthday,address) VALUES(#{name},#{sex},#{birthday},#{address})
    </insert>
    
    session.insert("insertUser",new User(...));
    session.commit();
    

    删除

    <delete id="deleteUser" parameterType="int">
     DELETE FROM USER WHERE id=#{id}
    </delete>
    
    
    session.delete("deleteUser",1);
    

    更新

    <update id=“updateUser” parameterType="com.xxx.xxx.User">
     Update From User SET username=#{username},sex=#{sex} WHERE id=#{id}
    </update>
    
    session.update("updateUser",user);
    

    主键返回之MySQL自增主键

    我们可以通过MySQL的函数获取到刚插入的自增主键

    LAST_INSERT_ID()

    <insert id="insertUser" parameterType="com.gyf.domain.User">
     <!-- 
     [selectKey标签]:通过select查询来生成主键
     [keyProperty]:指定存放生成主键的属性
     [resultType]:生成主键所对应的Java类型
     [order]:指定该查询主键SQL语句的执行顺序,相对于insert语句
     [last_insert_id]:MySQL的函数,要配合insert语句一起使用 -->
     <selectKey keyProperty="id" resultType="int" order="AFTER">
     SELECT LAST_INSERT_ID()
     </selectKey>
     <!-- 如果主键的值是通过MySQL自增机制生成的,那么我们此处不需要再显示的给ID赋值 -->
     INSERT INTO USER (username,sex,birthday,address) 
     VALUES(#{username},#{sex},#{birthday},#{address})
    </insert>
    

    主键返回之MySQL自增UUID

     <selectKey keyProperty="id" resultType="String" order="BEFORE">
     SELECT UUID()
     </selectKey>
     INSERT INTO USER (username,sex,birthday,address) 
     VALUES(#{username},#{sex},#{birthday},#{address})
    </insert>
    

    MyBatis使用Mapper接口代理方式 实现Dao

    Mapper代理的开发模式,程序员只需要编写mapper接口(dao接口)。Mybatis会自动为mapper接口生成动态代理实现类

    开发规范

    1. mapper接口的全限定名要和mapper映射文件的namespace的值相同

    2. mapper接口的方法名称要和mapper映射文件中的statement的id相同

    3. mapper接口的方法参数只能有一个,且类型要和mapper映射文件中的statement的parameterType的值保持一致

    4. mapper接口的返回值类型要和mapper映射文件中的statement的resultType值或resultMap中的type值保持一致

    全局配置文件其他配置

    properties数据库文件配置

    Mybatis可以允许独立配置数据库文件

    在src下配置个db.properties文件

    driverClass=com.mysql.jdbc.Driver
    url=jdbc:mysql:///mybatisdb
    username=root
    password=123456
    

    修改Mybatis全局配置文件 sqlMapConfig.xml

    <configuration>
     <!-- 添加外部配置文件 -->
     <properties resource="db.properties"/>
     ...
     <dataSource type="POOLED">
     <property name=driver value=#{driver} #配置文件中的配置名
    
     </dataSource>
     ...以下代码省略
    </configuration>
    

    typeAliases 别名

    别名是使用为了在映射文件中,更方便的去指定参数和结果集的类型,不用再写很长的全限定名

    mybatis支持的别名

    别名 映射的类型
    _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

    自定义别名

    <configuration>
     <!-- 指定自定义别名 -->
     <typeAlias type="com.xxx.xxx.User" alias="user"/>
     <!-- 批量设置别名-->
     <!--[name]:指定批量定义别名的类包,别名为该包下的类名 -->
     <package name="com.xxx.xxx"/>
    </configuration>
    

    mappers加载映射文件的几种方式

    <mapper resource=""/>
    <mapper url=""/> 几乎不用 完全限定路径
    <mapper class=""/> 接口的类全限定名
    

    Mybatis的映射文件

    输入映射ParameterType

    指定输入参数的Java类型,可以使用别名或者类的全限定名 可以接收 简单类型POJO对象HashMap

    输入映射resultType/resultMap

    • resultType

      • 使用resultType结果进行映射时,查询的列名和映射的POJO属性名完全一致,该列才能映射成功

        • 如果查询的列名和映射的pojo属性名全部不一致,则不会创建pojo对象

        • 如果查询的列名和映射的pojo属性名有一个一致,就会创建pojo对象

    • 输出简单类型

      • 当输出结果只有一列时,可以使用ResultType指定简单类型作为输出结果类型

    动态SQL

    If和where

    if标签

    if标签 作为判断入参来使用,如果符合条件,则把if标签体内的SQL拼接上。

    • UserMapper.xml
    <select id="findGeneral" resultType="user">
            SELECT * FROM tb_user WHERE 1=1
            <if test="name !=null and name != ''">
                AND name=#{name}
            </if>
            <if test="email !=null and email!=''">
                AND email=#{email}
            </if>
        </select>
    

    where标签

    Where标签:会去掉条件中的第一个and符号

    <select id="findGeneralwhere" resultType="user">
            SELECT * FROM tb_user
            <where>
                <if test="name !=null and name !=''">
                    AND name=#{name}
                </if>
                <if test="email !=null and email !=''">
                    AND email=#{email}
                </if>
            </where>
        </select>
    

    choose标签

    相当于java中的if...else if...else语句结构

    sql =  select  *  from user  where  1=1 
    if(  name  !=   null ){
    and name = #{}
    }else if( email  != null){
    and email = #{}
    }else{
    and 1=2
    }
    
    • choose标签
    <select id="findGeneralChoose" resultType="user">
            SELECT * FROM tb_user
            <where>
                <choose>
                    <when test="name !=null and name!=''">
                        AND name = #{name}
                    </when>
                    <when test="email !=null and email!=''">
                        AND email=#{email}
                    </when>
                    <otherwise>
                        and 1=2
                    </otherwise>
                </choose>
            </where>
    
        </select>
    

    set用于update语句

    <select id="updateGeneralSetUpdate" resultType="user">
            UPDATE tb_user
            <set>
                <if test="name !=null and name!=''">
                    name = #{name},
                </if>
                <if test="email !=null and email!=''">
                    email=#{email},
                </if>
            </set>
            where uid=#{uid}
        </select>
    

    SQL片段

    Mybatis提供SQL片段的功能可以提高SQL的可重用性

    SQL片段需要使用<sql id="片段名称">使用时 使用<include refid="片段名称">

    foreach遍历

    使用集合

    <!--collection 表示参数的名称 如果是直接传入集合参数 此处只能填写[list|collection]-->
    <!--item 每次遍历出来的对象-->
    <!--open 开始遍历时拼接的串-->
    <!--close 结束遍历时拼接的串-->
    <!--separator 遍历出的每个对象之间需要拼接的字符-->
      <select id="findByUserIds" resultType="user">
            SELECT * FROM tb_user where uid IN 
            <foreach collection="collection" item="var" separator=","
                     open="(" close=")">
                #{var}
            </foreach>
        </select>
    

    使用数组

    • 使用数组参数名称必须为array
    <select id="findByUserIdsArr" resultType="user">
            SELECT * FROM tb_user WHERE uid IN
            <foreach collection="array" separator="," open="(" close=")" item="var">
                #{var}
            </foreach>
        </select>
    

    mybatis与hibernate的区别

    Mybatis技术特点

    • 好处

    通过直接编写SQL语句,可以直接对SQL进行性能的优化;

    学习门槛低,学习成本低。只要有SQL基础,就可以学习mybatis,而且很容易上手;

    由于直接编写SQL语句,所以灵活多变,代码维护性更好。

    • 缺点

    不能支持数据库无关性,即数据库发生变更,要写多套代码进行支持,移植性不好。

    Mysql:limit

    Oracle:rownum

    需要编写结果映射。

    Hibernate技术特点

    • 好处

    标准的orm框架,程序员不需要编写SQL语句。

    具有良好的数据库无关性,即数据库发生变化的话,代码无需再次编写。

    以后,mysql数据迁移到oracle,只需要改方言配置

    • 缺点:

    学习门槛高,需要对数据关系模型有良好的基础,而且在设置OR映射的时候,需要考虑好性能和对象模型的权衡。

    程序员不能自主的去进行SQL性能优化。

    相关文章

      网友评论

        本文标题:MyBatis基本使用

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