1.参考官方中文文档

2.参考视频

快速入门

1.pom.xml文件中添加依赖

参考maven仓库地址需要什么依赖查找即可

  1. 添加mybatis依赖
<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis</artifactId>
    <version>3.5.7</version>
</dependency>

  1. 添加MySQL驱动依赖
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.26</version>
</dependency>
  1. 另外在pom.xml文件中还需要加上 标签(资源插件)
<build>
 
<!--资源插件:处理src/main/java目录中的xml-->
<resources>
    <resource>
        <directory>src/main/java</directory>
        <includes>
            <include>**/*.xml</include>
            <include>**/*.properties</include>
        </includes>
        <filtering>false</filtering>
    </resource>

    <!--原有资源路径-->
    <resource>
        <directory>src/main/resources</directory>
        <includes>
            <include>**/*.xml</include>
            <include>**/*.properties</include>
        </includes>
        <filtering>false</filtering>
    </resource>

</resources>
</build>
2.在dao包下创建sql映射文件(最好与dao包下的接口名一致)
  1. 负责编写与接口方法对应的sql语句
3.在resources目录下创建主配置文件
  1. 负责连接数据库
  2. 指定sql映射文件的位置
4.创建SqlSession类型的对象
  1. 通过该类的对象调用方法执行sql语句
5,使用mybatis读取MySQL数据库student表中数据,往该表中插入数据的例子

image.png

  1. pom.xml文件如下:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>module_dbs</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>
<!--        spring依赖-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.3.10</version>
        </dependency>
<!--        junit依赖-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13.1</version>
            <scope>test</scope>
        </dependency>
<!--        mybatis依赖-->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.7</version>
        </dependency>
<!--        MySQL驱动依赖-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.26</version>
        </dependency>
    </dependencies>
    <build>
       <resources>
           <!-- 资源插件-->
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.xml</include>
                    <include>**/*.properties</include>
                </includes>
                <filtering>false</filtering>
            </resource>

            <!--原有资源路径-->
            <resource>
                <directory>src/main/resources</directory>
                <includes>
                    <include>**/*.xml</include>
                    <include>**/*.properties</include>
                </includes>
                <filtering>false</filtering>
            </resource>

        </resources>

    </build>
</project>
  1. StudentDao.xml(mapper文件)文件如下:
<?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.nrvcer.dao.StudentDao">
    <select id="selectStudents" resultType="com.nrvcer.entity.Student">
        select * from student order by NO
    </select>
    <insert id="insertStudents">
        insert into student values(#{no}, #{pwd}, #{name},#{sex}, #{age},#{major},#{cls}, #{contactInfo})
    </insert>
</mapper>
  1. mybatis主配置文件如下:
<?xml version="1.0" encoding="UTF-8" ?>
<!--Mybatis的主配置文件-->
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <!--设置日志,将日志输出到控制台,有利于开发人员调试-->
    <settings>
        <setting name="logImpl" value="STDOUT_LOGGING"/>
    </settings>
    <!--配置Mybatis环境 -->
    <environments default="MySQL">
        <!-- id表示数据源的名称-->
        <environment id="MySQL">
            <!-- 配置事务类型:使用JDBC事务-->
            <transactionManager type="JDBC"/>
            <!--配置数据源DataSource:创建数据库的连接Connection对象
                属性type:其值POOLED表示使用数据库的连接池
            -->
            <dataSource type="POOLED">
                <!--连接数据库的四要素
                    driver:驱动内容
                -->
                <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
                <!--连接数据库的url-->
                <property name="url" value="jdbc:mysql://localhost:3306/ssm?useUnicode=true&amp;characterEncoding=utf-8"/>
                <!--用户名-->
                <property name="username" value="root"/>
                <!--密码-->
                <property name="password" value="123456"/>
            </dataSource>
        </environment>
    </environments>

    <!--指定其他mapper文件的位置
        目的是找到其他mapper文件的sql语句
    -->
    <mappers>
        <!--使用mapper的resource属性指定mapper文件的路径
            这个路径是从target/classes路径开启的
            使用注意:resource="mapper"文件的路径,使用 / 分割路径
            一个resource指定一个mapper文件
        -->
        <mapper resource="com/nrvcer/dao/StudentDao.xml"/>
    </mappers>
</configuration>

note:jdbc:mysql://localhost:3306/secs?useUnicode=true&characterEncoding=utf-8表示支持中文的URL
4. MyBatis工具类 如下(用于获取SqlSession类型的对象,避免代码重复)

package utils;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.apache.ibatis.session.SqlSessionFactory;

import java.io.IOException;
import java.io.InputStream;

public class MybatisUtil {
    // SqlSessionFactory类型的对象,创建该对象耗时长,占用资源多,整个项目中有一个就够用了
    private static SqlSessionFactory factory = null;

    static {
        String config = "mybatis.xml";

        try {
            // Resource负责读取配置文件
            InputStream in = Resources.getResourceAsStream(config);
            factory =  new SqlSessionFactoryBuilder().build(in);
        } catch (IOException e) {
            factory = null;
            e.printStackTrace();
        }
    }

    //获取SqlSession的方法
    public static SqlSession getSqlSession() {
        SqlSession sqlSession = null;
        sqlSession = factory.openSession();
        return sqlSession;
    }
}

  1. StudentDao接口如下:
package com.nrvcer.dao;

import com.nrvcer.entity.Student;

import java.util.List;

public interface StudentDao {
    List<Student> selectStudents();
    int insertStudents(Student student);
}

  1. 测试类如下:
import com.nrvcer.dao.StudentDao;
import com.nrvcer.entity.Student;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;
import utils.MybatisUtil;

import java.util.List;

public class DaoTest {
    @Test
    public void selectStudentsTest() {
        SqlSession session = MybatisUtil.getSqlSession();
        // 通过动态代理的技术自动创建Dao接口的实现类。
        StudentDao mapper = session.getMapper(StudentDao.class);
        //com.sun.proxy.$Proxy6
        System.out.println(mapper.getClass().getName());
        List<Student> students = mapper.selectStudents();
        for (Student student : students) {
            System.out.println(student);
        }
        session.close();
    }
    @Test
    public void insertStudentsTest() {
        SqlSession session = MybatisUtil.getSqlSession();
        StudentDao mapper = session.getMapper(StudentDao.class);
        Student student = new Student("2", "2", "2", "2", "2", "2", "2", "2");
        int i = mapper.insertStudents(student);
        System.out.println("插入的成功记录:" + i);
        // 提交事务
        session.commit();
        session.close();
    }
}

2.配置日志

在mybatis的主配置文件mybatis.xml文件中增加如下内容:
<settings>
    <!--配置日志信息。将日志输出到控制台-->
    <setting name="logImpl" value="STDOUT_lOGGING"/>
</settings>

3.动态代理技术自动创建Dao接口的实现类对象

Mybatis框架不用程序员自定义Dao的实现类,直接定位到映射文件Mapper中的相应SQL语句,对DB进行操作。这种对Dao的实现方式称为Mapper的动态代理方式。Mapper动态代理方式无需程序员实现Dao接口,接口是由Mybatis结合映射文件自动生成的动态代理实现的。

1.通过SqlSession类的getMapper()方法获取代理对象(即指定接口的实现类对象)
// 关键方法:SqlSession类的getMapper()方法
// 参数为指定 Dao接口类的 class 值。
 StudentDao dao = sqlSession.getMapper(StudentDao.class);

4.Mybatis传递参数

从 java 代码中把参数传递到 mapper.xml 文件。

1.一个简单的数据类型的参数传递(一个简单类型的参数)

如何将简单类型(包括基本数据类型和String)的参数传递到mapper文件中。

// 占位符使用#{任意字符}
List<Student> selectStudentsByNo( String number);
<select id="selectStudentsByNo" resultType="com.nrvcer.entity.Student">
        <!--number是自定义的变量名称,与方法参数名无关 -->
        select No,Pwd,Name from student where NO=#{number}
</select>

// mapper即为生成的动态代理对象
List<Student> students = mapper.selectStudentsByNo("1");
2.多个参数的传递方式
  1. 使用@Param("自定义参数名")命名参数。在方法形参前面加入@Param("自定义参数名"),mapper文件中使用#{自定义参数名}
List<Student> selectStudentsByNameOrAge(@Param("myname") String name, @Param("myage") String age);

<!--mapper文件中使用#{自定义参数名} -->
<select id="selectStudentsByNameOrAge" resultType="com.nrvcer.entity.Student">
        select No,Pwd,Name,Age from Student where Name=#{myname} or Age=#{myage}
</select>
List<Student> students = mapper.selectStudentsByNameOrAge("张三", "23");
  1. 对象传参
List<Student> selectMultiObject(Student student);

<select id="selectMultiObject" resultType="com.nrvcer.entity.Student">
        select No,Pwd,Name,Age from student where
        Name=#{name,javaType=java.lang.String,jdbcType=VARCHAR}
        or Age=#{age,javaType=java.lang.String,jdbcType=VARCHAR}
</select>

<!--javaType和jdbcType的类型MyBatis的类型可以检测出来,所以一般不需要设置 -->

List<Student> students = mapper.selectMultiObject(student1);
  1. 多参数按位置传参:参数位置从 0 开始, 引用参数语法 #{ arg 位置 } , 第一个参数是#{arg0}, 第二个是#
List<Student> selectStudentsByNameOrAge(String name, String age);

<select id="selectStudentsByNameOrAge" resultType="com.nrvcer.entity.Student">
        select No,Pwd,Name,Age from Student where Name=#{arg0} or Age=#{arg1}
</select>
List<Student> students = mapper.selectStudentsByNameOrAge("张三", "23");
  1. 多参数使用Map
Map 集合可以存储多个值,使用Map向 mapper 文件一次传入多个参数。Map 集合使用 String的 key,
Object 类型的值存储参数。 mapper 文件使用 # { key } 引用参数值。

掌握12,其他了解

$和#的区别

  1. #:占位符,告诉mybatis使用实际的参数值代替。并使用 PrepareStatement 对象执行 sql 语句, #{…}代替sql 语句的“?”。这样做更安全,更迅速,通常也是首选做法。
  2. $ 字符串替换,告诉mybatis使用$包含的“字符串”替换所在位置。使用Statement把sql语句和${}的内容连接起来。主要用在替换表名,列名,不同列排序等操作。
// 指定使用不同的列名作为查询条件
List<Student> selectStudentsByField(@Param("col")String columnName, @Param("cval") Object value);

<select id="selectStudentsByField" resultType="com.nrvcer.domain.Student">
--         select * from student where ${arg0} = #{arg1}
        select * from student where ${col} = #{cval}
</select>

// 使用$
select * from student where name = ?
// 使用#
select * from student where ? = ?

封装MyBatis处理结果

1.resultType

resultType:执行sql得到ResultSet转换的类型,其属性值使用类型的完全限定名或者别名。note:如果返回的是集合,那么应该设置为集合包含的类型

List<Student> selectStudents();

<select id="selectStudents" resultType="com.nrvcer.domain.Student">
        select id,name,email,age from student
</select>
2.resultMap

resultMap:可以自定义SQL语句的结果和Java对象属性的映射关系。更灵活的将列值赋值给指定属性,常用在列名和Java对象属性名不一样的情况。

List<Student> selectStudentByNameOrAge(@Param("name") String name, @Param("age") Integer age);

<!-- 创建 resultMap
 id属性:自定义的唯一名称,在<select>使用
 type属性:期望转为的 java 对象的全限定名称或别名
-->
<resultMap id="selectMap" type="com.nrvcer.domain.Student">
    <!-- 主键字段使用id标签-->
    <id column="id" property="stuId"></id>
    <!-- 非主键字段使用result标签-->
    <result column="name" property="stuName"></result>
    <result column="email" property="stuEmail"></result>
    <result column="age" property="stuAge"></result>
</resultMap>
<!--resultMap属性: resultMap 标签中的 id 属性值-->
<select id="selectStudentByNameOrAge" resultMap="selectMap">
    select id,name,email,age from student where name=#{name} or age=#{age}
</select>

实体类属性名和数据库表中的列名不同的处理方式

1.使用列别名和
<select id="selectStudent" resultType="domain.Student">
    select id as sid,name as sname,age,score from student where id=#{id}
</select>
2.使用resultMap
<!-- 创建 resultMap
id:自定义的唯一名称,在<select>使用
type:期望转为的 java 对象的全限定名称或别名
-->
<resultMap id="selectStudentMap" type="domain.Student">
    <!-- 主键字段使用id-->
    <id column="id" property="sid"></id>
    <!-- 非主键字段使用result-->
    <result column="name" property="sname"></result>
</resultMap>
<!--resultMap: resultMap 标签中的 id 属性值-->
<select id="selectStudent" resultMap="selectStudentMap">
    select id ,name,age,score from student where id=#{id}
</select>

模糊查询

模糊查询使用关键字like,其实现主要有两种方式:

  1. java 代码中给查询数据加上“%”
<select id="selectStudentsByName" resultType="domain.Student">
    select id,name,age,score from student where name like #{sss}
</select>
// 查询姓名中有"四"的
List<Student> students = mapper.selectStudentsByName("%四%");
  1. 在 mapper 文件 sql 语句的条件位置加上“%”,
<select id="selectStudentsByName" resultType="domain.Student">
    select id,name,age,score from student where name like "%" #{sss} "%"
</select>
// 查询姓名中有"四"的
List<Student> students = mapper.selectStudentsByName("四");

动态SQL

动态SQL,通过MyBatis提供的各种标签对条件作出判断以实现动态拼接SQL语句。动态SQL中常用的标签有if,where,choose,foreach.

note: 在mapper文件中的动态SQL中,如果出现大于号,小于号等符号,最好将其转化为实体符号,否则XML可能会出现解析出错的问题。

  1. < 小于 &lt;
  2. > 大于 &gt;
  3. >= 大于等于 &gt;=
  4. <= 小于等于 &lt;=
1.动态SQL之if

当test属性的值为true时,会将其包含的SQL片段拼接到其所在的SQL语句中。语法为<if test="条件">sql语句的部分</if>

List<Student> selectStudentIf(Student student);

<select id="selectStudentIf" resultType="student">
    select * from student where 1 = 1
    <if test="name != null and name != ''">
        and name = #{name}
    </if>
    <if test="age > 0">
        and age &gt; #{age}
    </if>
</select>
2.动态SQL之where

使用where标签,在有查询条件且为真时,可以自动添加上 where 子句;没有查询条件时或者查询条件为假,不会添加where 子句。语法为:<where>其他动态SQL<where>

List<Student> selectStudentWhere(Student student);

<select id="selectStudentWhere" resultType="com.nrvcer.domain.Student">
    select * from student
    <where>
        <if test="name != null and name != ''">
            and name = #{name}
        </if>
        <if test="age >0">
            and age > #{age}
        </if>
    </where>
</select>

3.动态SQL之foreach

<foreach/>标签用于实现对于数组与集合的遍历。主要用在sql的in语句中,比如说select * from student where id in(1001,1002,1003)

  1. 语法规则:
collection属性:表示要遍历的集合类型, list ,array 等。如果是数组就
使用array,如果是集合就使用list
<foreach collection="集合类型" open="循环开始的字符" close="循环结束的字符" 
item="集合或者数组中的成员变量" separator="集合成员之间的分隔符">
 #{item 的值}
</foreach>
  1. 遍历List<简单类型>,示例:查询id为1,3,5的学生
List<Student> selectStudentForList(List<Integer> idList);

<!--select * from student where id in ( ? , ? , ? )-->
<select id="selectStudentForList" resultType="com.nrvcer.domain.Student">
    select * from student
    <if test="list != null and list.size > 0">
        where id in
        <foreach collection="list" item="tempId" open="("
                 close=")" separator=",">
            #{tempId}
        </foreach>
    </if>
</select>
  1. 遍历List<对象类型>,示例
List<Student> selectStudentForStuList(List<Student> stuList);

<!--select * from student where id in ( ? , ? , ? )-->
<select id="selectStudentForStuList" resultType="com.nrvcer.domain.Student">
    select * from student
    <if test="list != null and list.size > 0">
        where id in
        <foreach collection="list" item="student" open="("
                 close=")" separator=",">
            #{student.id}
        </foreach>
    </if>
</select>
4.动态SQL之代码片段

标签用于定义 SQL 片段,以便其它 SQL 标签复用。而其它标签使用该 SQL 片断,需要使用
子标签。该标签可以定义 SQL 语句中的任何部分,所以子标签可以放在动态 SQL的任何位置。

// 示例


<!--创建 sql 片段, id属性:片段的自定义名称-->
<sql id="selectStudent">
    select * from student
</sql>
<!--select * from student where id in ( ? , ? , ? )-->
<select id="selectStudentForStuList" resultType="com.nrvcer.domain.Student">
    <!-- 引用 sql 片段 -->
    <include refid="selectStudent"></include>
    <if test="list != null and list.size > 0">
        where id in
        <foreach collection="list" item="student" open="("
                 close=")" separator=",">
            #{student.id}
        </foreach>
    </if>
</select>

Mybatis中的事务

  1. 默认需要手动提交事务:Mybatis 框架是对 JDBC 的封装,所以 Mybatis 框架的事务控制方式,本身也是用 JDBC 的 Connection
    对象的 commit(), rollback()
  2. 指定MyBatis所使用的事务管理器:使用transactionManager标签。事务管理器类型::JDBC 与 MANAGED
JDBC:使用 JDBC 的事务管理机制。即通过
Connection 的 commit()方法提交,通过 rollback()方法
回滚
MANAGED:由容器来管理事务的整个生命周期(如 Spring 容器)。

// 示例:
在Mybatis的主配置文件中的transactionManager标签的type属性可以指定事务的类型
<transactionManager type="JDBC"/>
  1. 自动提交事务
1. 方式1:session = factory.openSession(true);
openSession()等同于openSession(false)
2. 方式2:session.commit()

MyBatis配置文件

1.MyBatis的主配置文件
  1. 头部约束
<?xml version="1.0" encoding="UTF-8" ?>
<!--Mybatis的主配置文件-->
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
  1. 配置数据源:使用dataSource标签
dataSource的type属性可以指定MyBatis使用连接池技术,其值有三个
1. UNPOOLED:不使用连接池的数据源
2. POOLED:使用连接池的数据源
3. JNDI:使用JNDI实现的数据源

MyBatis主配置文件中配置dataSource如下
<!--配置数据源DataSource:创建数据库的连接Connection对象
属性type:其值POOLED表示使用数据库的连接池
-->
<dataSource type="POOLED">
<!--连接数据库的四要素
    driver:驱动内容
-->
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<!--连接数据库的url-->
<property name="url" value="jdbc:mysql://localhost:3306/ssm?useUnicode=true&amp;characterEncoding=utf-8"/>
<!--用户名-->
<property name="username" value="root"/>
<!--密码-->
<property name="password" value="123456"/>
</dataSource>
2.数据库属性配置文件的使用

为 了方便对数据库连接的管理,DB连接四要素数据一般都是存放在一个专门的属性文件中的。MyBatis主配置文件需要从这个属性文件中读取这些数据。

  1. 使用步骤:
1. 在resources目录下创建jdbc.properties文件,名称可以自定义
    jdbc.driver=com.mysql.cj.jdbc.Driver
    jdbc.url=jdbc:mysql://localhost:3306/ssm?useUnicode=true&characterEncoding=utf-8
    jdbc.username=root
    jdbc.password=123456
2. 主配置文件中使用properties标签引入属性配置文件
    configuration根标签下加入如下内容
    <properties resource="jdbc.properties"/>
3. 使用属性配置文件中的键来指定主配置文件中使用到的一些属性值
    <dataSource type="POOLED">
        <!-- 使用properties文件:语法${key}-->
        <property name="driver" value="${jdbc.driver}"/>
        <!--连接数据库的url-->
        <property name="url" value="${jdbc.url}"/>
        <!--用户名-->
        <property name="username" value="${jdbc.username}"/>
        <!--密码-->
        <property name="password" value="${jdbc.password}"/>
    </dataSource>
    
3.typeAliases(类型别名)
  1. 定义别名:在MyBatis主配置文件中使用typeAliases标签定义别名。定义好别名后,在Mapper文件中定义SQL语句使用到的resultType属性的值就可以方便书写。注意声明typeAliases标签的顺序
方式1: 定义单个类型的别名
    types属性:指定类型的全限定名称
    alias:自定义别名
    示例:
    <typeAliases>
        <typeAlias type="com.nrvcer.domain.Student" alias="sss"/>
    </typeAliases>
方式2:批量定义包名,扫描整个包下的类,别名为类名(首字母大写或者小写都可以)
    示例:
    <typeAliases>
        <!-- name属性指定包名-->
        <package name="com.nrvcer.domain"/>
    </typeAliases>
4.mappers(映射器)
<mappers>
    <!--使用mapper的resource属性指定mapper文件的路径
        这个路径是从target/classes路径开启的
        使用注意:resource="mapper"文件的路径,使用 / 分割路径
        一个resource指定一个mapper文件
    -->
    <mapper resource="com/nrvcer/dao/StudentDao.xml"/>
</mappers>
  1. 使用:此种方法要求 Dao 接口名称和 mapper映射文件名称相同,且在同一个目录中。
 <!--指定其他mapper文件的位置
        目的是找到其他mapper文件的sql语句
    -->
<mappers>
    <!--指定包下的所有Dao接口 -->
    <package name="com.nrvcer.dao"/>
</mappers>

基于PageHelper分页

PageHelper参考:https://github.com/pagehelper/Mybatis-PageHelper

  1. 在pom.xml文件中添加maven坐标
<dependency>
    <groupId>com.github.pagehelper</groupId>
    <artifactId>pagehelper</artifactId>
    <version>5.1.10</version>
</dependency>
  1. 在主配置mybatis文件中的environments标签之前加入plugin配置
<plugins>
    <plugin interceptor="com.github.pagehelper.PageInterceptor" />
</plugins>
  1. 调用PageHelper的方法startPage()进行分页操作:在你需要进行分页的MyBatis查询方法前调用。
// 获取第一页,2条内容(记录)
PageHelper.startPage(1, 2);
List<Student> students = studentDao.selectStudentByNameOrAge("老刘", 21);