Mybatis学习笔记

Posted Shimmers微光

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Mybatis学习笔记相关的知识,希望对你有一定的参考价值。

Mybatis学习笔记

本篇文章是观看B站UP主狂神说关于Mybatis讲解的视频,借鉴Mybatis官方文档以及CSDN博主黑心白莲相关文章整理的个人Mybatis笔记。因笔者能力有限,文章难免有错误之处,欢迎各位评论勘误,共同探讨!

1、Mybatis简介

1.1 什么是Mybatis

  • MyBatis 是一款优秀的持久层框架,它支持自定义 SQL、存储过程以及高级映射。

  • MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。

  • MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。

  • Maven仓库

    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis</artifactId>
        <version>3.5.7</version>
    </dependency>
    
  • 中文文档:链接

  • GitHub:链接

1.2 数据持久化

  • 持久化:将程序的数据从瞬时状态转化为持久状态的过程
  • 原因:内存断电即失,内存条价格较昂贵
  • 实现方式:I/O文件操作、数据库存储(JDBC技术)

1.3 持久层

  • 完成持久化工作的代码块
  • 层可以使实现不同功能代码的界限明显
  • Dao层/Mapper层

1.4 为什么需要使用Mybatis

  • 传统的JDBC代码过于复杂
  • 半自动化的框架可以帮助程序员更方便地将数据存入数据库
  • 不使用Mybatis也可以,技术没有高低之分

2、第一个Mybatis程序

2.1 搭建环境

搭建数据库

新建项目

  1. 创建一个普通的 Maven 项目

  2. 删除 src 目录(可将此项目作为父项目,然后创建子项目)

  3. 在 pom.xml 文件中导入 Maven 依赖

    <!--导入依赖-->
        <dependencies>
            <!--mysql驱动-->
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>8.0.25</version>
            </dependency>
            <!--Mybatis-->
            <dependency>
                <groupId>org.mybatis</groupId>
                <artifactId>mybatis</artifactId>
                <version>3.5.6</version>
            </dependency>
            <!--Junit-->
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>4.12</version>
                <scope>test</scope>
            </dependency>
        </dependencies>
    
  4. 右键项目名创建一个模块 Module

2.2 创建 Module

  • 编写 Mybatis 的核心配置文件(mybatis-config.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>
        <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/数据库名?useSSL=true&amp;useUnicode=true&amp;characterEncoding=utf-8"/>
                    <property name="username" value="数据库用户名"/>
                    <property name="password" value="数据库密码"/>
                </dataSource>
            </environment>
        </environments>
    </configuration>
    
  • 编写 Mybatis 工具类文件(MybatisUtils.java)

    public class MybatisUtils {
        private static SqlSessionFactory sqlSessionFactory;
    
        //使用Mybatis获取SqlSessionFactory对象
        static {
            InputStream inputStream = null;
            try {
                String resource = "mybatis-config.xml";
                inputStream = Resources.getResourceAsStream(resource);
                sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    
        /**
         * SqlSession 提供了在数据库执行 SQL 命令所需的所有方法
         */
        public static SqlSession getSqlSession() {
            return sqlSessionFactory.openSession();
        }
    }
    

2.3 编写代码

  • 实体类 pojo / Bean

  • Dao 接口 (UserMapper.java)

    public interface UserMapper {
        /**
         * 通过用户ID查询用户
         * @param id 用户ID
         * @return 用户所有信息
         */
        User getUserById(int id);
    }
    
  • 接口实现文件(UserMapper.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接口-->
    <mapper namespace="com.sit.mapper.UserMapper">
        <select id="getUserById" parameterType="int" resultType="com.sit.pojo.User">
            select * from mybatis.user where id = #{id}
        </select>
    </mapper>
    
  • 测试

    junit测试

    @Test
    public void getUserById() {
        SqlSession sqlSession = MybatisUtils.getSqlSession();
    
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        User user = mapper.getUserById(1);
        System.out.println(user);
    
        sqlSession.close();
    }
    
  • 可能遇到的问题

    org.apache.ibatis.binding.BindingException: Type interface com.sit.mapper.UserMapper is not known to the MapperRegistry.
    

    解决方法:

    在 pop.xml 文件中添加如下代码:

    <!--在build中配置resources,防止资源导出失败的问题-->
    <build>
        <resources>
            <resource>
                <directory>src/main/resources</directory>
                <includes>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                </includes>
                <filtering>false</filtering>
            </resource>
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                </includes>
                <filtering>false</filtering>
            </resource>
        </resources>
    </build>
    

3、基本CRUD操作

3.1 命名空间 Namespace

UserMapper.xml 文件中 namespace 的包名 需要和 Dao/Mapper 接口的包名一致!

<mapper namespace="com.sit.mapper.UserMapper">.....</mapper>

3.2 查询—select

  1. 接口中添加方法
public interface UserMapper {
    /**
     * 获得用户列表
     * @return 用户列表
     */
    List<User> getUserList();
}
  1. 在对应的 Mapper.xml 文件中编写SQL语句

    <select id="getUserList" resultType="com.sit.pojo.User">
            select * from mybatis.user
    </select>
    
    • id:对应的 namespace 中的方法名
    • resultType:sql语句执行的返回值类型
    • parameterType:参数类型
  2. 测试

    @Test
    public void getUserList() {
        //1.获取sqlSession
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        //2.执行sql语句
        try{
            UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
            List<User> userList = userMapper.getUserList();
            for (User user : userList) {
                System.out.println(user);
            }
        } finally {
            //3.关闭sqlSession
            sqlSession.close();
        }
    }
    

3.3 添加—insert

  1. 接口中添加方法

    /**
    * 添加用户
    * @param user 新用户信息
    * @return 是否插入成功
    */
    int addUser(User user);
    
  2. 在对应的 Mapper.xml 文件中编写SQL语句

    <insert id="addUser" parameterType="com.sit.pojo.User">
        insert into mybatis.user(id, name, pwd) VALUES (#{id}, #{name}, #{pwd})
    </insert>
    
  3. 测试

    @Test
    public void addUser() {
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        int res = mapper.addUser(new User(4, "小王", "666666"));
        if (res > 0) System.out.println("用户添加成功! ");
        //增删改必须提交事务
        sqlSession.commit();
        sqlSession.close();
    }
    

3.4 更新—update

  1. 接口中添加方法

    /**
    * 通过用户ID更新用户信息
    * @param user 新的用户信息
    * @return 是否修改成功
    */
    int updateUserById(User user);
    
  2. 在对应的 Mapper.xml 文件中编写SQL语句

    <update id="updateUserById" parameterType="com.sit.pojo.User">
        update mybatis.user set name = #{name}, pwd = #{pwd} where id = #{id}
    </update>
    
  3. 测试

    @Test
    public void updateUserById() {
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        int res = mapper.updateUserById(new User(5, "小杨", "987654"));
        if(res > 0) {
            System.out.println("用户修改成功! ");
        }
        //增删改必须提交事务
        sqlSession.commit();
        sqlSession.close();
    }
    

3.5 删除—delete

  1. 接口中添加方法

    /**
    * 通过用户ID删除用户信息
    * @param id 用户ID
    * @return 是否成功删除
    */
    int deleteUserById(int id);
    
  2. 在对应的 Mapper.xml 文件中编写SQL语句

    <delete id="deleteUserById" parameterType="int">
        delete from mybatis.user where id = #{id}
    </delete>
    
  3. 测试

    @Test
    public void deleteUserById() {
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        int res = mapper.deleteUserById(4);
        if(res > 0) {
            System.out.println("用户删除成功! ");
        }
        //增删改都需要提交事务
        sqlSession.commit();
        sqlSession.close();
    }
    

3.6 注意点

增删改操作一定要提交事务!!!

sqlSession.commit();

3.7 模糊查询

  1. 在Java代码执行的时候,传递通配符% %

    List<User> userList = mapper.getUserLike("%王%");
    
  2. 在sql拼接中使用通配符

    select * from user where name like "%"#{value}"%"
    

3.8 万能 Map

当实体类的属性或数据库中的字段过多时,应当考虑使用Map.

  1. UserMapper.java

    //用万能 Map 插入用户
    public void addUser2(Map<String,Object> map);
    
  2. UserMapper.xml

    <!--通过传递 map 的 key 可以直接取出对象中的属性值 -->
    <insert id="addUser2" parameterType="map">
        insert into user (id,name,password) values (#{userid},#{username},#{userpassword})
    </insert>
    
  3. 测试

    @Test
    public void addUser2(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        HashMap<String, Object> map = new HashMap<String, Object>();
        map.put("userid",4);
        map.put("username","小王");
        map.put("userpassword","789789");
        mapper.addUser2(map);
        //提交事务
        sqlSession.commit();
        //关闭资源
        sqlSession.close();
    }
    

4、Mybatis配置解析

4.1 核心配置文件

  • mybatis-config.xml

  • Mybatis的配置文件包含了Mybatis行为的设置和属性信息。

    configuration(配置)
        properties(属性)
        settings(设置)
        typeAliases(类型别名)
        typeHandlers(类型处理器)
        objectFactory(对象工厂)
        plugins(插件)
        environments(环境配置)
        	environment(环境变量)
        		transactionManager(事务管理器)
        		dataSource(数据源)
        databaseIdProvider(数据库厂商标识)
        mappers(映射器)
    

4.2 环境配置

  • Mybatis 可以配置多个环境,但是每个 SqlSessionFactory 实例只能选择一种环境
  • Mybatis 默认的事务管理器是 JDBC,连接池:POOLED

4.3 属性 properties

  • 可以通过 properties 属性来实现引用配置文件;
  • 属性可以在外部进行配置,并且可以进行动态替换(例如:典型的 Java属性文件【db.properties】);
  • 属性也可以在 properties 元素的子元素中设置。
  1. 编写一个配置文件 db.properties

    driver=com.mysql.cj.jdbc.Driver
    url=jdbc:mysql://localhost:3306/数据库名?userSSL=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC
    username=用户名
    password=密码
    
  2. 在核心配置文件中引入

    <!--引用外部配置文件-->
    <properties resource="db.properties">
        <property name="username" value="用户名"/>
        <property name="password" value="密码"/>
    </properties>
    

    注意点:如果外部文件(例如:db.properties)和核心配置文件(mybatis-config.xml)有相同字段,则优先使用外部配置文件中的属性值

4.4 类型别名 typeAliases

  • 可以为 Java 类型设置一个缩写名字,仅用于 XML 配置;
  • 目的是降低冗余的全限定类名书写。
<!--可以给实体类起别名-->
<typeAliases>
    <typeAlias type="com.sit.pojo.User" alias="User"/>
</typeAliases>

也可以指定一个包,每一个在包 com.sit.pojo 中的 Java Bean, 在没有注解的情况下,会使用 Bean 的首字母小写的非限定类名来作为它的别名。例如 com.sit.pojo.User 的别名为 user ; 若有注解,则别名为其注解值。

<typeAliases>
    <package name="com.sit.pojo"/>
</typeAliases>
  • 在实体类比较少的时候,使用第一种方式(可以自定义别名);
  • 如果实体类很多,则使用第二种扫描包的方式。

4.5 设置 Settings

  • Mybatis 中极为重要的调整设置,会改变 Mybatis 的运行时行为。
<settings>
        <!--标准的日志工厂的实现-->
<!--    <setting name="logImpl" value="STDOUT_LOGGING"/>    -->
    	<!--LOG4J日志工厂的实现-->
    	<setting name="logImpl" value="LOG4J"/>
        <!--开启驼峰命名转换-->
        <setting name="以上是关于Mybatis学习笔记的主要内容,如果未能解决你的问题,请参考以下文章

MyBatis-05-笔记

学习笔记:python3,代码片段(2017)

mybatis学习(39):动态sql片段

mybatis学习笔记使用generator生成mybatis基础配置代码和目录结构

Mybatis学习笔记-增删改的操作 -对SqlSession的优化封装-优化代码

MyBatis学习笔记