Mybatis新手教程

80 阅读9分钟

前言

鉴于现在mabatis教程篇幅巨长 恰巧我最近刚学完此框架,于是有了这个简短快速上手的教程

Mybatis

相信大家都应该了解了什么是Mybatis以及它在Java开发中的重要性----若有不懂请移步至Mybatis[官MyBatis中文网方文档]()。

配置教程

pom.xml初始化

  • 打开idea创建maven项目

在这里插入图片描述

  • 找到pom.xml文件注入相关jar包 这三种都是必备jar包 MySQL连接数据库 junit用来调用相关注解测试

在这里插入图片描述

  • 定义资源文件的目录、包含规则和过滤行为 这个必须配置不要遗忘

    <project>
        <build>
            <resources>
                <!-- 处理 src/main/resources 目录 -->
                <resource>
                    <directory>src/main/resources</directory>
                    <includes>
                        <include>**/*.properties</include>
                        <include>**/*.xml</include>
                    </includes>
                    <filtering>true</filtering>
                </resource>
                <!-- 处理 src/main/java 目录 -->
                <resource>
                    <directory>src/main/java</directory>
                    <includes>
                        <include>**/*.properties</include>
                        <include>**/*.xml</include>
                    </includes>
                    <filtering>true</filtering>
                </resource>
            </resources>
        </build>
    </project>
    

配置config核心文件

  • 找到目录下resourse 创建config.xml和dp.properties config用来配置依赖属性 dp作为外部配置文件封装你的数据库信息

    <configuration><!--核心配置文件-->
    
        <!--1.引入外部配置文件-->
        <properties resource="dp.properties"/>
        
        <!--标准的日志工厂实现-->
        <settings>
            <setting name="logImpl" value="STDOUT_LOGGING"/>
            <!--是否开启驼峰(camel case)映射-->
            <setting name="mapUnderscoreToCamelCase" value="true"/>
    
        </settings>
    
    
        <!--给实体类起别名-->
        <typeAliases><typeAlias type="com.crm.pojo.User" alias="User"/> </typeAliases>
    
    
        <!--环境配置-->
        <environments default="development">
            <environment id="development">
                <transactionManager type="JDBC"/>
                <dataSource type="POOLED">
                    <property name="driver" value="${driver}"/>
                    <property name="url" value="${url}"/>
                    <property name="username" value="${username}"/>
                    <property name="password" value="${password}"/>
                </dataSource>
            </environment>
        </environments>
    
    
        <!--注意,每一个mapper.xml都需要在Mybatis核心配置文件中注册-->
        <mappers>
            <mapper resource="com/crm/dao/UserMapper.xml"/>
        </mappers>
    
    
    
    </configuration>
    
  • 环境配置中数据库属性已被配置到dp中 可以调用

在这里插入图片描述


创建实体

  • pojo存放实体类(例如User)

  • dao持久层(UserMapper UserMapper.xml)

  • utile工具类(MybatisUtils)

  • 创建数据库并连接,保障后面CRUD的进行

  • Test测试类

注意 mapper.xml注册路径必须保持一致 否则无法使用映射器

在这里插入图片描述


SqlSession

  • 每个基于 MyBatis 的应用都是以一个 SqlSessionFactory 的实例为核心的。SqlSessionFactory 的实例可以通过 SqlSessionFactoryBuilder 获得。在Mybatis中,SqlSession极为强大,甚至可以说它是Mybatis中最重要的部分,通过它你可以调用方法接口来执行映射器中的sql语句来操纵数据库,极大简化了老掉牙的jdbc繁琐的步骤

    下面是它的构建过程:打开工具类 用输入流的方式获得资源并构建 最后通过静态使它随类一起加载

在这里插入图片描述


属性

  • 名称空间 ,位于你的mapper.xml中,请指定自己的mappper接口

    <?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="com.crm.dao.UserMapper">//指定你的
    
  • 在config.xml中有一个固定的配置属性顺序 必须严格遵守否则会报错

在这里插入图片描述

  • typeAliases起别名,简化代码 常用于实体类型 在这里插入图片描述
<select id="getUserList" resultType="com.crm.pojo.User">
        select * from mybatis.user
    </select>
   
---------------------------------------------------------------
<select id="getUserList" resultType="User">
        select * from mybatis.user
    </select>

上述代码中第二段将返回类型com.crm.User取别名为User 减少了代码冗余

  • 这是 MyBatis 中极为重要的调整设置,它们会改变 MyBatis 的运行时行为。 下表描述了设置中各项设置的含义、默认值等。

在这里插入图片描述

想要了解更多设置请移步至配置文档

因为内容太多 篇幅不够 我这里只是简短说一下驼峰命名

<!--是否开启驼峰(camel case)映射-->
        <setting name="mapUnderscoreToCamelCase" value="true"/>

在这里插入图片描述

在mysql中我们常常遇到create_time这种带下划线的字段,这时候我们只要开启驼峰映射我们就能用createTime与之匹配

 <insert id="addBlog">
    insert into mybatis.blog (id, title, author, create_time, views) VALUES
    (#{id},#{title},#{author},#{createTime},#{views});
    </insert>

xml映射器

MyBatis 的真正强大在于它的语句映射,这是它的魔力所在。由于它的异常强大,映射器的 XML 文件就显得相对简单。如果拿它跟具有相同功能的 JDBC 代码进行对比,你会立即发现省掉了将近 95% 的代码。MyBatis 致力于减少使用成本,让用户能更专注于 SQL 代码。

简单的crud
  • 四个标签与sql语句的j基本含义是一样的

下面是一个简单的crud通过xml映射

 
    <!--查询用户-->
    <select id="getUserById" resultType="User" parameterType="int">
        select * from mybatis.user where id= #{id}
    </select>
    
    <!--添加用户-->
    <insert id="addUser" parameterType="User">
        insert into mybatis.user (id, name, pwd) VALUES (#{id},#{name},#{pwd});
    </insert>
    
    <!--修改用户 -->
    <update id="updateUser" parameterType="User">
        update mybatis.user set name = #{name} ,pwd = #{pwd} where id=#{id}
    </update>

    <!--删除用户-->
    <delete id="deleteUser" parameterType="int">
        delete from mybatis.user where id=#{id}
    </delete>
  • 关于# & $

    使用#{id},传入id执行sql语句时会先进行预编译参数 而不是简单的字符拼接,能够防止sql注入

    而${}是直接拼接字符串,安全性极低


    属性名与字段名不一致

    我们可以使用resultMap进行映射 例如:在User表中pwd表示密码 而在java我们将它设置为了password

    此时查出来用户密码则为为默认的null

    在这里插入图片描述

     
        <select id="getUserList" resultType="User">
            select * from mybatis.user
        </select>
        ----------------------------------------------------------
    

    此时只要通过resultMap映射就好 column代表表的字段 property是属性

在这里插入图片描述

在这里插入图片描述


动态sql
  • 什么是动态sql ?顾名思义就是指能够动态的拼接sql语句 从而避免编写大量重复代码

  • 有以下常用标签

    1. if:条件判断,满足时拼接sql

      <select id="findUser" resultType="User">
          select * from user 
          <where>
              <if test="name != null">
              and name = #{name}
              </if>
              <if test="age != null">
              and age = #{age}
              </if>      
          </where>
      </select>
      

      2.choose>/when/otherwise多条件选择,有时候,我们不想使用所有的条件,而只是想从多个条件中选择一个使用。针对这种情况,MyBatis 提供了 choose 元素,它有点像 Java 中的 switch 语句。

      <choose>
          <when test="name == 'admin'">
          and level > 10
          </when>
          <when test="name == 'user'">
          and level <= 10
          </when>
          <otherwise>
              and status = 1
          </otherwise>  
      </choose>
      

      依次进行条件筛选 直到出现一个条件满足就结束

      3.foreach遍历集合(批量操作)

      <select id="getUser" prameterTyper="map">
          select * from user
          <where>
          	<foreach collections="ids" item="id" open="(" separator="or" close=")">
                  id = #{id}
              </foreach>
          </where>
      </select>
      

      where:自动处理where后的首个and或or

      set:动态生成update语句中的字段

      trim可以自定义这些元素>

      <trim prefix="WHERE" prefixOverrides="AND |OR ">
        ...
      </trim>
      
模糊查询
  • concat用于将两个或多个字符串拼接 并且它会将null当做空字符串处理

  • %用做占位符

<select id="getUserLike" resultType="User">
        select * from mybatis.user where name like concat('%',#{value},'%')
    </select>
一对多与多对一
  • 一对多 查询一个学生的tid对应的多个老师
<!--按照结果查询-->
    <select id="getTeacher" resultMap="TeacherStudent">
        select s.id sid, s.name sname,t.name tname,t.id tid
        from mybatis.student s,mybatis.teacher t
        where s.tid = t.id and t.id=#{tid}
    </select>
    <resultMap id="TeacherStudent" type="Teacher">
        <result property="id" column="tid"/>
        <result property="name" column="tname"/>
        <collection property="students" ofType="Student">
            <result property="name" column="sname"/>
            <result property="id" column="sid"/>
            <result property="tid" column="tid"/>
        </collection>
    </resultMap>

 <!--********************************************************************************************-->
    <!--嵌套子查询-->
    <select id="getTeacher2" resultMap="TeacherStudent2">
        select * from mybatis.teacher where id = #{tid}
    </select>
    <resultMap id="TeacherStudent2" type="Teacher">
        <collection property="students" javaType="ArrayList" ofType="Student" column="id" select="getStudent">
        </collection>
    </resultMap>
    <select id="getStudent" resultType="Student">
        select * from mybatis.student where tid=#{tid}
    </select>

  • 多对 一 查询多个学生对应一个老师

    <!--按结果查询-->
        <select id="getStudent1" resultMap="StudentTeacher1">
            select t.name tname,s.id,s.name from mybatis.student s,mybatis.teacher t where s.tid = t.id
        </select>
        <resultMap id="StudentTeacher1" type="Student">
            <result column="id" property="id"/>
            <result column="name" property="name"/>
            <association property="teacher" javaType="Teacher">
                <result column="tname" property="name"/>
            </association>
        </resultMap>
    
    
        <!--嵌套子查询-->
        <select id="getStudent" resultMap="StudentTeacher">
            select * from mybatis.student
        </select>
        <!--查询学生信息 根据查询出来的tid寻找对应的老师-->
        <resultMap id="StudentTeacher" type="Student">
            <result property="id" column="id"/>
            <result property="name" column="name"/>
            <!--复杂的属性需要单独处理-->
            <!--集合用colletion 对象用association-->
            <association property="teacher" column="tid" javaType="Teacher" select="getTeacher"/>
        </resultMap>
        <select id="getTeacher" resultType="Teacher">
            select name from mybatis.teacher where id=#{tid}
        </select>
    
    
    

    日志

    日志(Log)是在计算机系统和应用程序中用于记录事件、错误、警告、调试信息或其他重要数据的一种机制。它是系统管理和故障排查的重要工具,能够帮助开发人员和系统管理员了解系统的运行状态、跟踪问题发生的原因,以及监控应用程序的行为。

    Mybatis 通过使用内置的日志工厂提供日志功能。内置日志工厂将会把日志工作委托给下面的实现之一:

    • SLF4J

    • Apache Commons Logging

    • Log4j 2

    • Log4j

    • JDK logging

    MyBatis 内置日志工厂会基于运行时检测信息选择日志委托实现。它会(按上面罗列的顺序)使用第一个查找到的实现。当没有找到这些实现时,将会禁用日志功能。

  • 不过当前学习阶段我们使用默认的log足矣

    在这里插入图片描述 如有其他需要,移步至更多日志配置


注解开发
  • 使用MyBatis提供的注解(如@Select、@Insert、@Update、@Delete等)来定义SQL语句。
  • 可以直接在接口上使用
  • 使用于简单的句子 一般不推荐用在复杂语句
public class User {
    private int id;
    private String name;
    private String email;
    // getters and setters
}

import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Mapper;

@Mapper
public interface UserMapper {

    // 使用@Select注解定义SQL查询
    @Select("SELECT * FROM users WHERE id = #{id}")
    User getUserById(int id);
}
SQL片段
  • 在MyBatis中,SQL片段(SQL Fragment)是一种重用SQL代码的机制。通过使用<sql>标签,你可以在MyBatis的映射文件(通常是XML文件)中定义一个SQL片段,然后在其他SQL语句中通过<include>标签来引用这个片段。这样做的好处是可以减少重复代码,提高SQL语句的可读性和可维护性。

    <sql id="userColumns">
        id, username, password, email, created_at, updated_at
    </sql>
    
    <select id="selectUserById" resultType="User">
        SELECT
            <include refid="userColumns"/>
        FROM users
        WHERE id = #{id}
    </select>
    

    refid属性用来指定引用的片段的id


缓存

一级缓存
  1. MyBatis的一级缓存是SQLSession级别的缓存,它是MyBatis框架的默认缓存机制。每一个SQLSession都有一个独立的一级缓存,用于缓存当前SQLSession中执行的查询结果。
  2. 当在SQLSession中执行查询操作时,MyBatis会首先检查一级缓存中是否存在相同的查询结果。
  3. 如果存在,则直接从缓存中返回结果,而不再执行实际的数据库查询。
  4. 如果缓存中不存在相应的查询结果,MyBatis会执行实际的数据库查询操作,并将查询结果存储在一级缓存中,以备后续相同查询使用。

执行了INSERT、UPDATE、DELETE等修改操作后,因为这些操作可能会改变数据状态,所以MyBatis会出于数据一致性的考虑,清空一级缓存。

手动调用SQLSession.clearCache()方法也会使一级缓存失效。

关闭当前的SQLSession也会导致一级缓存失效。

二级缓存
  • MyBatis的二级缓存是Mapper级别的缓存,它的生命周期与SQLSession无关,多个SQLSession可以共享同一个Mapper的二级缓存。相比于一级缓存,二级缓存提供了更广泛的缓存范围,但需要手动配置。默认情况下是关闭的,需要显式配置才能启用。

  • MyBatis的二级缓存是Mapper级别的缓存,它的生命周期与SQLSession无关,多个SQLSession可以共享同一个Mapper的二级缓存。相比于一级缓存,二级缓存提供了更广泛的缓存范围,但需要手动配置。默认情况下是关闭的,需要显式配置才能启用。

  • 和一级缓存类似,二级缓存也会在执行INSERT、UPDATE、DELETE操作时部分或全部失效。

    不过,二级缓存可以通过配置来调整其失效策略,例如设置失效时间、刷新条件等。

    总结:

    缓存范围:一级缓存是SQLSession级别的,适用于单个事务内多次相同查询的场景;二级缓存是Mapper级别的,适用于跨事务、频繁访问相同数据的场景。

    生命周期:一级缓存的生命周期是SQLSession的生命周期,二级缓存的生命周期与SQLSession无关。

    配置与使用:一级缓存默认开启且不需要额外配置;二级缓存需要显式配置才能启用。

    数据一致性:两者都会在执行修改操作时失效,但二级缓存可以通过配置来调整其失效策略。

    img转存失败,建议直接上传图片文件

结语 :

祝大家新春快乐 需要学习的道路还很长 我们要坚持住 相信成功就在前方!