• Mybatis笔记一


    一、Mybatis介绍

    1、什么是Mybatis

    官方文档:https://mybatis.org/mybatis-3/zh/getting-started.html

    1、MyBatis 是一款优秀的持久层框架
    2、它支持定制化 SQL、存储过程以及高级映射。
    MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。
    3、MyBatis 可以使用简单的 XML 或注解来配置和映射原生类型、接口和 Java 的 POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。
    4、MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis 。
    5、2013年11月迁移到Github

    2、持久化

    1、 持久化就是将程序的数据在持久状态和瞬时状态转化的过程
    2、 内存:断电即失
    3、 数据库(Jdbc),io文件持久化。

    为什么需要他持久化
    1、 有一些对象,不能让他丢掉。
    2、 内存太贵了

    3、持久层

    Dao层,Service层,Controller层….

    完成持久化工作的代码块
    层界限十分明显

    4、为什么需要Mybatis

    • 帮助程序员将数据存入到数据库中
    • 方便
    • 传统的JDBC代码太复杂了。简化。框架。自动化。
    • 不用Mybatis也可以。更容易上手。 技术没有高低之分
    • 优点:
      1.简单易学
      2.灵活
      3.sql和代码的分离,提高了可维护性。
      4.提供映射标签,支持对象与数据库的orm字段关系映射
      5.提供对象关系映射标签,支持对象关系组建维护
      6.提供xml标签,支持编写动态sql。

    二、第一个Mybatis程序

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

    1、搭建环境

    搭建数据库

    -- 建库
    create database `mybatis`;
    use `mybatis`
    
    -- 建表
    create table `user`(
    `id` int(20) not NULL PRIMARY KEY,
    `name` VARCHAR(30) DEFAULT null,
    `pwd` VARCHAR(30) DEFAULT NULL
    
    ) ENGINE=INNODB DEFAULT CHARSET=utf8; -- 指定引擎,指定字符集
    
    -- 插入数据
    INSERT into `user`(`id`,`NAME`,`pwd`) VALUES
    (1,'张三','123456'),
    (2,'张四','123456'),
    (3,'张五','123456'),
    (4,'张六','123456');
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    新建maven项目
    添加项目依赖

    
    <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.0modelVersion>
    
    
        <groupId>com.jjlgroupId>
        <artifactId>mybatis-studyartifactId>
        <version>1.0-SNAPSHOTversion>
    
        <dependencies>
            
            <dependency>
                <groupId>mysqlgroupId>
                <artifactId>mysql-connector-javaartifactId>
                <version>8.0.28version>
            dependency>
            
            <dependency>
                <groupId>org.mybatisgroupId>
                <artifactId>mybatisartifactId>
                <version>3.5.10version>
            dependency>
            
            <dependency>
                <groupId>junitgroupId>
                <artifactId>junitartifactId>
                <version>4.13.2version>
                <scope>testscope>
            dependency>
        dependencies>
    project>
    
    • 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

    2、创建一个模块

    • mybatis从 XML 中构建 SqlSessionFactory
      
      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?userSSL=true&useUnicode=true&characterEncoding=UTF-8"/>
                      <property name="username" value="root"/>
                      <property name="password" value="1234qwer"/>
                  dataSource>
              environment>
          environments>
      configuration>
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
    • 编码mybatis工具类
      package com.jjl.utils;
      
      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;
      import static org.apache.ibatis.io.Resources.*;
      
      //sqlSessionFactory 工具类
      public class MybatisUtils {
          private  static SqlSessionFactory sqlSessionFactory;
          static {
              try {
                  //获取sqlSessionFactory对象
                  String resource = "mybatis-config.xml";
                  InputStream inputStream = getResourceAsStream(resource);
                  sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
              } catch (IOException e) {
                  e.printStackTrace();
              }
          }
      //    既然有了 SqlSessionFactory,顾名思义,我们可以从中获得 SqlSession 的实例。SqlSession 提供了在数据库执行 SQL 命令所需的所有方法。
      //    你可以通过 SqlSession 实例来直接执行已映射的 SQL 语句。
          public static SqlSession getSqlSession(){
              return sqlSessionFactory.openSession();
          }
      }
      
      
      • 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

    3、编写代码

    • 实体类

      package com.jjl.pojo;
      
      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 + '\'' +
                      '}';
          }
      }
      
      
      • 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
    • dao接口

      package com.jjl.dao;
      import com.jjl.pojo.User;
      import java.util.List;
      
      public interface UserDao {
          List<User> getUserList();
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
    • 接口实现类,由原来的UserDaoImpl转变为一个Mapper配置文件

    
    DOCTYPE mapper
            PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
            "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    
    <mapper namespace="com.jjl.dao.UserDao">
    
        <select id="getUserList" resultType="com.jjl.pojo.User">
            select * from user;
        select>
    mapper>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    4、测试

    • 注意报错
      问题1:
      org.apache.ibatis.binding.BindingException: Type interface com.jjl.dao.UserDao is not known to the MapperRegistry.
      解决:
      在pom.xml中添加
    <build>
            <resources>
                <resource>
                    <directory>src/main/resourcesdirectory>
                    <includes>
                        <include>**/*.propertiesinclude>
                        <include>**/*.xmlinclude>
                    includes>
                    <filtering>truefiltering>
                resource>
                <resource>
                    <directory>src/main/javadirectory>
                    <includes>
                        <include>**/*.propertiesinclude>
                        <include>**/*.xmlinclude>
                    includes>
                    <filtering>truefiltering>
                resource>
            resources>
        build>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    问题2:
    Cause: org.apache.ibatis.builder.BuilderException: Error creating document instance. Cause: com.sun.org.apache.xerces.internal.impl.io.MalformedByteSequenceException: 1 字节的 UTF-8 序列的字节 1 无效
    解决:
    在这里插入图片描述
    测试

    package com.jjl.dao;
    
    import com.jjl.pojo.User;
    import com.jjl.utils.MybatisUtils;
    import org.apache.ibatis.session.SqlSession;
    import org.junit.Test;
    
    import java.util.List;
    
    public class UserDaoTest {
        @Test
        public void test(){
            //获得sqlSession对象
            SqlSession sqlSession = MybatisUtils.getSqlSession();
            //执行sql:方法一
            UserDao mapper = sqlSession.getMapper(UserDao.class);
            List<User> userList = mapper.getUserList();
    
    		//执行sql:方法二
            //List userList = sqlSession.selectList("com.jjl.dao.UserDao.getUserList");
            
            for (User user : userList) {
                System.out.println(user.toString());
            }
            //关闭sqlSession
            sqlSession.close();
        }
    }
    
    • 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

    三、CRUD(增删改查)

    1、namespace

    namespace中的包名要和Dao/mapper接口的包一致!

    2、select、insert、update、delete

    参数

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

    3、实现步骤

    1、编写接口

    package com.jjl.dao;
    import com.jjl.pojo.User;
    import java.util.List;
    public interface UserMapper {
        //获取全部用户
        List<User> getUserList();
    
        //根据id查询用户
        User getUserById(int id);
    
        //insert一个用户
        int addUser(User user);
    
        //修改数据
        int updateUser(User user);
    
        //删除用户
        int deleteUser(int id);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    2、编写对应的mapper中的sql语句

    
    DOCTYPE mapper
            PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
            "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    
    <mapper namespace="com.jjl.dao.UserMapper">
    
        <select id="getUserList" resultType="com.jjl.pojo.User">
            select * from mybatis.user;
        select>
    
    
        <select id="getUserById" resultType="com.jjl.pojo.User" parameterType="int">
            select * from mybatis.user where id = #{id};
        select>
    
    
        <insert id="addUser" parameterType="com.jjl.pojo.User">
            insert into user(id,name,pwd)value (#{id},#{name},#{pwd});
        insert>
    
    
        <update id="updateUser" parameterType="com.jjl.pojo.User">
            update user set name = #{name},pwd = #{pwd} where id = #{id};
        update>
    
    
        <delete id="deleteUser" parameterType="int">
            delete from user where id = #{id}
        delete>
    mapper>
    
    • 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

    3、测试
    增删改需要提交事务:sqlSession.commit();

    package com.jjl.dao;
    import com.jjl.pojo.User;
    import com.jjl.utils.MybatisUtils;
    import org.apache.ibatis.session.SqlSession;
    import org.junit.Test;
    import java.util.List;
    
    public class UserDaoTest {
        //测试查询所有用户信息
        @Test
        public void test() {
            //获得sqlSession对象
            SqlSession sqlSession = MybatisUtils.getSqlSession();
            //执行sql:方法一
            UserMapper mapper = sqlSession.getMapper(UserMapper.class);
            List<User> userList = mapper.getUserList();
            //执行sql:方法二
            //List userList = sqlSession.selectList("com.jjl.dao.UserDao.getUserList");
            for (User user : userList) {
                System.out.println(user);
            }
            //关闭sqlSession
            sqlSession.close();
        }
    
        //指定id查询用户信息
        @Test
        public void getUserById(){
            SqlSession sqlSession = MybatisUtils.getSqlSession();
            UserMapper mapper = sqlSession.getMapper(UserMapper.class);
            User userById = mapper.getUserById(1);
            System.out.println(userById);
            sqlSession.close();
        }
        
        //添加用户信息
        @Test
        public void addUser(){
            SqlSession sqlSession = MybatisUtils.getSqlSession();
            UserMapper mapper = sqlSession.getMapper(UserMapper.class);
            int user = mapper.addUser(new User(5, "shan", "123"));
            if (user>0){
                sqlSession.commit();
                System.out.println("插入成功");
            }
            sqlSession.close();
        }
        
        //更新用户信息
        @Test
        public void updateUser(){
            SqlSession sqlSession = MybatisUtils.getSqlSession();
            UserMapper mapper = sqlSession.getMapper(UserMapper.class);
            int updateUser = mapper.updateUser(new User(2, "jjl", "123123"));
            if (updateUser>0){
                sqlSession.commit();
                System.out.println("更新成功");
            }
            sqlSession.close();
        }
        
        //删除用户
        @Test
        public void deleteUser(){
            SqlSession sqlSession = MybatisUtils.getSqlSession();
            UserMapper mapper = sqlSession.getMapper(UserMapper.class);
            int deleteUser = mapper.deleteUser(4);
            if (deleteUser>0){
                sqlSession.commit();
                System.out.println("删除成功");
            }
            sqlSession.close();
        }
    
    }
    
    • 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

    4、map

    1、编写接口

    //    使用MAP
        //insert一个用户
        int addUserMap(Map<String,Object> map);
    
        //根据条件查询用户
        User getUserByIdMap(Map<String,Object> map);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    2、编写对应的mapper中的sql语句

    
    
        <insert id="addUserMap" parameterType="map">
            insert into user(id,name,pwd)value (#{userid},#{username},#{userpwd});
        insert>
        
        <select id="getUserByIdMap" resultType="com.jjl.pojo.User" parameterType="map">
            select * from mybatis.user where id = #{id} and name=#{name};
        select>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    3、测试

    //    Map
        @Test
        public void addUserMap(){
            SqlSession sqlSession = MybatisUtils.getSqlSession();
            UserMapper mapper = sqlSession.getMapper(UserMapper.class);
            HashMap<String, Object> hashMap = new HashMap<>();
            hashMap.put("userid",6);
            hashMap.put("username","xl");
            hashMap.put("userpwd","1234123");
            int userMap = mapper.addUserMap(hashMap);
            if (userMap>0){
                sqlSession.commit();
                System.out.println("插入成功");
            }
            sqlSession.close();
        }
    
        //指定id查询用户信息
        @Test
        public void getUserByIdMap(){
            SqlSession sqlSession = MybatisUtils.getSqlSession();
            UserMapper mapper = sqlSession.getMapper(UserMapper.class);
            HashMap<String, Object> hashMap = new HashMap<String, Object>();
            hashMap.put("id",4);
            hashMap.put("name","xl");
            User userByIdMap = mapper.getUserByIdMap(hashMap);
            System.out.println(userByIdMap);
            sqlSession.close();
        }
    
    • 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

    Map传递参数,直接在sql中取出key即可
    而对象传递参数,直接在sql中取对象的属性即可
    只有一个基本类型参数情况下,可以直接在sql中取到
    多个参数用Map,或者注解

    5、模糊查询

    1、编写接口

    List<User> getUserLike(String value);
    
    • 1

    2、对应接口实现的sql语句

    
        <select id="getUserLike" resultType="com.jjl.pojo.User">
            select * from user where name like "%"#{value}"%";
        select>
    
    • 1
    • 2
    • 3
    • 4

    3、测试

    //    like模糊查询
    //指定id查询用户信息
        @Test
        public void getUserLike(){
            SqlSession sqlSession = MybatisUtils.getSqlSession();
            UserMapper mapper = sqlSession.getMapper(UserMapper.class);
            List<User> userLike = mapper.getUserLike("张");
            for (User user : userLike) {
                System.out.println(user);
            }
            sqlSession.close();
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    四、配置解析

    1、核心配置文件

    • mybatis-config.xml
    • Mybatis的配置文件包含了会深深影响MyBatis行为的设置和属性信息
      configuration(配置)
      properties(属性)
      settings(设置)
      typeAliases(类型别名)
      typeHandlers(类型处理器)
      objectFactory(对象工厂)
      plugins(插件)
      environments(环境配置)
      environment(环境变量)
      transactionManager(事务管理器)
      dataSource(数据源)
      databaseIdProvider(数据库厂商标识)
      mappers(映射器)
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13

    2、环境配置(environments)

    MyBatis 可以配置成适应多种环境
    不过要记住:尽管可以配置多个环境,但每个 SqlSessionFactory 实例只能选择一种环境。

    • 在 MyBatis 中有两种类型的事务管理器(也就是 type=“[JDBC|MANAGED]”),默认JDBC
    • 默认连接池:POOLED

    3、属性(properties)

    可以通过properties属性来实现引用配置文件
    这些属性可以在外部进行配置,并可以进行动态替换。你既可以在典型的 Java 属性文件中配置这些属性,也可以在 properties 元素的子元素中设置。【db.properties】

    • 编写一个配置文件
      db.properties
      driver=com.mysql.cj.jdbc.Driver
      url=jdbc:mysql://localhost:3306/mybatis?useSSL=true&useUnicode=true&characterEncoding=UTF8
      username=root
      password=1234qwer
      
      • 1
      • 2
      • 3
      • 4
    • 在核心配置文件中引入
      1、可以直接引入外部文件
      <?xml version="1.0" encoding="UTF8" ?>
      <!DOCTYPE configuration
              PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
              "http://mybatis.org/dtd/mybatis-3-config.dtd">
      <!--configuration核心配置文件-->
      <configuration>
      <!--    引入外部配置文件-->
          <properties resource="db.properties"/>
              <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>
          <mappers>
              <mapper resource="com/jjl/dao/UserMapper.xml"/>
          </mappers>
      </configuration>
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      2、可以在其中增加一些属性配置
      <?xml version="1.0" encoding="UTF8" ?>
      <!DOCTYPE configuration
              PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
              "http://mybatis.org/dtd/mybatis-3-config.dtd">
      <!--configuration核心配置文件-->
      <configuration>
      <!--    引入外部配置文件-->
          <properties resource="db.properties">
              <property name="username" value="root"/>
              <property name="password" value="1234qwer"/>
          </properties>
              <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>
          <mappers>
              <mapper resource="com/jjl/dao/UserMapper.xml"/>
          </mappers>
      </configuration>
      
      • 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
      3、如果外部文件和内部增加的配置一样,则外部文件中配置的优先级高于内部增加的配置。

    4、类型别名(typeAliases)

    • 类型别名可为 Java 类型设置一个缩写名字。 它仅用于 XML 配置,意在降低冗余的全限定类名书写。

      
          <typeAliases>
              <typeAlias type="com.jjl.pojo.User" alias="User"/>
          typeAliases>
      
      • 1
      • 2
      • 3
      • 4

      在这里插入图片描述

    • 也可以指定一个包名,MyBatis 会在包名下面搜索需要的 Java Bean,每一个在包 domain.blog 中的 Java Bean,在没有注解的情况下,会使用 Bean 的首字母小写的非限定类名来作为它的别名。 比如 domain.blog.Author 的别名为 author

          <typeAliases>
              <package name="com.jjl.pojo"/>
          typeAliases>
      
      • 1
      • 2
      • 3
    • 在实体类比较少时没使用第一种方式

    • 在实体类比较多时,使用第二种方式

    • 第一种可以自定义起别名,第二种不行(但可以通过给实体类添加注解来自定义别名:@Alias(“hello”))

    五、设置(settings)

    这是 MyBatis 中极为重要的调整设置,它们会改变 MyBatis 的运行时行为。

    设置名描述有效值默认值
    cacheEnabled全局性地开启或关闭所有映射器配置文件中已配置的任何缓存。true /falsetrue
    lazyLoadingEnabled延迟加载的全局开关。当开启时,所有关联对象都会延迟加载。 特定关联关系中可通过设置 fetchType 属性来覆盖该项的开关状态。true/ falsefalse
    logImpl指定 MyBatis 所用日志的具体实现,未指定时将自动查找。SLF4J / LOG4J(3.5.9 起废弃) / LOG4J2 /JDK_LOGGING / COMMONS_LOGGING / STDOUT_LOGGING /NO_LOGGING未设置
    ··························

    六、其他

    • typeHandlers(类型处理器)
    • objectFactory(对象工厂)
    • plugins(插件)
      • mybatis-generator-core
      • mybatis-plus
      • 通用mapper

    七、映射器(mappers)

    方式1

    	<mappers>
            <mapper resource="com/jjl/dao/UserMapper.xml"/>
        mappers>
    
    • 1
    • 2
    • 3

    方式2:使用class文件绑定注册

        <mappers>
            <mapper class="com.jjl.dao.UserMapper"/>
        mappers>
    
    • 1
    • 2
    • 3

    方式3:使用扫描包镜像注册绑定

        <mappers>
    <!--        <mapper resource="com/jjl/dao/UserMapper.xml"/>-->
    <!--        <mapper class="com.jjl.dao.UserMapper"/>-->
            <package name="com.jjl.dao"/>
        </mappers>
    
    • 1
    • 2
    • 3
    • 4
    • 5

    方式2和方式3注意点:

    • 接口和它的Mapper配置文件必须同名
    • 接口和他的Mapper配置文件必须在同一个包下

    八、生命周期和作用域

    生命周期和作用域是至关重要的,因为错误的使用会导致非常严重的并发问题
    在这里插入图片描述

    • SqlSessionFactoryBuilder:
      • 一旦创建了 SqlSessionFactory,就不再需要它了。
      • 局部变量
    • SqlSessionFactory:
      • 说白就是可以想象为:数据库连接池。
      • SqlSessionFactory 一旦被创建就应该在应用的运行期间一直存在,没有任何理由丢弃它或重新创建另一个实例。
      • SqlSessionFactory 的最佳作用域是应用作用域。
      • 最简单的就是使用单例模式或者静态单例模式。
    • SqlSession:
      连接到连接池的一个请求!
      SqlSession 的实例不是线程安全的,因此是不能被共享的,所以它的最佳的作用域是请求或方法作用域。
      用完后需要赶紧关闭,否则资源被占用!

    九、解决属性名和字段名不一致的问题

    1、测试问题

    数据库中的字段
    在这里插入图片描述
    实体类
    在这里插入图片描述
    测试结果:
    在这里插入图片描述
    获取不到数据库中pwd的值

    2、解决方法:

    2.1、在sql语句中起别名

    在这里插入图片描述

    2.2、resultMap(结构集映射)

    • resultMap 元素是 MyBatis 中最重要最强大的元素

    • ResultMap 的设计思想是,对简单的语句做到零配置,对于复杂一点的语句,只需要描述语句之间的关系就行了。

      数据库:id name pwd
      实体类:id name password

    <?xml version="1.0" encoding="UTF8" ?>
    <!DOCTYPE mapper
            PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
            "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    <!--namespace绑定一个对应的dao/mapper接口-->
    <mapper namespace="com.jjl.dao.UserMapper">
    <!--    结果集映射-->
        <resultMap id="UserMap" type="User">
    <!--        column:数据库中的字段    property:对应实体类中的属性-->
            <result column="id" property="id"/> <!--如果数据库字段名和实体类属性一样,则可以不单独做映射,所以该行可以省略-->
            <result column="name" property="name"/> <!--如果数据库字段名和实体类属性一样,则可以不单独做映射,所以该行可以省略-->
            <result column="pwd" property="password"/>
        </resultMap>
    
        <select id="getUserById" resultMap="UserMap" parameterType="int">
            select * from mybatis.user where id = #{id};
        </select>
    </mapper>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    十、日志工厂

    如果一个数据库操作,出现了异常,我们需要排错,日志就是最好的助手
    Mybatis 通过使用内置的日志工厂提供日志功能。内置日志工厂将会把日志工作委托给下面的实现之一:

    • SLF4J
    • LOG4J(要掌握)
    • LOG4J2
    • JDK_LOGGING
    • COMMONS_LOGGING
    • STDOUT_LOGGING (要掌握)
    • NO_LOGGING

    在mybatis中具体使用,需要设置中设定

    1、STDOUT_LOGGING:标准日志输出

    在mybatis核心配置文件(mybatis-config.xml)中,配置日志

    
        <settings>
            <setting name="logImpl" value="STDOUT_LOGGING"/>
        settings>
    
    • 1
    • 2
    • 3
    • 4

    在这里插入图片描述

    6.2、Log4j

    什么是Log4j

    • Log4j是Apache的一个开源项目,通过使用Log4j,我们可以控制日志信息输送的目的地是控制台、文件、GUI组件,
    • 我们也可以控制每一条日志的输出格式;
    • 通过定义每一条日志信息的级别,我们能够更加细致地控制日志的生成过程。
    • 通过一个配置文件来灵活地进行配置,而不需要修改应用的代码。

    1、先导入log4j的依赖包

    <dependency>
                <groupId>log4jgroupId>
                <artifactId>log4jartifactId>
                <version>1.2.17version>
            dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5

    2、log4j.properties配置文件

    log4j.rootLogger=DEBUG,console,file
    log4j.additivity.org.apache=true
    
    # 控制台(console)
    log4j.appender.console=org.apache.log4j.ConsoleAppender
    log4j.appender.console.Threshold=DEBUG
    log4j.appender.console.ImmediateFlush=true
    log4j.appender.console.Target=System.out
    log4j.appender.console.layout=org.apache.log4j.PatternLayout
    log4j.appender.console.layout.ConversionPattern=[%-5p] %d(%r) --> [%t] %l: %m %x %n
    # 日志文件(file)
    log4j.appender.file=org.apache.log4j.FileAppender
    log4j.appender.file.Threshold=DEBUG
    log4j.appender.file.ImmediateFlush=true
    log4j.appender.file.Append=true
    log4j.appender.file.File=./log/jjl.log
    log4j.appender.file.MaxFileSize=10mb
    log4j.appender.file.layout=org.apache.log4j.PatternLayout
    log4j.appender.file.layout.ConversionPattern=[%-5p] %d(%r) --> [%t] %l: %m %x %n
    
    #日志输出级别
    log4j.logger.org.mybatis=DEBUG
    log4j.logger.java.sql=DEBUG
    log4j.logger.java.Statement=DEBUG
    log4j.logger.java.ResultSet=DEBUG
    log4j.logger.java.PreparedStatement=DEBUG
    
    • 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

    3、配置log4j为日志的实现

    <!--    配置日志-->
        <settings>
            <setting name="logImpl" value="LOG4J"/>
        </settings>
    
    • 1
    • 2
    • 3
    • 4

    4、log4j的使用
    在这里插入图片描述

    简单实用
    1、在要使用Log4j类中,导包import org.apache.log4j.Logger;
    2、日志对象,参数为当前类的class

    static Logger logger = Logger.getLogger(UserDaoTest.class);

    3、日志级别

    public void testLog4j(){
            logger.info("info:进入testLog4j");
            logger.debug("debug:进入testLog4j");
            logger.error("error:进入testLog4j");
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    十一、分页

    • 减少数据的处理量

    使用Limit分页

    select * from user limit #{startIndex},#{pageSize}
    
    • 1

    1、使用Mybatis实现分页

    1、接口

    List<User> getUserByLimit(Map<String,Integer> map);
    
    • 1

    2、Mapper.xml

    
        <select id="getUserByLimit" parameterType="map" resultMap="UserMap">
            select * from user limit #{startIndex},#{pageSize}
        select>
    
    • 1
    • 2
    • 3
    • 4

    3、测试

    @Test
        public void getUserByLimit(){
            SqlSession sqlSession = MybatisUtils.getSqlSession();
            UserMapper mapper = sqlSession.getMapper(UserMapper.class);
            HashMap<String, Integer> hashMap = new HashMap<String, Integer>();
            hashMap.put("startIndex",0);
            hashMap.put("pageSize",3);
            List<User> userByLimit = mapper.getUserByLimit(hashMap);
            for (User user : userByLimit) {
                System.out.println(user);
            }
            sqlSession.close();
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    在这里插入图片描述

    2、RowBounds实现分页

    不使用sql进行分页
    1、接口

        //rowbounds分页
        List<User> getUserByRouBounds();
    
    • 1
    • 2

    2、mapper.xml

        
        <select id="getUserByRouBounds" resultMap="UserMap">
            select * from user
        select>
    
    • 1
    • 2
    • 3
    • 4

    3、测试

        @Test
        public void getUserByRowBounds() {
            SqlSession sqlSession = MybatisUtils.getSqlSession();
            //Rowbounds实现
            RowBounds rowBounds = new RowBounds(1, 3);
            List<User> userList = sqlSession.selectList("com.jjl.dao.UserMapper.getUserByRouBounds",null,rowBounds);
            for (User user : userList) {
                System.out.println(user);
            }
            sqlSession.close();
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    3、分页插件

    在这里插入图片描述
    官方文档:https://pagehelper.github.io/docs/howtouse/

    十二、使用注解开发

    1、面向接口编程

    大家之前都学过面向对象编程,也学习过接口,但在真正的开发中,很多时候我们会选择面向接口编程
    根本原因:解耦,可拓展,提高复用,分层开发中,上层不用管具体的实现,大家都遵守共同的标准,使得开发变得更容易,规范性更好
    在一个面向对象的系统中,系统的各种功能是由许许多多的不同对象协作完成的。在这种情况下,各个对象内部是如何实现自己的,对系统设计人员来讲就不那么重要了;而各个对象之前的协作关系则成为系统设计的关键,小到不同类之间的通信,大到各模块之间的交互,在系统设计之初都是要着重考虑的,这也是系统设计的主要工作内容,面向接口编程就是指按照这种思想来编程。

    关于接口的理解

    • 接口从更深层次的理解,应是定义(规范,约束)与实现(名实分离)的分离。
    • 接口的本身反映了系统设计人员对系统的抽象理解。
    • 接口应有两类:
      • 第一类是对一个个体的抽象,它可对应为一个抽象体(abstract class);
      • 第二类是对一个个体某一方面的抽象,即形成一个抽象面(interface);
    • 一个体有可能有多个抽象面,抽象体与抽象面是有区别的

    2、案例测试

    1、编写接口

    package com.jjl.dao;
    import com.jjl.pojo.User;
    import org.apache.ibatis.annotations.Select;
    import java.util.List;
    
    public interface UserMapper {
        @Select("select * from user")
        List<User> getUsers();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    2、绑定接口
    在mybatis-config.xml中添加

    
        <mappers>
            <mapper class="com.jjl.dao.UserMapper"/>
        mappers>
    
    • 1
    • 2
    • 3
    • 4

    3、测试实现

    import com.jjl.dao.UserMapper;
    import com.jjl.pojo.User;
    import com.jjl.utils.MybatisUtils;
    import org.apache.ibatis.session.SqlSession;
    import org.junit.Test;
    import java.util.List;
    public class UserMapperTest {
        @Test
        public void test(){
            SqlSession sqlSession = MybatisUtils.getSqlSession();
            //底层使用的是反射机制
            UserMapper mapper = sqlSession.getMapper(UserMapper.class);
            List<User> users = mapper.getUsers();
            for (User user : users) {
                System.out.println(user);
            }
            sqlSession.close();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    4、测试结果:
    在这里插入图片描述
    没法做字段映射(结构集映射),mybatis建议使用xml

    Mybatis详细的底层分析
    在这里插入图片描述

    十三、使用注解实现CRUD

    1、修改sqlSessionFactory 工具类

    修改sqlSessionFactory 工具类为自动提交为自动提交,真实开发不建议修改使用

    package com.jjl.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;
    
    //sqlSessionFactory 工具类
    public class MybatisUtils {
        private  static SqlSessionFactory sqlSessionFactory = null;
        static {
            try {
                //获取sqlSessionFactory对象
                String resource = "mybatis-config.xml";
                InputStream inputStream = Resources.getResourceAsStream(resource);
                sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        public static SqlSession getSqlSession(){
            //sqlSessionFactory.openSession(true):自动提交,真实项目中尽量不要使用自动提交
            return sqlSessionFactory.openSession(true);
        }
    }
    
    • 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

    2、编写接口和注解

    这种使用注解实现CRUD只能用于简单sql语句

    package com.jjl.dao;
    import com.jjl.pojo.User;
    import org.apache.ibatis.annotations.*;
    import java.util.List;
    public interface UserMapper {
        @Select("select * from user")
        List<User> getUsers();
    
        //指定条件查询
        //方法有多个参数时,所有参数前面必须加上@Param("id")注解
        @Select("select * from user where id=#{id} and name=#{name}")
        User getUserById(@Param("id") int id,@Param("name") String name);
    
        //插入数据
        @Insert("insert into user(id,name,pwd) values (#{id},#{name},#{password})")
        int addUser(User user);
    
        //修改数据
        @Update("update user set name=#{name},pwd=#{password} where id=#{id}")
        int UpdateUser(User user);
    
        //删除数据
        @Delete("delete from user where id = #{id}")
        int deleteUser(@Param("id") int id);
    }
    
    • 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

    3、测试

    import com.jjl.dao.UserMapper;
    import com.jjl.pojo.User;
    import com.jjl.utils.MybatisUtils;
    import org.apache.ibatis.session.SqlSession;
    import org.junit.Test;
    import java.util.List;
    public class UserMapperTest {
        //查询全部数据
        @Test
        public void test(){
            SqlSession sqlSession = MybatisUtils.getSqlSession();
            //底层应用反射
            UserMapper mapper = sqlSession.getMapper(UserMapper.class);
            List<User> users = mapper.getUsers();
            for (User user : users) {
                System.out.println(user);
            }
            sqlSession.close();
        }
    
        //指定条件查询
        @Test
        public void test2(){
            SqlSession sqlSession = MybatisUtils.getSqlSession();
            //底层应用反射
            UserMapper mapper = sqlSession.getMapper(UserMapper.class);
            User user1 = mapper.getUserById(2, "jjl");
            System.out.println(user1);
            sqlSession.close();
        }
    
        //添加数据
        @Test
        public void test3(){
            SqlSession sqlSession = MybatisUtils.getSqlSession();
            //底层应用反射
            UserMapper mapper = sqlSession.getMapper(UserMapper.class);
            int addUser = mapper.addUser(new User(9,"hell3","1234"));
            if (addUser>0){
                System.out.println("添加成功");
            }
            sqlSession.close();
        }
    
        //修改数据
        @Test
        public void test4(){
            SqlSession sqlSession = MybatisUtils.getSqlSession();
            //底层应用反射
            UserMapper mapper = sqlSession.getMapper(UserMapper.class);
            int addUser = mapper.UpdateUser(new User(9,"文盛","9999"));
            if (addUser>0){
                System.out.println("修改成功");
            }
            sqlSession.close();
        }
    
        //删除数据
        @Test
        public void test5(){
            SqlSession sqlSession = MybatisUtils.getSqlSession();
            UserMapper mapper = sqlSession.getMapper(UserMapper.class);
            int i = mapper.deleteUser(7);
            if (i>0){
                System.out.println("删除成功");
            }
            sqlSession.close();
        }
    
    }
    
    • 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

    4、关于@param()注解

    • 基本类型的参数或者String类型,需要加上
    • 引用类型不需要加
    • 如果只有一个基本类型的话,可以忽略,但是建议都加上
    • 我们在SQL中引用的就是我们在@Param()中设定的属性名

    在使用mybatis的时候我们会使用到#{}和${}这两个符号来为sql语句传参数

    • #{}是预编译处理,是占位符,${}是字符串替换,是拼接符
    • 使用#{}可以有效的防止sql注入,提高系统的安全性

    十四、Lombok

    Project Lombok 是一个 java 库,可自动插入您的编辑器和构建工具,为您的 java 增添趣味。
    不要再编写getter 或 equals 方法,使用一个注释的类就有一个功能齐全的构建器、自动化您的日志记录变量。

    使用步骤

    1、在IDEA中安装Lombok插件
    2、在项目中导入Lombok的jar包

            <dependency>
                <groupId>org.projectlombokgroupId>
                <artifactId>lombokartifactId>
                <version>1.18.24version>
            dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5

    3、在实体类上加注解

    package com.jjl.pojo;
    import lombok.*;
    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    @ToString
    @Getter
    @Setter
    public class User {
        private int id;
        private String name;
        private String password;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    @Getter and @Setter
    @FieldNameConstants
    @ToString
    @EqualsAndHashCode
    @AllArgsConstructor, @RequiredArgsConstructor and @NoArgsConstructor
    @Log, @Log4j, @Log4j2, @Slf4j, @XSlf4j, @CommonsLog, @JBossLog, @Flogger, @CustomLog
    @Data
    @Builder
    @SuperBuilder
    @Singular
    @Delegate
    @Value
    @Accessors
    @Wither
    @With
    @SneakyThrows

    十五、多对一的处理

    学习用的SQL语句:
    在这里插入图片描述

    CREATE TABLE `teacher` (
       `id` INT(10) NOT NULL,
       `name` VARCHAR(30) DEFAULT NULL,
       PRIMARY KEY (`id`)
    ) ENGINE=INNODB DEFAULT CHARSET=utf8;
    
    INSERT INTO teacher(`id`, `name`) VALUES (1, '秦老师');
    
    CREATE TABLE `student` (
       `id` INT(10) NOT NULL,
       `name` VARCHAR(30) DEFAULT NULL,
       `tid` INT(10) DEFAULT NULL,
       PRIMARY KEY (`id`),
       KEY `fktid` (`tid`),
       CONSTRAINT `fktid` FOREIGN KEY (`tid`) REFERENCES `teacher` (`id`)
    ) ENGINE=INNODB DEFAULT CHARSET=utf8;
    INSERT INTO `student` (`id`, `name`, `tid`) VALUES (1, '小明', 1);
    INSERT INTO `student` (`id`, `name`, `tid`) VALUES (2, '小红', 1);
    INSERT INTO `student` (`id`, `name`, `tid`) VALUES (3, '小张', 1);
    INSERT INTO `student` (`id`, `name`, `tid`) VALUES (4, '小李', 1);
    INSERT INTO `student` (`id`, `name`, `tid`) VALUES (5, '小王', 1);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    1、测试环境搭建

    1、导入lombok
    2、新建实体类Teacher、Student

    package com.jjl.pojo;
    import lombok.Data;
    
    @Data
    public class Student {
        private int id;
        private String name;
        //学生需要关联一个老师
        private Teacher teacher;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    package com.jjl.pojo;
    import lombok.Data;
    
    @Data
    public class Teacher {
        private int id;
        private String name;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    3、建立Mapper接口

    package com.jjl.dao;
    public interface StudentMapper {
    }
    
    • 1
    • 2
    • 3
    package com.jjl.dao;
    
    import com.jjl.pojo.Teacher;
    import org.apache.ibatis.annotations.Param;
    import org.apache.ibatis.annotations.Select;
    
    public interface TeacherMapper {
        @Select("select * from teacher where id=#{tid}")
        Teacher getTeacher(@Param("tid") int id);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    4、建立Mapper.xml文件

    
    DOCTYPE mapper
            PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
            "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    
    <mapper namespace="com.jjl.dao.StudentMapper">
        
    mapper>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    
    DOCTYPE mapper
            PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
            "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    
    <mapper namespace="com.jjl.dao.TeacherMapper">
    
    mapper>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    5、在核心配置文件(mybatis-config.xml)中绑定Mapper接口文件

        <mappers>
            <mapper class="com.jjl.dao.StudentMapper"/>
            <mapper class="com.jjl.dao.TeacherMapper"/>
        </mappers>
    
    • 1
    • 2
    • 3
    • 4

    5、测试查询

    import com.jjl.dao.TeacherMapper;
    import com.jjl.pojo.Teacher;
    import com.jjl.utils.MybatisUtils;
    import org.apache.ibatis.session.SqlSession;
    
    public class Ttest {
        public static void main(String[] args) {
            SqlSession sqlSession = MybatisUtils.getSqlSession();
            TeacherMapper mapper = sqlSession.getMapper(TeacherMapper.class);
            Teacher teacher = mapper.getTeacher(1);
            System.out.println(teacher);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    2、按照查询嵌套处理

    需求:查询所有学生的信息,以及对应老师的信息
    1、接口编写

    package com.jjl.dao;
    import com.jjl.pojo.Student;
    import java.util.List;
    
    public interface StudentMapper {
        //查询所有学生的信息,以及对应老师的信息
    /*
    * 思路:
    * 1、查询所有的学生信息
    * 2、根据查询出来的学生的tid,寻找对应的老师
    * */
        List<Student> getStudent();
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    2、编写StudentMapper.xml

    <?xml version="1.0" encoding="UTF8" ?>
    <!DOCTYPE mapper
            PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
            "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    <!--configuration核心配置文件-->
    <mapper namespace="com.jjl.dao.StudentMapper">
        <!--查询所有学生的信息,以及对应老师的信息
        思路:
        1、查询所有的学生信息
        2、根据查询出来的学生的tid,寻找对应的老师
        -->
        <select id="getStudent" resultMap="StudentTeacher">
            select * from student
        </select>
        <resultMap id="StudentTeacher" type="Student">
            <result property="id" column="id"/>
            <result property="name" column="name"/>
    <!--        复杂的属性需要单独处理
                对象:association
                集合:collection
                -->
            <association property="teacher" column="tid" javaType="Teacher" select="getTeacher"/>
        </resultMap>
    
        <select id="getTeacher" resultType="Teacher">
            select * from teacher where id=#{id}
        </select>
    </mapper>
    
    • 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

    3、测试

        @Test
        public void testStudent(){
            SqlSession sqlSession = MybatisUtils.getSqlSession();
            StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
            List<Student> studentList = mapper.getStudent();
            for (Student student : studentList) {
                System.out.println(student);
            }
            sqlSession.close();
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    3、按照结果嵌套处理

    • 编写接口
      List getStudent2();
    • 编写核心sql处理
          <select id="getStudent2" resultMap="StudentTeacher2">
              select s.id sid,s.name sname,t.name tname from student s,teacher t where s.tid=t.id;
          </select>
          <resultMap id="StudentTeacher2" type="Student">
              <result property="id" column="sid"/>
              <result property="name" column="sname"/>
              <association property="teacher" javaType="Teacher">
                  <result property="name" column="tname"/>
              </association>
          </resultMap>
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
    • 测试
          @Test
          public void testStudent2(){
              SqlSession sqlSession = MybatisUtils.getSqlSession();
              StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
              List<Student> studentList = mapper.getStudent2();
              for (Student student : studentList) {
                  System.out.println(student);
              }
              sqlSession.close();
          }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10

    十六、一对多处理

    1、环境搭建

    • 实体类
      student

      package com.jjl.pojo;
      import lombok.*;
      @Data
      @ToString
      @NoArgsConstructor
      @AllArgsConstructor
      @Getter
      @Setter
      public class Student {
          private int id;
          private String name;
          private int tid;
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13

      teacher

      package com.jjl.pojo;
      import lombok.*;
      import java.util.List;
      
      @Data
      @AllArgsConstructor
      @NoArgsConstructor
      @ToString
      @Getter
      @Setter
      public class Teacher {
          private int id;
          private String name;
      
          //一个老师拥有多个学生
          private List<Student> students;
      }
      
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
    • 编写接口

      public interface TeacherMapper {
          //获取老师
          List<Teacher> getTeacher();
      }
      
      • 1
      • 2
      • 3
      • 4
    • 编写sql

      <?xml version="1.0" encoding="UTF8" ?>
      <!DOCTYPE mapper
              PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
              "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
      <!--configuration核心配置文件-->
      <mapper namespace="com.jjl.dao.TeacherMapper">
          <select id="getTeacher" resultType="Teacher">
              select * from teacher;
          </select>
      </mapper>
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
    • 测试

      @Test
          public void test(){
              SqlSession sqlSession = MybatisUtils.getSqlSession();
              TeacherMapper mapper = sqlSession.getMapper(TeacherMapper.class);
              List<Teacher> teacher = mapper.getTeacher();
              for (Teacher teachers : teacher) {
                  System.out.println(teachers);
              }
              sqlSession.close();
          }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10

    2、按结果集查询

    • 编写接口

      public interface TeacherMapper {
          //获取指定老师下的所有学生及老师的信息
          Teacher getTeacher(@Param("tid") int id);
      
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
    • 编写核心sql

      
      DOCTYPE mapper
              PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
              "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
      
      <mapper namespace="com.jjl.dao.TeacherMapper">
      
          <select id="getTeacher" resultMap="TeacherStudent">
              select s.id sid,s.name sname,t.name tname,t.id tid from student s, 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="id" column="sid"/>
                  <result property="name" column="sname"/>
                  <result property="tid" column="tid"/>
              collection>
          resultMap>
      mapper>
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
    • 测试

          @Test
          public void test(){
              SqlSession sqlSession = MybatisUtils.getSqlSession();
              TeacherMapper mapper = sqlSession.getMapper(TeacherMapper.class);
              Teacher teacher = mapper.getTeacher(1);
              System.out.println(teacher);
              /*
              输出的结果:
              * Teacher(id=1, name=秦老师,
              * students=[
              * Student(id=1, name=小明, tid=1), Student(id=2, name=小红, tid=1),
              * Student(id=3, name=小张, tid=1), Student(id=4, name=小李, tid=1),
              * Student(id=5, name=小王, tid=1)
              * ])
              * */
              sqlSession.close();
          }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17

    3、按照查询进行处理

    • 编写接口
      Teacher getTeacher2(@Param("tid") int id);
    • 核心sql
      <!--    按子查询-->
          <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" select="getStudentByTeacherId" column="id"/>
          </resultMap>
      
          <select id="getStudentByTeacherId" resultType="Student">
              select * from student where tid=#{itd}
          </select>
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
    • 测试
      @Test
          public void test2(){
              SqlSession sqlSession = MybatisUtils.getSqlSession();
              TeacherMapper mapper = sqlSession.getMapper(TeacherMapper.class);
              Teacher teacher2 = mapper.getTeacher2(1);
              System.out.println(teacher2);
              sqlSession.close();
          }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8

    4、小结

    • 关联 - association 【多对一】
    • 集合 - collection 【一对多】
    • javaType & ofType
      • javaType:用来指定实体类中的属性的类型
      • ofType:用来指定映射到List或者集合中的pojo类型,泛型中的约束类型

    注意点

    • 保证SQL的可读性,尽量保证通俗易懂
    • 注意一对多和多对一中,属性名和字段的问题!
    • 如果问题不好排除错误,可以使用日志,建议使用Log4j
  • 相关阅读:
    【数据结构】【版本1.2】【线性时代】——双向链表
    Java 接口详解
    配音工具大jiemi|盘点市面上那些超好用的配音神器,短视频作者看过来
    stacking集成模型预测回归问题
    【iOS】—— ViewController生命周期
    P4 开发实践 — 硬件 DSA 架构
    ANSYS_Q3D仿真激光发射的寄生电感
    离线安装AWX 15.0.1
    Nacos源码分析专题(二)-服务注册
    Windows系统搭建FTP服务器教程
  • 原文地址:https://blog.csdn.net/qq_43427354/article/details/126241120