前言:

推荐免费MyBatis基础教程视频:【狂神说Java】Mybatis最新完整教程IDEA版通俗易懂_哔哩哔哩_bilibili

什么是MyBatis

环境:

  • JDK1.8
  • MySQL8.0
  • Maven 3.6.1
  • IDEA

回顾

  • JDBC
  • MySQL
  • Java基础
  • Maven
  • Junit

简介

什么是MyBatis

mybatis

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

  • MyBatis 是一款优秀的持久层框架
  • 它支持自定义 SQL、存储过程以及高级映射。
  • 它免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。
  • 通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。

入门

安装Mybatis

Maven:Maven Repository: org.mybatis » mybatis (mvnrepository.com)

1
2
3
4
5
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.6</version>
</dependency>

GitHub地址:mybatis/mybatis-3: MyBatis SQL mapper framework for Java (github.com)

中文文档:MyBatis中文网

持久化

数据持久化

  • 持久化就是将程序的数据在持久状态和瞬时状态转化的过程
  • 内存:断电即失
  • 数据库(JDBC),IO文件持久化
  • 生活:食品冷藏

为什么持久化?

  • 防止数据丢失
  • 内存昂贵

持久层

Dao层,Service层,Controller层…..

  • 完成持久化工作的代码
  • 层界线非常明显

为什么需要MyBatis

  • 简化JDBC代码

  • 简单易学,灵活

  • 结束SQL与程序代码的耦合

  • 提供映射标签,支持对象与数据库ORM字段关系映射

  • 提供对象关系映射标签,支持对象关系组件维护

  • 提供xml标签,支持编写动态SQL

  • 使用人数多 (●’◡’●)

不用Mybatis也能实现,使用MyBatis更方便。

第一个MyBatis程序

思路:搭建环境–>导入MyBatis–>编写代码–>测试

搭建环境

  1. 搭建测试的数据库

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    create database mybatis;
    use mybatis
    -- 创建表
    create table `user`(
    `id` int(20) not null,
    `name` varchar(30) default null,
    `pwd` varchar(30) default null,
    primary key (`id`)
    )engine=innodb default charset=utf8;

    insert into `user`(id,`name`,pwd)values(1,'admin','123'),(2,'abc','123'),(3,'def','123');

    select * from `user`;
  2. 新建普通Maven项目,删除src目录

    image-20220423143826867

  3. 导入项目依赖

    pom.xml

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    <dependencies>
    <!-- Mybatis-->
    <dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis</artifactId>
    <version>3.5.6</version>
    </dependency>

    <!-- 数据库-->
    <dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.22</version>
    </dependency>
    <!-- junit-->
    <dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.12</version>
    <scope>test</scope>
    </dependency>
    </dependencies>
    <!-- 解决资源导出问题-->

    <build>
    <resources>
    <resource>
    <directory>src/main/resources</directory>
    <includes>
    <include>**/*.properties</include>
    <include>**/*.xml</include>
    </includes>
    <filtering>true</filtering>
    </resource>
    <resource>
    <directory>src/main/java</directory>
    <includes>
    <include>**/*.properties</include>
    <include>**/*.xml</include>
    </includes>
    <filtering>true</filtering>
    </resource>
    </resources>
    <!-- junit测试必须的插件 否则会报错-->
    <plugins>
    <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>2.22.1</version>
    <configuration>
    <skipTests>true</skipTests>
    </configuration>
    </plugin>
    </plugins>
    </build>
  4. 创建一个模块

    编写MyBatis核心配置文件

    resources->mybatis-config.xml

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    <?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>
    <environments default="development">
    <environment id="development">
    <transactionManager type="JDBC"/>
    <dataSource type="POOLED">
    <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
    <property name="url" value="jdbc:mysql://localhost:3306/mybatis?useSSL=false&amp;serverTimezone=UTC"/>
    <property name="username" value="root"/>
    <property name="password" value="123456"/>
    </dataSource>
    </environment>
    </environments>
    </configuration>

    编写MyBatis工具类

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    package com.jokerdig.util;

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

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

    /**
    * @author Joker大雄
    * @data 2022/4/23 - 15:11
    **/
    public class MyBatisUtil {
    // sqlSessionFactory -- sqlSession
    private static SqlSessionFactory sqlSessionFactory;

    static {
    try {
    String resource = "mybatis-config.xml";
    InputStream inputStream = Resources.getResourceAsStream(resource);
    sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
    } catch (IOException e) {
    e.printStackTrace();
    }
    }
    // 既然有了 SqlSessionFactory,顾名思义,
    // 我们可以从中获得 SqlSession 的实例。
    // SqlSession 提供了在数据库执行 SQL 命令所需的所有方法。
    public static SqlSession getSqlSession(){
    return sqlSessionFactory.openSession();
    }
    }
  5. 编写代码

    User.java实体类

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    package com.jokerdig.pojo;

    import java.io.Serializable;

    /**
    * 实体类
    * @author Joker大雄
    * @data 2022/4/23 - 15:22
    **/
    public class User implements Serializable {
    private int id;
    private String name;
    private String pwd;

    public User() {
    }

    public User(int id, String name, String pwd) {
    this.id = id;
    this.name = name;
    this.pwd = pwd;
    }

    public int getId() {
    return id;
    }

    public void setId(int id) {
    this.id = id;
    }

    public String getName() {
    return name;
    }

    public void setName(String name) {
    this.name = name;
    }

    public String getPwd() {
    return pwd;
    }

    public void setPwd(String pwd) {
    this.pwd = pwd;
    }
    @Override
    public String toString() {
    return "User{" +
    "id=" + id +
    ", name='" + name + '\'' +
    ", pwd='" + pwd + '\'' +
    '}';
    }
    }

    UserMapper.java接口

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    package com.jokerdig.mapper;

    import com.jokerdig.pojo.User;

    import java.util.List;

    /**
    * @author Joker大雄
    * @data 2022/4/23 - 15:24
    **/
    public interface UserMapper {
    // 查询所有
    List<User> getUserList();
    }

    UserMapper.xml配置文件

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    <?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接口-->
    <mapper namespace="com.jokerdig.mapper.UserMapper">
    <!-- 查询语句 id对应接口方法名-->
    <select id="getUserList" resultType="com.jokerdig.pojo.User">
    select * from User
    </select>
    </mapper>

    mybatis-config.xml中注册UserMapper

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    <?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>
    <environments default="development">
    <environment id="development">
    <transactionManager type="JDBC"/>
    <dataSource type="POOLED">
    <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
    <property name="url" value="jdbc:mysql://localhost:3306/mybatis?useSSL=false&amp;serverTimezone=UTC"/>
    <property name="username" value="root"/>
    <property name="password" value="123456"/>
    </dataSource>
    </environment>
    </environments>
    <mappers>
    <!--这里来注册Mapper.xml-->
    <mapper resource="com/jokerdig/mapper/UserMapper.xml"/>
    </mappers>
    </configuration>
  6. 使用Junit进行测试

    在test->java中测试

    UserMapperTest.java

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    package com.jokerdig.mapper;

    import com.jokerdig.pojo.User;
    import com.jokerdig.util.MyBatisUtil;
    import org.apache.ibatis.session.SqlSession;
    import org.junit.Test;

    import java.util.List;

    /**
    * @author Joker大雄
    * @data 2022/4/23 - 15:37
    **/
    public class UserMapperTest {
    @Test
    public void test(){
    SqlSession sqlSession = null;
    try {
    // 获得sqlSession对象
    sqlSession = MyBatisUtil.getSqlSession();
    // 执行sql
    UserMapper mapper = sqlSession.getMapper(UserMapper.class);
    // mapper调用查询方法
    List<User> userList = mapper.getUserList();
    // 输出查询结果
    for (User user : userList) {
    System.out.println("id:"+user.getId()+" name:"+user.getName()+" 密码:"+user.getPwd());
    }
    } catch (Exception e) {
    e.printStackTrace();
    } finally {
    // 关闭sqlSession
    sqlSession.close();
    }
    }
    }
  7. 查询成功

    1
    2
    3
    4
    5
    6
    "..."com.jokerdig.mapper.UserMapperTest,test
    id:1 name:admin 密码:123
    id:2 name:abc 密码:123
    id:3 name:def 密码:123

    Process finished with exit code 0

容易遇到的问题

  • 配置文件未注册
  • 绑定接口错误
  • 方法名不对
  • 返回类型不对
  • Maven导出资源问题

增删改查实现

namespace

namespace(命名空间)中的包名要和接口中的报名一致!

select

选择,查询语句

  • id:就是对应的namespace中的方法名
  • resultType:sql语句执行的返回值
  • parameterType:传递的参数类型

Insert

插入语句(增删改需要提交事务)

  • id:就是对应的namespace中的方法名
  • parameterType:传递的参数类型

update

修改语句(增删改需要提交事务)

  • id:就是对应的namespace中的方法名
  • parameterType:传递的参数类型

delete

删除语句(增删改需要提交事务)

  • id:就是对应的namespace中的方法名
  • parameterType:传递的参数类型

测试增删改查

  • UserMapper.java

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    package com.jokerdig.mapper;

    import com.jokerdig.pojo.User;

    import java.util.List;

    /**
    * @author Joker大雄
    * @data 2022/4/23 - 15:24
    **/
    public interface UserMapper {
    // 查询所有
    List<User> getUserList();
    // 根据id查询用户
    User getUserById(int id);
    // 添加
    int add(User user);
    // 修改
    int update(User user);
    // 删除
    int delete(int id);
    }
  • UserMapper.xml

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    <?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接口-->
    <mapper namespace="com.jokerdig.mapper.UserMapper">
    <!-- 查询语句 id对应接口方法名-->
    <select id="getUserList" resultType="com.jokerdig.pojo.User">
    select * from user
    </select>
    <!--根据id查询用户-->
    <select id="getUserById" parameterType="int" resultType="com.jokerdig.pojo.User">
    select * from user where id=#{id}
    </select>
    <!-- 添加-->
    <insert id="add" parameterType="com.jokerdig.pojo.User" >
    insert into user(id,name,pwd) values (#{id},#{name},#{pwd})
    </insert>
    <!-- 修改-->
    <update id="update" parameterType="com.jokerdig.pojo.User">
    update user set name=#{name},pwd=#{pwd} where id=#{id}
    </update>
    <!-- 删除-->
    <delete id="delete" parameterType="int">
    delete from user where id=#{id}
    </delete>
    </mapper>
  • UserMapperTest.java

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    package com.jokerdig.mapper;

    import com.jokerdig.pojo.User;
    import com.jokerdig.util.MyBatisUtil;
    import org.apache.ibatis.session.SqlSession;
    import org.junit.Test;

    import java.util.List;

    /**
    * @author Joker大雄
    * @data 2022/4/23 - 15:37
    **/
    public class UserMapperTest {
    // 查询所有
    @Test
    public void test(){
    SqlSession sqlSession = null;
    try {
    // 获得sqlSession对象
    sqlSession = MyBatisUtil.getSqlSession();
    // 执行sql
    UserMapper mapper = sqlSession.getMapper(UserMapper.class);
    // mapper调用查询方法
    List<User> userList = mapper.getUserList();
    // 输出查询结果
    for (User user : userList) {
    System.out.println("id:"+user.getId()+" name:"+user.getName()+" 密码:"+user.getPwd());
    }
    } catch (Exception e) {
    e.printStackTrace();
    } finally {
    // 关闭sqlSession
    sqlSession.close();
    }
    }

    // 根据ID查询
    @Test
    public void getUserById(){
    //获取sqlSession
    SqlSession sqlSession = MyBatisUtil.getSqlSession();
    // 执行sql
    UserMapper mapper = sqlSession.getMapper(UserMapper.class);
    // 查询id为1的用户
    User user = mapper.getUserById(1);
    // 输出
    System.out.println("id:"+user.getId()+" name:"+user.getName()+" 密码:"+user.getPwd());
    // 关闭
    sqlSession.close();
    }
    // 添加
    @Test
    public void add(){
    // 获取sqlsession
    SqlSession sqlSession = MyBatisUtil.getSqlSession();
    // 执行sql
    UserMapper mapper = sqlSession.getMapper(UserMapper.class);
    // 添加用户
    User user = new User(4,"王富贵","123");
    // 增删改需要提交事务
    int flag = mapper.add(user);
    if(flag>0){
    System.out.println("添加成功"+user);
    // 提交事务
    sqlSession.commit();
    }else{
    System.out.println("添加失败");
    }
    //关闭
    sqlSession.close();
    }
    // 修改
    @Test
    public void update(){
    // 获取sqlsession
    SqlSession sqlSession = MyBatisUtil.getSqlSession();
    // 执行sql
    UserMapper mapper = sqlSession.getMapper(UserMapper.class);
    // 修改用户
    User user = new User(4,"王小胖","333");
    int flag = mapper.update(user);
    if(flag>0){
    System.out.println("修改成功"+user);
    // 增删改需要提交事务
    sqlSession.commit();
    }else{
    System.out.println("修改失败");
    }
    //关闭
    sqlSession.close();
    }
    // 删除
    @Test
    public void delete (){
    // 获取sqlsession
    SqlSession sqlSession = MyBatisUtil.getSqlSession();
    // 执行sql
    UserMapper mapper = sqlSession.getMapper(UserMapper.class);
    // 删除用户 删除id为4的用户
    int flag = mapper.delete(4);
    if(flag>0){
    System.out.println("删除成功");
    // 提交事务
    sqlSession.commit();
    }else{
    System.out.println("删除失败");
    }
    // 关闭
    sqlSession.close();
    }
    }
  • 运行结果

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    --------------根据ID查询------------------
    id:1 name:admin 密码:123

    Process finished with exit code 0
    -----------------添加---------------------
    添加成功User{id=4, name='王富贵', pwd='123'}

    Process finished with exit code 0
    -----------------修改---------------------
    修改成功User{id=4, name='王小胖', pwd='333'}

    Process finished with exit code 0
    -----------------删除---------------------
    删除成功

    Process finished with exit code 0