从小白到精通MyBatis之旅

一、MyBatis简介

1.1 框架概念

框架,就是软件的半成品,完成了软件开发过程中的通用操作,程序员只需很少或者不用加工就能实现特定的功能,从而简化开发人员在软件开发中的步骤,提高开发效率。

1.2 常用框架

  • MVC框架:简化了Servlet的开发步骤

    • Struts2
    • SpringMVC
  • 持久层框架:完成数据库操作的框架

    • apache DBUtils
    • Hibernate
    • spring JPA
    • MyBatis
  • 胶水框架:Spring

SSM Spring 、SpringMVC、 MyBatis

SSH Spring、Struts2、Hibernate

1.3 MyBatis介绍

MyBatis 是一个半自动的ORM框架

ORM(Object Relation Mapping)对象关系映射,将Java中的一个对象与数据表中一行记录一一对应

ORM框架提供了实体类与数据表的映射关系,通过映射文件的配置,实现对象的持久化

  • MyBatis的前身是iBatis,是Apache软件基金会提供的一个开源项目
  • 2010 年iBatis迁移到Google code,正式更名为MyBatis
  • 2013年迁移到GitHub托管
  • MyBatis特点:
    • 支持自定义SQL、存储过程
    • 对原有的JDBC进行了封装,几乎消除了所有JDBC代码让开发者只需关注SQL本身
    • 支持XML和注解配置方式自定完成ORM操作,实现结果映射

二、MyBatis框架部属

框架部属,就是将框架引入到我们的项目中

2.1 创建Maven项目

  • Java工程
  • Web工程

2.2 在项目中添加MyBatis依赖

  • 在Pom.xml中添加依赖
    • mybatis
    • mysql driver
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>5.1.47</version>
</dependency>

<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis</artifactId>
    <version>3.4.6</version>
</dependency>
    
  

2.3 创建Mybatis配置文件

  • 创建自定义模板:选择resources----右键New----Edit File Templates

在这里插入图片描述

  • resources中创建名为mybatis-config.xml的文件

  • 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配置数据库连接信息-->
    <!-- 在environments标签中可以定义多个environment标签,每个environment标签可以定义一套连接配置-->
    <!-- default属性,用来指定使用哪个environment标签-->
    <environments default="mysql">
        <environment id="mysql">
            <!--transactionManager标签用于配置数据库管理方式 -->
            <transactionManager type="JDBC"></transactionManager>
            <!--dataSource标签就是用来配置数据库连接信息 -->
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/fmwy?characterEncoding=utf-8"/>
                <property name="username" value="root"/>
                <property name="password" value="lgw19991218"/>
            </dataSource>
        </environment>


    </environments>



</configuration>

三、MyBatis框架使用

案例:学生信息的数据库操作

3.1 创建数据表

tb_students
在这里插入图片描述

3.2 创建实体类

Student.java
在这里插入图片描述

3.3 创建DAO接口,定义操作方法

package com.qfedu.dao;

import com.qfedu.pojo.Student;

public interface StudentDAO {

       public int insertStudent(Student student);
   
}

3.4 创建DAO接口的映射文件

  • 在resources目录下,新建名为mappers文件夹

  • 在mappers中新建名为StudentMapper.xml 的映射文件(可以根据模板创建)

  • 在映射文件中对DAO中定义的方法进行实现:

    <?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文件相当于DAO接口的实现类,namespace属性要指定实现DAO接口的全限定名-->
    <mapper namespace="com.qfedu.dao.StudentDAO">
    
        <insert id="insertStudent" parameterType="com.qfedu.pojo.Student">
            insert into tb_students(stu_num,stu_name,stu_gender,stu_age)
            values (#{stuNum},#{stuName},#{stuGender},#{stuAge})
    
        </insert>
        <delete id="deleteStudent">
            delete from tb_students where stu_num=#{stuNum}
        </delete>
    
    </mapper>
    

    3.5 将映射文件添加到主配置文件

    <?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配置数据库连接信息-->
        <!-- 在environments标签中可以定义多个environment标签,每个environment标签可以定义一套连接配置-->
        <!-- default属性,用来指定使用哪个environment标签-->
        <environments default="mysql">
            <environment id="mysql">
                <!--transactionManager标签用于配置数据库管理方式 -->
                <transactionManager type="JDBC"></transactionManager>
                <!--dataSource标签就是用来配置数据库连接信息 -->
                <dataSource type="POOLED">
                    <property name="driver" value="com.mysql.jdbc.Driver"/>
                    <property name="url" value="jdbc:mysql://localhost:3306/fmwy?characterEncoding=utf-8"/>
                    <property name="username" value="root"/>
                    <property name="password" value="lgw19991218"/>
                </dataSource>
            </environment>
    
    
        </environments>
    
        <mappers>
            <mapper resource="mappers/StudentMapper.xml"></mapper>
        </mappers>
    
    
    
    </configuration>
    

四、单元测试

4.1 添加单元测试依赖

 <!-- junit -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>

4.2 创建单元测试类

在被测试类名后alt+insert-----选择Test
在这里插入图片描述
在这里插入图片描述
package com.qfedu.dao;

import com.qfedu.pojo.Student;
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;

import static org.junit.Assert.*;

public class StudentDAOTest {

    @org.junit.Test
    public void insertStudent() {
     try {
         //加载mybatis配置文件
         InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
         SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
         //会话工厂
         SqlSessionFactory factory = builder.build(is);
         //会话(连接)
         SqlSession sqlSession = factory.openSession();

         StudentDAO studentDAO = sqlSession.getMapper(StudentDAO.class);

           //测试StudentDAO中的方法
         int i = studentDAO.insertStudent(new Student(0,"10003","李三","男",21));
         sqlSession.commit();
         System.out.println(i);

         
     }catch (IOException e){
         e.printStackTrace();

     }
     }

    @org.junit.Test
    public void deleteStudent() {
    }
}

五、MyBatis的CRUD

案例:学生信息的增删查改

5.1 添加操作

如上略

5.2 删除操作

根据学号删除一条学生信息

  • 在StudentDAO中定义删除方法
StudentDAO
在这里插入图片描述
  • 在StudentMapper.xml中对接口方法进行“实现”
StudentMapper.xml
在这里插入图片描述
  • 测试:在studentDAO的测试类中添加测试方法
studentDAO
在这里插入图片描述

5.3 修改操作

根据学号,修改其他字段信息

studentDAO
在这里插入图片描述

5.4 查询操作—查询所有

  • 在StudentDAO接口定义操作方法
StudentDAO
在这里插入图片描述
  • 在StudentMapper.xml中”实现“DAO中定义的方法
StudentMapper.xml
在这里插入图片描述
  • 单元测试
StudentDAOTest
在这里插入图片描述

5.5 查询操作—查询一条记录

根据学号查询一个学生信息

  • 在StudentDAO接口定义操作方法
StudentDAO
在这里插入图片描述
  • 在StudentMapper.xml中配置StudentDAO接口的方法实现–SQL
StudentMapper.xml
在这里插入图片描述
  • 单元测试
testQueryStudent
在这里插入图片描述

5.6 查询操作-多条件查询

分页查询(参数 start,pageSize)

  • 在StudentDAO中定义操作方法,如果方法有多个参数,使用@Param注解声明参数的别名
StudentDAO
在这里插入图片描述
  • 在StudnetMapper.xml 配置sql时,使用**#{别名}**获取到指定的参数

StudnetMapper.xml
在这里插入图片描述

注意如果DAO操作方法没有通过@Param指定参数别名,在SQL中也可以通过arg0,arg1…或者param1,param2…获取参数

  • 单元测试
单元测试
在这里插入图片描述

5.7 查询操作-查询总记录数

  • 在StudentDAO接口中定义操作方法
StudentDAO
在这里插入图片描述
  • 在StudnetMapper.xml 配置sql,通过resultType指定当前操作的返回类型为int
StudnetMapper.xml
在这里插入图片描述
  • 单元测试
单元测试
在这里插入图片描述

5.8 添加操作回填生成的主键

  • StudentMapper.xml的添加操作标签–insert
StudentMapper.xml
在这里插入图片描述

六、MyBatis工具类封装

  • MyBatisUtil
package com.qfedu.utils;

import com.qfedu.dao.StudentDAO;
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;

public class MyBatisUtil {
    private static SqlSessionFactory factory;
    private static  final ThreadLocal<SqlSession> local = new ThreadLocal<>();

    static {
        try{
            InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
            //SqlSessionFactoryBuilder
            SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
            //SqlSessionFactory表示Mybatis的会话工厂
             factory =builder.build(is);
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
      public static  SqlSessionFactory getFactory(){
        return factory;
      }


      public static SqlSession getSqlSession(){
          SqlSession sqlSession = local.get();
          if (sqlSession == null){
              sqlSession =factory.openSession();
              local.set(sqlSession);
          }
          return sqlSession;
      }

      public static <T extends Object>T getMapper(Class<T> c){
        SqlSession sqlSession = getSqlSession();
        return sqlSession.getMapper(c);
      }


}

七、事务管理

SqlSession对象

  • getMapper(DAO.class):获取Mapper(DAO接口的实例)
  • 事务管理

7.1 手动提交事务

  • sqlSession.commit();提交事务
  • sqlSession.rollback();事务回滚
@org.junit.Test
    public void insertStudent() {SqlSession sqlSession = MyBatisUtil.getSqlSession();
        //1.当我们获取sqlSession对象时,就默认开启了事务
        //通过会话获取DAO对象
        try{
            StudentDAO studentDAO = sqlSession.getMapper(StudentDAO.class);
        // 测试(StudentDAO中的方法)
            Student student = new Student(0,"10009","L","男",21);
            int i = studentDAO.insertStudent(student);
            System.out.println(student);
            //2.操作完成并成功之后,需要手动提交
            sqlSession.commit();
            System.out.println(i);
        }catch (Exception e){
            //3.当操作出现异常。调用rollback进行回滚

            sqlSession.rollback();
        }

     }

7.2 自动提交事务

通过SqlSessionFactory调用openSession方法获取SqlSession对象时,可以通过参数设置事务是否自动提交:

  • 如果参数设置为true,表示自定提交事务:factory.openSession(true);
  • 如果参数设置为false,或者不设置参数,表示手动提交:factory.openSession();/factory.openSession(false);

myBatisUtil优化

package com.qfedu.utils;

import com.qfedu.dao.StudentDAO;
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;

public class MyBatisUtil {
    private static SqlSessionFactory factory;
    private static  final ThreadLocal<SqlSession> local = new ThreadLocal<>();

    static {
        try{
            InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
            //SqlSessionFactoryBuilder
            SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
            //SqlSessionFactory表示Mybatis的会话工厂
             factory =builder.build(is);
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
      public static  SqlSessionFactory getFactory(){
        return factory;
      }
      public static SqlSession getSqlSession(){
        return getSqlSession(false);
      }

      private static SqlSession getSqlSession(boolean isAutoCommit){
          SqlSession sqlSession = local.get();
          if (sqlSession == null){
              //通过SqlSessionFactory调用openSession方法获取SqlSession对象时,可以通过参数设置事务是否自动提交
              //如果参数设置为true,表示自定提交事务;factory,openSession(true);
              //如果参数设置为false,或者不设置参数,表示手动提交:factor.openSession();factor.openSession(false)
              sqlSession =factory.openSession(isAutoCommit);
              local.set(sqlSession);
          }
          return sqlSession;
      }

      public static <T extends Object>T getMapper(Class<T> c){
        SqlSession sqlSession = getSqlSession(true);
        return sqlSession.getMapper(c);
      }


}

测试操作

public void deleteStudent() {
      
          StudentDAO studentDAO = MyBatisUtil.getMapper(StudentDAO.class);
          int i= studentDAO.deleteStudent("10003");         
     
    }

业务逻辑层自动事务管理

在这里插入图片描述

八、MyBatis主配置文件

mybatis-config.xml是MyBats框架的主配置文件,只要用于配置MyBatis数据源及属性信息

8.1 properties标签

用于设置键值对,或者加载属性文件

  • 在resources目录下创建jdbc.properties文件,配置键值对如下:
mysql_driver=com.mysql.jdbc.Driver
mysql_url=jdbc:mysql://localhost:3306/fmwy?characterEncoding=utf-8
mysql_username=root
mysql_password=lgw19991218
  • 在mybatis-config.xml中通过properties标签引用jdbc.properties文件;引入之后,在配置environment时可以直接使用jdbc.properties的key获取对应的value
<?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>
    <!--properties标签:1.可以定义键值对  2.可以引用属性文件  -->
    <properties resource="jdbc.properties"></properties>
    <!-- 在environments配置数据库连接信息-->
    <!-- 在environments标签中可以定义多个environment标签,每个environment标签可以定义一套连接配置-->
    <!-- default属性,用来指定使用哪个environment标签-->
    <environments default="mysql">
        <environment id="mysql">
            <!--transactionManager标签用于配置数据库管理方式 -->
            <transactionManager type="JDBC"></transactionManager>
            <!--dataSource标签就是用来配置数据库连接信息 -->
            <dataSource type="POOLED">
                <property name="driver" value="${mysql_driver}"/>
                <property name="url" value="${mysql_url}"/>
                <property name="username" value="${mysql_username}"/>
                <property name="password" value="${mysql_password}"/>
            </dataSource>
        </environment>



    </environments>

    <mappers>
        <mapper resource="mappers/StudentMapper.xml"></mapper>
    </mappers>



</configuration>

8.2 settings标签

 <!--设置mybatis的属性 -->
    <settings>
        <!-- 启动二级缓存 -->
        <setting name="cacheEnabled" value="true"/>
        <!-- 启动延迟加载-->
        <setting name="lazyLoadingEnable" value="true"/>
    </settings>

8.3 typeAliases标签

<!--typeAliases标签用于给实体类取别名,在映射文件中可以直接使用别名来替代类的全限定名 -->
    <typeAliases>
        <typeAlias type="com.qfedu.pojo.Student" alias="Student"></typeAlias>
        <typeAlias type="com.qfedu.pojo.Book" alias="Book"></typeAlias>
    </typeAliases>

8.4 Plugins标签

<!--plugins标签,用于配置MyBatis插件(分页插件) -->
    <plugins>
        <plugin interceptor=""></plugin>
    </plugins>

8.5 envirments标签

<environments default="mysql">
        <!-- environment 标签用于配置数据库连接信息 -->
        <environment id="mysql">
            <!--transactionManager标签用于配置数据库管理方式
             type="JDBC"可以进行事务的提交和回滚操作
             type="MANAGED"依赖容器完成事务管理,本身不进行事务的提交和回滚操作
             -->
            <transactionManager type="JDBC"></transactionManager>
            <!--dataSource标签就是用来配置数据库连接信息 POOLED|UNPOOLED-->
            <dataSource type="POOLED">
                <property name="driver" value="${mysql_driver}"/>
                <property name="url" value="${mysql_url}"/>
                <property name="username" value="${mysql_username}"/>
                <property name="password" value="${mysql_password}"/>
            </dataSource>
        </environment>


    </environments>

8.6 mappers标签

加载映射配置(映射文件、DAO注解)

<!--mappers标签用于载入映射文件 -->
    <mappers>
        <mapper resource="mappers/StudentMapper.xml"></mapper>
    </mappers>

九、映射文件

9.1 MyBatist初始化

在这里插入图片描述

9.2 Mapper根标签

mapper文件相当于DAO接口的实现类,namespace属性要指定实现DAO接口的全限定名

9.3 insert标签

声明添加操作(sql:insert…)

常用属性

id属性,绑定对应DAO接口中的方法

ParameterType属性,用以指定接口中对应方法的参数类型(可省略)

useGeneratedKeys属性,设置添加操作是否需要回填生成的主键

keyProperty属性,指定回填的id设置到参数对象中的哪个属性

timeout属性,设置此操作的超时时间,如果不设置则一直等待

主键回填

在这里插入图片描述

9.4 delete标签

声明删除操作

9.5 update标签

声明修改操作

9.6 select标签

声明查询操作

  • Id属性,指定绑定方法的方法名
  • parameterType属性,设置参数类型
  • resultType属性,指定当前sql返回数据封装的对象类型(实体类)
  • resultMap属性,指定从数据表到实体类的字段和属性的对应关系
  • useCache属性,指定此查询操作是否需要缓存
  • timeout属性,设置超时时间

9.7 resultMap标签

<!--resultMap标签用于定义实体类与数据表的映射关系(ORM) -->
    <resultMap id="studentMap" type="com.qfedu.pojo.Student">
        <id column="sid" property="stuSid"/>
        <result column="stu_num" property="stuNum"/>
        <result column="stu_name" property="stuName"/>
        <result column="stu_gender" property="stuGender"/>
        <result column="stu_age" property="stuAge"/>
    </resultMap>

9.8 cache标签

设置当前DAO进行数据库操作时的缓存属性设置

<cache type="" size="" readOnly="false"/>

9.9 sql和include

SQL片段

在这里插入图片描述

十.分页插件

分页插件是一个独立于MyBatis框架之外的第三方插件;

10.1 添加分页插件的依赖

PageHelper:

<!--pagehelper分页插件-->
        <dependency>
            <groupId>com.github.pagehelper</groupId>
            <artifactId>pagehelper</artifactId>
            <version>5.1.10</version>
        </dependency>

10.2 配置插件

在mybatis的主配置文件mybatis-config.xml中通过plugins标签进行配置

<!--plugins标签,用于配置MyBatis插件(分页插件) -->
    <plugins>
        <plugin interceptor="com.github.pagehelper.PageInterceptor"></plugin>
    </plugins>

10.3 分页实例

对学生信息进行分页查询

@Test
    public void testListStudentsByPage(){
      StudentDAO studentDAO = MyBatisUtil.getMapper(StudentDAO.class);//sqlSession
        PageHelper.startPage(2,4);
      List<Student> students = studentDAO.listStudents();
        PageInfo<Student> PageInfo = new PageInfo<Student>(students);
        //PageInfo中就包含了数据及分页信息
        List<Student> list = PageInfo.getList();
        for (Student stu:list){
            System.out.println(stu);
        }
    }

多条件查询

 @Test
    public void testListStudentsByPage(){
      StudentDAO studentDAO = MyBatisUtil.getMapper(StudentDAO.class);//sqlSession
        PageHelper.startPage(2,4);            
        //PageInfo中就包含了数据及分页信息
        List<Student> list = studentDAO.listStudentsByGender("女");
        
    }

十一. 关联映射

11.1 实体关系

实体——数据实体,实体关系指的就是数据与数据之间的关系

例如:用户和角色、房屋和楼栋、订单和商品。

实体关系分为以下四种:

一对一关联

实例:人和身份证、学生和学生证 、用户基本信息和详情

数据表关系:

  • 主键关系(用户表主键和详情表主键相同时,表示是匹配的数据)

在这里插入图片描述

  • 唯一外键关联

在这里插入图片描述

用户登录:根据用户名查询用户信息,当用户表中数据量很大且字段很多时会严重影响查询的速度

一对多关联、多对一关联

实例:

  • 一对多:班级和学生、类别和商品
  • 多对一:学生和班级、商品和类别

数据表关系:

  • 在多的一端添加外键和一的一段进行关联

多对多关联

实例:用户和角色、角色和权限、房屋和业主、学生和社团、订单和商品

数据表关系:建立第三张关系表添加两个外键分别与两张表主键进行关联

用户 (user_id) 用户角色表(uid,rid) 角色(role_id)

11.2 创建项目,部属MyBatis框架

  • 创建web项目(maven)

在这里插入图片描述

  • 部属MyBatis框架
    • 添加依赖
<dependencies>
        <!-- mybatis -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.4.6</version>
        </dependency>

        <!-- mysql -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.47</version>
        </dependency>

    </dependencies>

配置文件(mybatis-config.xml)(resources目录)

<?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>
    <properties resource="jdbc.properties"></properties>
    
    <environments default="mysql">
        <environment id="mysql">
            <transactionManager type="JDBC"></transactionManager>
            <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>
</configuration>

jdbc.properties(resources目录)

driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/db_2022_mybatis?characterEncoding=utf-8
username=root
password=lgw19991218

帮助类

package 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;

public class MyBatisUtil {

    private static SqlSessionFactory factory;
    private static final ThreadLocal<SqlSession> local = new ThreadLocal<SqlSession>();

    static {
        try{
            InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
            factory = new SqlSessionFactoryBuilder().build(is);

        }catch (IOException e){
            e.printStackTrace();
        }
    }

    public static SqlSessionFactory getSqlSessionFactory(){
        return factory;
    }

    private static SqlSession getSqlsession(boolean isAutoCommit){
         SqlSession sqlSession = local.get();
         if (sqlSession == null){
            sqlSession = factory.openSession(isAutoCommit);
            local.set(sqlSession);
         }
         return sqlSession;
    }
    public static  SqlSession getSqlsession(){
        return getSqlsession(false);
    }

    public static <T extends Object>T getMapper(Class<T> c){
        SqlSession sqlSession = getSqlsession(true);
        return sqlSession.getMapper(c);
    }

}

11.3 一对一关联

实例:用户----详情

11.3.1 创建数据表

–用户信息表

create table users(
     user_id int primary key auto_increment,
     user_name varchar(20) not null unique,
     user_pwd varchar(20) not null,
     user_realname varchar(20) not null,
     user_img varchar(100) not null
);

–用户详情表

create table details(
     detail_id int primary key auto_increment,
     user_addr varchar(50) not null,
     user_tel char(11) not null,
     user_desc varchar(200),
     user_id int not null unique
);

constraint FK _USER foregin key (uid) references users(user_id)//物理连接

11.3.2 创建实体类
  • User
package com.qfedu.pojo;

import com.oracle.webservices.internal.api.databinding.DatabindingMode;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;

@Data//get()和set()方法
@NoArgsConstructor//无参构造器
@AllArgsConstructor//全体有参构造器
@ToString
public class User {
    private int userId;
    private String userName;
    private String userPwd;
    private String userRealname;
    private String userImg;
}

  • Detail
package com.qfedu.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;

@Data//get()和set()方法
@NoArgsConstructor//无参构造器
@AllArgsConstructor//全体有参构造器
@ToString

public class Detail {
    private int detailId;
    private String userAddr;
    private String userTel;
    private String userDes;
    private int userId;
}

11.3.3 添加操作(事务)

在添加用户的同时关联添加与之对应的详情

|在这里插入图片描述
|在这里插入图片描述
|
| ------------------------------------------------------------ | ------------------------------------------------------------ |
|在这里插入图片描述
|在这里插入图片描述
|
| 测试: |在这里插入图片描述
|

11.3.4一对一 关联查询

在查询用户的同时关联查询出与之对应的详情

  • 实体
UserDetail
在这里插入图片描述
在这里插入图片描述

映射文件

  • 连接查询
连接查询测试
在这里插入图片描述
在这里插入图片描述
  • 子查询
子查询(DetailMapper)测试和(Usermapper)
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

11.4 一对多关联

案例:班级(1)—学生(n)

11.4.1 创建数据表
--创建班级信息表
create table classes(
   cid int primary key auto_increment,
   cname varchar(30) not null unique,
   cdesc varchar(100)
);
--创建学生信息表
create table students(
   sid char(5) primary key,
   sname varchar(20) not null,
   sage int not null,
   scid int not null
);
11.4.2 创建实体类
ClazzStudent
在这里插入图片描述
在这里插入图片描述
11.4.3 关联查询

当查询一个班级的时候,要关联查询出这个班级下的所有学生

连接查询

映射配置测试
在这里插入图片描述
在这里插入图片描述

子查询

映射配置StudentDAO
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

11.5 多对一关联

实例:学生(n)—班级(1)

当查询一个学生的时候,关联查询这个学生所在的班级信息

11.5.1 创建实体类
StudentClazz
在这里插入图片描述
在这里插入图片描述
11.5.2 关联查询

连接查询

映射配置测试
在这里插入图片描述
在这里插入图片描述

子查询

映射文件测试
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

11.6 多对多关联

案例:学生(m)—课程(n)

11.6.1 创建数据表
--学生信息表(如上)
--课程信息表
create table courses(
   course_id int primary key auto_increment,
   course_name varchar(50) not null
);
--选课信息表/成绩表(学号、课程号、成绩)
create table grades(
   sid char(5) not null,
   cid int not null,
   score int not null
);
11.6.2 关联查询

查询学生时,同时查询学生选择的课程

studentCourse
在这里插入图片描述
在这里插入图片描述

根据课程编号查询时,同时查询选择了这门课程的学生

StudentCourse
在这里插入图片描述
在这里插入图片描述
连接查询关联配置测试
在这里插入图片描述
在这里插入图片描述
子查询测试
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

十二、动态SQL

交友网:珍爱网、百合网 筛选心仪对象 性别 年龄 城市

方讲朋 性别 女 select*from members where gender=‘女’

萝卜 性别 女 年龄 18-23 select*from members where gender=‘女’ and age <=23 and <=23

张三 年龄 城市

电商:淘宝、京东 筛选商品 羽毛球拍 品牌 价格

筛选

用户的筛选条件不同,我们完成筛选执行的SQL也不一样;我们可以通过穷举来——的完成不同条件的筛选,但是这种实现思路过于繁琐和复杂,MyBatis就提供了动态SQL的配置方式来实现多条件查询。

12.1 什么是动态SQL?

根据查询条件动态完成SQL的拼接

12.2 动态SQL使用案例

案例:心仪对象搜索

12.2.1 创建数据表
create table members(
    member_id int primary key auto_increment,
    member_nick varchar(20) not null unique,
    member_gender char(2) not null,
    member_age int not null,
    member_city varchar(30) not null
);
12.2.2 创建实体类
@Data
@NoArgsConstructor
@AllArgsConstructor
@ToString
public class Member {
    private int memberId;
    private String memberNick;
    private String memberGender;
    private int memberAge;
    private String memberCity;
}
12.2.3 创建DAO接口

在DAO接口中定义一个多条件查询的方法

public interface MemberDAO {
    //在多条件查询中,如果查询条件不确定,可以直接使用HashMap作为参数
    public List<Member> searchMember(HashMap<String,Object> params);

}

if标签的使用
在这里插入图片描述

在这里插入图片描述

12.3 where标签的用法:

在这里插入图片描述

<where>
        <if test="gender != null"><!--gender 就是参数对象的属性/参数Map的Key  -->
           and member_gender=#{gender}
        </if>
        <if test="minAge != null">
            and member_age &gt;=#{minAge}<!--&gt;代表大于 -->
        </if>
        <if test="maxAge != null">
            and member_age &lt;=#{maxAge}<!--&lt;代表小于 -->
        </if>
        <if test="city != null">
            and member_city =#{city}
        </if>
       </where>
       order by member_age

12.4 trim标签的用法

<trim prefix="where" prefixOverrides="and | or" suffix="order by member_age">
        <if test="gender != null"><!--gender 就是参数对象的属性/参数Map的Key  -->
           and member_gender=#{gender}
        </if>
        <if test="minAge != null">
            and member_age &gt;=#{minAge}<!--&gt;代表大于 -->
        </if>
        <if test="maxAge != null">
            and member_age &lt;=#{maxAge}<!--&lt;代表小于 -->
        </if>
        <if test="city != null">
            and member_city =#{city}
        </if>
        </trim>

12.5 foreach标签的使用

<select id="searchMemberByCity" resultMap="memberMap">
        select member_id,member_nick,member_gender,member_age,member_city
        from members where member_city in
        <foreach collection="list" item="cityName" separator="," open="(" close=")">
            #{cityName}
        </foreach>
    </select>

十三、模糊查询

案例:根据昵称查询会员信息(模糊匹配 like)

13.1 模糊查询实现

13.1.1 DAO

在这里插入图片描述

13.1.2 映射文件

在这里插入图片描述

13.1.3 测试

在这里插入图片描述

13.2 #{}和${}的区别

  • ${key} 表示获取参数,先获取参数的值拼接到SQL语句中,再编译执行SQL语句;肯引起SQL注入问题 。
  • #{Key} 表示获取参数,先完成SQL编译(预编译),预编译之后再将获取的参数设置到SQL与中,可以避免SQL注入。

十四、MyBatis日志配置

MyBatis做为一个封装好的ORM框架,其运行过程我们没办法跟踪,为了让开发者了解Mybatis执行流程及每个执行步骤完成的工作,MyBatis框架本身继承了log4j日志框架,对运行的过程进行跟踪记录。 我们只需对MyBatis进行相关的日志配置,就可以看到MyBatis运行过程中的日志信息。

14.1 添加日志框架依赖

<!-- https://mvnrepository.com/artifact/log4j/log4j -->
<dependency>
    <groupId>log4j</groupId>
    <artifactId>log4j</artifactId>
    <version>1.2.17</version>
</dependency>

14.2 添加日志配置文件

  • 在resources目录下创建名为log4j.properties文件
  • 在log4j.properties文件配置日志输出方式
#将等级为DEBUG的日志信息输出到Console和file这两个目的地,console和file的定义在下面代码
log4j.rootLogger=DEBUG,console,file
#输出到控制台
log4j.appender.console=org.apache.log4j.ConsoleAppender
log4j.appender.console.Target=System.out
log4j.appender.console.Threshold=DEBUG
log4j.appender.console.layout=org.apache.log4j.PatternLayout
#定义日志的打印格式 %t表示线程名称  %5 日志级别 
log4j.appender.console.layout.ConversionPattern=[%c]-%m%n
#文件输出的相关设置
log4j.appender.file=org.apache.log4j.RollingFileAppender
log4j.appender.file.File=./log/ceshi.log
log4j.appender.file.MaxFileSize=10mb
log4j.appender.file.Threshold=DEBUG
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=[%p][%d{yy-MM-dd}][%c]%m%n
#日志输出级别
log4j.logger.org.mybatis=DEBUG
log4j.logger.java.sql=DEBUG
log4j.logger.java.sql.Statement=DEBUG
log4j.logger.java.sql.ResultSet=DEBUG
log4j.logger.java.sql.PreparedStatement=DEBUG

14.3 日志信息的级别

在这里插入图片描述

十五、 配置数据库连接池-整合Druid

在这里插入图片描述

15.1 常见的连接池

  • DBCP
  • C3P0
  • Druid性能也比较好,提供了比较便捷的监控系统
  • HiKari性能最好

在这里插入图片描述

15.2 添加Druid依赖

<!-- https://mvnrepository.com/artifact/com.alibaba/druid -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid</artifactId>
    <version>1.2.11</version>
</dependency>

15.3 创建Druid连接池工厂

public class DruidDataSourceFactory extends PooledDataSourceFactory {
    public DruidDataSourceFactory(){
        this.dataSource =new DruidDataSource();
    }
}

15.4 将DruidDataSourceFactory配置给MyBatis数据源

<environments default="mysql">
        <environment id="mysql">
            <transactionManager type="JDBC"></transactionManager>

           <!--POOLED使用Mybatis内置的连接池实现 -->
            <!--mybatis需要一个连接池工厂,这个工厂可以产生数据库连接池pooledDataSourceFactory -->

            <dataSource type="com.qfedu.utils.DruidDataSourceFactory">
                <property name="driverClass" value="${driver}"/>
                <property name="jdbcUrl" value="${url}"/>
                <property name="username" value="${username}"/>
                <property name="password" value="${password}"/>
            </dataSource>
        </environment>
    </environments>

十六、MyBatis缓存

MyBatis是基于JDBC的封装,使数据库操作更加便捷;MyBatis除了对JDBC操作步骤进行封装之外也对其性能进行了优化:

  • 在MyBatis引入缓存机制,用于提升MyBatis的检索效率
  • 在MyBatis引入加载机制,用于减少对数据库不必要的访问

16.1 缓存的工作原理

缓存,就是储存数据的内存

在这里插入图片描述

16.2 MyBatis缓存

MyBatis缓存分为一级缓存和二级缓存

16.2.1 一级缓存

在这里插入图片描述

测试代码:

在这里插入图片描述

16.2.2 两次查询与数据库数据不一致问题

在这里插入图片描述

16.2.3 二级缓存

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

16.3 查询操作的缓存开关

在这里插入图片描述

十七、延迟加载

在这里插入图片描述


版权声明:本文为lgwhsai原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。