MyBatis-01-初识MyBatis

一、简介

1.1 什么是MyBatis

  • 简介
    • MyBatis 是一款优秀的持久层框架,它支持自定义 SQL、存储过程以及高级映射。
    • MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。
    • MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。
  • 特点
    • 简单易学:本身就很小且简单。没有任何第三方依赖,最简单安装只要两个jar文件+配置几个sql映射文件易于学习,易于使用,通过文档和源代码,可以比较完全的掌握它的设计思路和实现。
    • 灵活:mybatis不会对应用程序或者数据库的现有设计强加任何影响。 sql写在xml里,便于统一管理和优化。通过sql语句可以满足操作数据库的所有需求。
    • 解除sql与程序代码的耦合:通过提供DAO层,将业务逻辑和数据访问逻辑分离,使系统的设计更清晰,更易维护,更易单元测试。sql和代码的分离,提高了可维护性。
    • 提供映射标签,支持对象与数据库的orm字段关系映射
    • 提供对象关系映射标签,支持对象关系组建维护
    • 提供xml标签,支持编写动态sql
  • 官方文档
  • Github

1.2 持久化与持久层

1. 持久化

  • 什么是持久化?
    • 持久化是将程序数据在持久状态和瞬时状态间转换的机制。
      • 简单来说就是把内存中的数据保存在外存上
  • 为什么要持久化?
    • 内存的断点即失特性决定了内存无法长久存储数据
    • 虽然我们可以保证某台服务器7*24运行,但是万一意外发生的话,没有持久化的数据就会全部丢失

2. 持久层

  • 什么是持久层?

    • 专门负责持久化操作的逻辑层,由该层统一对数据库层进行操作

      img

1.3 为什么要用MyBatis

  • 用的人多啊,用的人多说明肯定优秀啊,不优秀的话为什么用的人多呢

  • 简化了传统的JDBC操作,提高了开发效率

  • 所有的事情,不用Mybatis依旧可以做到,只是用了它,所有实现会更加简单!

    技术没有高低之分,只有使用这个技术的人有高低之别


二、Hello MyBatis

2.1 搭建测试环境

  • 建立测试数据库

    DROP TABLE IF EXISTS user;
    
    CREATE TABLE `user` (
      `id` int NOT NULL AUTO_INCREMENT,
      `name` varchar(20) DEFAULT (NULL),
      `pwd` varchar(20) DEFAULT ('123456'),
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
    
    INSERT INTO `mybatis`.`user`(`name`, `pwd`) 
    VALUES ('李四', '12345'),('张三','1234'),('bruce','root');
    
  • 在maven中导入MySQL和MyBatis依赖

    <!--MySQL驱动-->
    <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>8.0.22</version>
    </dependency>
    
    <!--MyBatis-->
    <!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis</artifactId>
        <version>3.5.6</version>
    </dependency>
    
  • 创建核心配置文件

    <?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=true&amp;useUnicode=true&amp;characterEncoding=utf8&amp;serverTimezone=GMT%2B8"/>
                    <property name="username" value="root"/>
                    <property name="password" value="123456"/>
                </dataSource>
            </environment>
        </environments>
    </configuration>
    

2.2 准备工作

  • 创建MyBatis工具类

    • 用于构建 SqlSessionFactory,MyBatis中的SqlSession提供了在数据库执行 SQL 命令所需的所有方法。我们可以通过 SqlSession 实例来直接执行已映射的 SQL 语句
    package com.pbx.utils;
    
    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 BruceXu
     * @date 2020/10/30
     */
    public class MyBatisUtils {
        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();
            }
        }
    
        public static SqlSession getSqlSession() {
            return sqlSessionFactory.openSession();
        }
    }
    
  • 创建实体类

    package com.pbx.pojo;
    
    /**
     * @author BruceXu
     * @date 2020/10/30
     */
    public class User {
        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 + '\'' +
                    '}';
        }
    }
    
  • 编写Mapper接口

    package com.pbx.mapper;
    
    import com.pbx.pojo.User;
    
    import java.util.List;
    
    /**
     * @author BruceXu
     * @since 2020/10/30
     */
    public interface UserMapper {
        List<User> getUsers();
    }
    

2.3 编写代码

  • 编写Mapper.xml配置文件

    • namespace要和mapper接口文件的包名保持一致
    • id要对应上mapper接口中提供的函数名
    • resultType代表SQL语句的返回值
    • parameterType表示对应方法中需要接收的参数类型
    • 如果出现需要传递参数,可以使用 #{}表示占位符。而且可以无视实体类中的权限修饰符,可以直接取出其中的属性
    <?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.pbx.mapper.UserMapper">
        <select id="getUsers" resultType="com.pbx.pojo.User">
        select * from mybatis.user
      </select>
    </mapper>
    
  • 在mybatis-config.xml中注册UserMapper

    <mappers>
        <mapper resource="com/pbx/mapper/Mapper.xml" />
    </mappers>
    

2.4 测试

  • 编写测试类

    package com.pbx.mapper;
    
    import com.pbx.pojo.User;
    import com.pbx.utils.MyBatisUtils;
    import org.apache.ibatis.session.SqlSession;
    import org.junit.Test;
    
    import java.util.List;
    
    /**
     * @author BruceXu
     * @date 2020/10/30
     */
    public class TestUserMapper {
    
        @Test
        public void test() {
            SqlSession sqlSession = MyBatisUtils.getSqlSession();
            UserMapper mapper = sqlSession.getMapper(UserMapper.class);
            List<User> list = mapper.getUsers();
            for (User user : list) {
                System.out.println(user);
            }
        }
    
    }
    
  • 测试运行

    • 运行出现如下错误

    • 错误原因如下:Error parsing SQL Mapper Configuration. Cause: java.io.IOException: Could not find resource com/pbx/mapper/Mapper.xml,找不导我们的Mapper.xml文件。但是观察项目结构后发现,诶,Mapper.xml文件明明就有啊,为什么会找不到呢?

      image-20201030194811713image-20201030194901826

      • 这个问题产生的原因是由于maven静态资源的导出存在问题,我们需要调整静态资源的过滤条件,能让maven过滤到他
    • 解决方法:修改maven的静态资源过滤

      <build>
      <resources>
          <resource>
              <directory>src/main/java</directory>
              <includes>
                  <include>**/*.properties</include>
                  <include>**/*.xml</include>
              </includes>
              <filtering>false</filtering>
          </resource>
          <resource>
              <directory>src/main/resources</directory>
              <includes>
                  <include>**/*.properties</include>
                  <include>**/*.xml</include>
              </includes>
              <filtering>false</filtering>
          </resource>
      </resources>
      </build>
      
    • 修改之后,就可以到正确的输出结果了

      image-20201030195501941

2.5 在Maven中使用MyBatis的一般步骤

  1. 导入相应的数据库驱动和MyBatis依赖
  2. 编写mybatis-config.xml主要配置文件
  3. 构建SqlSessionFactory
  4. 创建实体类
  5. 创建mapper接口,编写mapper.xml实现SQL操作
  6. 在mybatis-config.xml中配置注册使用到的mapper.xml文件
  7. 进行使用
  • 注意
    • 每个线程都应该有它自己的 SqlSession 实例。
    • SqlSession 的实例不是线程安全的,因此是不能被共享的,所以它的最佳的作用域是请求或方法作用域。
    • 绝对不能将 SqlSession 实例的引用放在一个类的静态域,甚至一个类的实例变量也不行。
    • 也绝不能将 SqlSession 实例的引用放在任何类型的托管作用域中,比如 Servlet 框架中的 HttpSession。
    • 如果你现在正在使用一种 Web 框架,考虑将 SqlSession 放在一个和 HTTP 请求相似的作用域中。
    • 换句话说,每次收到 HTTP 请求,就可以打开一个 SqlSession,返回一个响应后,就关闭它
    • 不仅仅是在web应用中,每当一个SqlSession用完之后,一定要关闭它
posted @ 2020-11-06 16:00  PrimaBruceXu  阅读(68)  评论(0编辑  收藏  举报