MyBatis框架(学习笔记)

MyBatis框架(学习笔记)

文章目录

1.1 软件开发常用结构

1.1.1界面层(表示层,视图层)

主要功能是接受用户的数据,显示请求的处理结果。使用 web 页面和用户交互,手机 app 也就是表示层的,用户在 app 中操作,业务逻辑在服务器端处理。

1.1.2业务逻辑层

接收表示传递过来的数据,检查数据,计算业务逻辑,调用数据访问层获取数据。

1.1.3数据访问层

与数据库打交道。主要实现对数据的增、删、改、查。将存储在数据库中的数据提交给业务层,同时将业务层处理的数据保存到数据库.

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gvTaB8uE-1660321060438)(C:\Users\13417\AppData\Roaming\Typora\typora-user-images\image-20220812100638299.png)]

三层的处理请求的交互:

客户端<—>界面层<—>业务逻辑层<—>数据访问层<—>数据库。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aVNHSKIg-1660321060439)(C:\Users\13417\AppData\Roaming\Typora\typora-user-images\image-20220812142647358.png)]

1.2框架是什么?

框架其实是半成品软件,就是一组组件,供你使用完成你自己的系统。从另一个角度来说框架一个舞台,你在舞台上做表演。在框架基础上加入你要完成的功能。

框架安全的,可复用的,不断升级的软件。

1.3MyBatis框架

1.3.1MyBatis框架介绍

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

  • iBATIS 一词来源于“internet”和“abatis”的组合,是一个基于 Java 的持久层框架。iBATIS 提供的持久层框架包括 SQL Maps 和 Data Access Objects(DAOs)

  • MyBatis 是一个优秀的基于 java 的持久层框架,内部封装了 jdbc,开发者只需要关注 sql 语句本身,而不需要处理加载驱动、创建连接、创建 statement、关闭连接,资源等繁杂的过程。

  • MyBatis 通过xml注解两种方式将要执行的各种 sql 语句配置起来,并通过 java 对象和 sql 的动态参数进行映射生成最终执行的 sql 语句,最后由 mybatis 框架执行 sql 并将结果映射为 java 对象并返回。

1.3.2MyBatis框架解决的主要问题

以前写连接数据库的增删改查步骤重复并且很麻烦

public void findStudent() {
Connection conn = null; 
Statement stmt = null;
ResultSet rs = null;
try {
//注册 mysql 驱动 
  Class.forName("com.mysql.jdbc.Driver");
//连接数据的基本信息 url ,username,password
String url = "jdbc:mysql://localhost:3306/springdb"; 
String username = "root";
String password = "123456";
//创建连接对象 
conn = DriverManager.getConnection(url, username, password);
//保存查询结果 
List<Student> stuList = new ArrayList<>();
//创建 Statement, 用来执行 sql 语句 
stmt = conn.createStatement();
//执行查询,创建记录集, 
rs = stmt.executeQuery("select * from student");
while (rs.next()) {
Student stu = new Student(); 
stu.setId(rs.getInt("id"));
stu.setName(rs.getString("name"));
stu.setAge(rs.getInt("age"));
//从数据库取出数据转为 Student 对象,封装到 List 集合 
stuList.add(stu);}
  }catch(Exception e){
      e.printStackTrace();
}finally{
   try{
if(rs != null)
      rs.lose();
if(pstm != null)
      pstm.close();
   if(con != null)
      con.close();
   
}catch(Exception e){
  e.printStackTrace();
}
}

MyBatis框架减轻使用 JDBC 的复杂性,不用编写重复的创建 Connetion , Statement ; 不用编写关闭资源代码。直接使用 java 对象,表示结果数据。让开发者专注 SQL的处理。 其他分心的工作由 MyBatis 代劳。

1.3.3MyBatis框架的结构

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cEptG9zq-1660321060440)(C:\Users\13417\AppData\Roaming\Typora\typora-user-images\image-20220812101243642.png)]

  1. mybatis配置 SqlMapConfig.xml,此文件作为mybatis的全局配置文件,配置了mybatis的运行环境等信息。 mapper.xml文件即sql映射文件,文件中配置了操作数据库的sql语句。此文件需要在SqlMapConfig.xml中加载。
  2. 通过mybatis环境等配置信息构造SqlSessionFactory即会话工厂 。
  3. 由会话工厂创建sqlSession即会话,操作数据库需要通过sqlSession进行。
  4. mybatis底层自定义了Executor执行器接口操作数据库,Executor接口有两个实现,一个是基本执行器、一个是缓存执行器。
  5. Mapped Statement也是mybatis一个底层封装对象,它包装了mybatis配置信息及sql映射信息等。mapper.xml文件中一个sql对应一个Mapped Statement对象,sql的id即是Mapped statement的id。
  6. Mapped Statement对sql执行输入参数进行定义,包括HashMap、基本类型、pojo,Executor通过Mapped Statement在执行sql前将输入的java对象映射至sql中,输入参数映射就是jdbc编程中对preparedStatement设置参数。
  7. Mapped Statement对sql执行输出结果进行定义,包括HashMap、基本类型、pojo,Executor通过Mapped Statement在执行sql后将输出结果映射至java对象中,输出结果映射过程相当于jdbc编程中对结果的解析处理过程。

1.4MyBatis入门案例

完成一个MyBatis基本CURD的操作

1.4.1准备MySQL数据库

CREATE DATABASE ssm DEFAULT CHARSET utf8;

use ssm;

CREATE TABLE `student` (
`id` int(11)  AUTO_INCREMENT primary key ,
`name` varchar(255) DEFAULT NULL,
`email` varchar(255) DEFAULT NULL,
`age` int(11) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
insert into student(name,email,age) values('张三','zhangsan@126.com',22);
insert into student(name,email,age) values('李四','lisi@126.com',21);
insert into student(name,email,age) values('王五','wangwu@163.com',22);
insert into student(name,email,age) values('赵六','zhaoliun@qq.com',24);
select * from student;

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7dkr3tJU-1660321060441)(C:\Users\13417\AppData\Roaming\Typora\typora-user-images\image-20220812102021365.png)]

1.4.2创建工程添加依赖

1.4.2.1新建maven项目,选quickstart模板

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-22kynnoq-1660321060441)(C:\Users\13417\AppData\Roaming\Typora\typora-user-images\image-20220812102429925.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-12Ii4jmP-1660321060442)(C:\Users\13417\AppData\Roaming\Typora\typora-user-images\image-20220812102531539.png)]

在这里插入图片描述

1.4.2.2补齐目录

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0X66kcms-1660321060444)(C:\Users\13417\AppData\Roaming\Typora\typora-user-images\image-20220812103450921.png)]

1.4.2.3添加依赖
<dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>
<!--    添加mybatis框架的依赖-->
    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis</artifactId>
      <version>3.5.1</version>
    </dependency>
<!--    添加mysql8.0驱动-->
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>8.0.22</version>
    </dependency>

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-luIryPjN-1660321060445)(C:\Users\13417\AppData\Roaming\Typora\typora-user-images\image-20220812103011723.png)]

1.4.2.4添加资源文件的指定
<!--添加资源文件的指定-->
<build>
  <resources>
    <resource>
      <directory>src/main/java</directory>
      <includes>
        <include>**/*.xml</include>
        <include>**/*.properties</include>
      </includes>
    </resource>

    <resource>
      <directory>src/main/resources</directory>
      <includes>
        <include>**/*.xml</include>
        <include>**/*.properties</include>
      </includes>
    </resource>
  </resources>
</build>

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AAnYp62k-1660321060446)(C:\Users\13417\AppData\Roaming\Typora\typora-user-images\image-20220812104337109.png)]

1.4.2.5在idear中添加数据库的可视化

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ouQ6yRVp-1660321060446)(C:\Users\13417\AppData\Roaming\Typora\typora-user-images\image-20220812104553870.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qHr2yQEJ-1660321060447)(C:\Users\13417\AppData\Roaming\Typora\typora-user-images\image-20220812104612103.png)]

在这里插入图片描述

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vQ4SxWf8-1660321060448)(C:\Users\13417\AppData\Roaming\Typora\typora-user-images\image-20220812105237278.png)]

1.4.2.6创建jdbc.properties的文件
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/ssm?useUnicode=true&characterEncoding=utf8
jdbc.username=root
jdbc.password=root

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZZCQi3Ra-1660321060449)(C:\Users\13417\AppData\Roaming\Typora\typora-user-images\image-20220812110710382.png)]

1.4.2.7创建sqlMapConfig.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>

</configuration>

<?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>

    <!--读取属性文件(jdbc.properties)
      属性:
         resources:从resources目录下找指定名称的文件加载
         url:使用绝对路径加载属性文件
             D:\course\16.MyBatis\04_project\mybatisall\mybatis_001_student\src\main\resources\jdbc.properties
    -->
    <properties resource="jdbc.properties"></properties>

    <!--设置日志输出底层执行的代码-->
    <settings>
        <setting name="logImpl" value="STDOUT_LOGGING"/>
    </settings>
    <!--注册实体类的别名-->
    <typeAliases>
        <!--单个实体类别名注册-->
        <!--<typeAlias type="com.bjpowernode.pojo.Student" alias="student"></typeAlias>-->
        <!--批量注册别名
          别名是类名的驼峰命名法(规范)
        -->
        <package name="com.bjpowernode.pojo"></package>
    </typeAliases>

    <!--配置数据库的环境变量(数据库连接配置)
       default:使用下面的environment标签的id属性进行指定配置
    -->
    <environments default="development">
        <!--开发时在公司使用的数据库配置
          id:就是提供给environments的default属性使用
        -->
        <environment id="development">
            <!--配置事务管理器
               type:指定事务管理的方式
                  JDBC:事务的控制交给程序员处理
                  MANAGED:由容器(Spring)来管理事务
            -->
            <transactionManager type="JDBC"></transactionManager>
            <!--配置数据源
               type:指定不同的配置方式
                  JNDI:java命名目录接口,在服务器端进行数据库连接池的管理
                  POOLED:使用数据库连接池
                  UNPOLLED:不使用数据库连接池
            -->
            <dataSource type="POOLED">
                <!--配置数据库连接的基本参数
                    private String driver;
                    private String url;
                    private String username;
                    private String password;
                -->
                <property name="driver" value="${jdbc.driverClassName}"></property>
                <property name="url" value="${jdbc.url}"></property>
                <property name="username" value="${jdbc.username}"></property>
                <property name="password" value="${jdbc.password}"></property>
            </dataSource>
        </environment>

        <!--&lt;!&ndash;在家的数据库配置&ndash;&gt;-->
        <!--<environment id="home">-->
            <!--<transactionManager type=""></transactionManager>-->
            <!--<dataSource type=""></dataSource>-->
        <!--</environment>-->

        <!--&lt;!&ndash;上线后的数据库配置&ndash;&gt;-->
        <!--<environment id="online">-->
            <!--<transactionManager type=""></transactionManager>-->
            <!--<dataSource type=""></dataSource>-->
        <!--</environment>-->
    </environments>

    <!--注册mapper.xml文件
       resource:从resources目录下找指定名称的文件注册
       url:使用绝对路径注册
       class:动态代理方式下的注册
    -->
    <mappers>
        <mapper resource="StudentMapper.xml"></mapper>
    </mappers>

</configuration>

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-W2tokLbK-1660321060450)(C:\Users\13417\AppData\Roaming\Typora\typora-user-images\image-20220812112851176.png)]

1.4.2.8创建学生的实体类

数据库表中的字段来创建,注意主键有自增,全参构造方法不需要带着id

package com.bue.vue.pojo;

/**
 * @ClassName Student
 * @Description TODO
 * @Author Jiang
 * @Date 2022/8/12 11:59
 * @Version 1.0
 **/
public class Student {
    private Integer id;
    private String name;
    private String eamil;
    private Integer age;

    public Student() {
    }

    public Student(String name, String eamil, Integer age) {
        this.name = name;
        this.eamil = eamil;
        this.age = age;
    }

    public Integer getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

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

    public String getEamil() {
        return eamil;
    }

    public void setEamil(String eamil) {
        this.eamil = eamil;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Student{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", eamil='" + eamil + '\'' +
                ", age=" + age +
                '}';
    }
}

1.4.2.9创建StudentMapper.xml文件

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YQVLI4nR-1660321060450)(C:\Users\13417\AppData\Roaming\Typora\typora-user-images\image-20220812112956909.png)]

文件头部拷贝一下内容

<?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">

右键新建StudentDaoImpl.xml文件,从MyBatis-3-User-Guide-Simplified-Chinese.pdf中拷贝过来头参数.

该文件完成数据库中student表的所有增删改查的操作.

,在简单访问中namespace中的内容可以自定义,目的是为了区别不同中相同id的语句.

该文件中提供等数据库中的基本操作标签.

<?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:是整个文件的大标签,用来开始和结束xml文件
  属性:
     namespace:指定命名空间(相当于包名),用来区分不同mapper.xml文件中相同的id属性

-->
<mapper namespace="zar">
    <!--
      完成查询全部学生的功能
      List<Student> getALL();
         resultType:指定查询返回的结果集的类型,如果是集合,则必须是泛型的类型
         parameterType:如果有参数,则通过它来指定参数的类型
    -->
    <select id="getAll" resultType="student" >
       select id,name,email,age
       from student
    </select>

    <!--
      按主键id查询学生信息
      Student getById(Integer id);
    -->
    <select id="getById" parameterType="int" resultType="student">
        select id,name,email,age
        from student
        where id=#{id}
    </select>

    <!--
      按学生名称模糊查询
      List<Student> getByName(String name);
    -->
    <select id="getByName" parameterType="string" resultType="student">
        select id,name,email,age
        from student
        where name like '%${name}%'
    </select>

    <!--
      增加学生
      int insert(Student stu);
      实体类:
        private Integer id;
        private String name;
        private String email;
        private Integer age;
    -->
    <insert id="insert" parameterType="student">
        insert into student (name,email ,age) values(#{name},#{email},#{age})
    </insert>
    <!--
      按主键删除学生
      int delete(Integer id);
    -->
    <delete id="delete" parameterType="int" >
        delete from student where id=#{id}
    </delete>
    <!--
      更新学生
      int update(Student stu);
    -->
    <update id="update" parameterType="student">
        update student set name=#{name},email=#{email},age=#{age}
        where id=#{id}
    </update>
</mapper>
1.4.2.10单元测试
public class MyTest {
        SqlSession sqlSession;

        @Before  //在所有的@Test方法执行前先执行的代码
        public void openSqlSession() throws IOException {
                //使用文件流读取核心配置文件SqlMapConfig.xml
                InputStream in = Resources.getResourceAsStream("SqlMapConfig.xml");
                //创建SqlSessionFactory工厂
                SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
                //取出sqlSession的对象
                sqlSession = factory.openSession();
        }

        @After
        public void closeSqlSession(){
                //关闭sqlSession
                sqlSession.close();
        }

        @Test
        public void testGetAll() throws IOException {
                //完成查询操作
                List<Student> list = sqlSession.selectList("zar.getAll");
                list.forEach(student -> System.out.println(student));
        }

        @Test
        public void testGetById() throws IOException {
                //按主键查学生
                Student stu = sqlSession.selectOne("zar.getById",3);
                System.out.println(stu);
        }

        @Test
        public void testGetByName()throws IOException{

                //4.调用方法
                List<Student> list = sqlSession.selectList("zar.getByName","李");
                list.forEach(student -> System.out.println(student));

        }

        @Test
        public void testInsert()throws IOException{

                //4.调用方法
                int num = sqlSession.insert("zar.insert",new Student("haha666","haha@126.com",23));
                //切记切记切记:在所有的增删改后必须手工提交事务!!!
                sqlSession.commit();

        }

        @Test
        public void testDelete()throws IOException {

                //4.调用方法
                int num = sqlSession.delete("zar.delete",1);
                System.out.println(num);
                //切记切记切记:在所有的增删改后必须手工提交事务!!!
                sqlSession.commit();

        }

        @Test
        public void testUpdate()throws IOException {

                //4.调用方法
                int num = sqlSession.update("zar.update",new Student(3,"hehe","hehe@126.com",30));
                System.out.println(num);
                sqlSession.commit();

        }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cm7hXSfb-1660321060450)(C:\Users\13417\AppData\Roaming\Typora\typora-user-images\image-20220812140045351.png)]

1.5MyBatis对象分析

1.5.1Resources 类

Resources 类,顾名思义就是资源,用于读取资源文件。其有很多方法通过加载并解析资源文件,返回不同类型的 IO 流对象。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pW9Snr7G-1660321060451)(C:\Users\13417\AppData\Roaming\Typora\typora-user-images\image-20220812135239199.png)]

1.5.2SqlSessionFactoryBuilder类

SqlSessionFactory 的 创 建 , 需 要 使 用 SqlSessionFactoryBuilder 对 象 的 build() 方 法 。 由 于SqlSessionFactoryBuilder对象在创建完工厂对象后,就完成了其历史使命,即可被销毁。所以,一般会将该 对象创建为一个方法内的局部对象,方法结束,对象销毁。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2c4hYeOA-1660321060451)(C:\Users\13417\AppData\Roaming\Typora\typora-user-images\image-20220812135300279.png)]

1.5.3SqlSessionFactory 接口

SqlSessionFactory 接口对象是一个重量级对象(系统开销大的对象),是线程安全的,所以一个应用只需要一个该对象即可。创建 SqlSession 需要使用SqlSessionFactory 接口的的 openSession()方法。

A. openSession(true):创建一个有自动提交功能的 SqlSession

B. openSession(false):创建一个非自动提交功能的 SqlSession,需手动提交

C. openSession():同 openSession(false)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-i5AyXcx2-1660321060452)(C:\Users\13417\AppData\Roaming\Typora\typora-user-images\image-20220812135355863.png)]

1.6为实体类注册别名

1.6.1单个注册

  <typeAlias type="com.bjpowernode.pojo.Student" alias="student"></typeAlias>

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ydGL1ZYU-1660321060452)(C:\Users\13417\AppData\Roaming\Typora\typora-user-images\image-20220812141121983.png)]

这时在StudentMapper.xml文件里面,可以简便操作

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ODnHDZEh-1660321060453)(C:\Users\13417\AppData\Roaming\Typora\typora-user-images\image-20220812141306809.png)]

1.6.2批量注册

注册到pojo的包,然后在对应的xml文件里面直接写上驼峰命名法即可。

<package name="com.bjpowernode.pojo"></package>

别名是类名的驼峰命名法(规范)

1.7设置日志输出

 <!--设置日志输出底层执行的代码-->
    <settings>
        <setting name="logImpl" value="STDOUT_LOGGING"/>
    </settings>

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-17de48pT-1660321060453)(C:\Users\13417\AppData\Roaming\Typora\typora-user-images\image-20220812141652567.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XyZhPOde-1660321060454)(C:\Users\13417\AppData\Roaming\Typora\typora-user-images\image-20220812141728215.png)]

1.8动态代理

MyBatis框架使用**动态代理**的方式来进行数据库的访问.

Mapper接口的开发相当于是过去的Dao接口的开发。由MyBatis框架根据接口定义创建动态代理对象,代理对象的方法体同Dao接口实现类的方法。在设计时要遵守以下规范.

  1. Mapper接口与Mapper.xml文件在同一个目录下。

  2. Mapper接口的完全限定名与Mapper.xml文件中的namespace的值相同。

  3. Mapper接口方法名称与Mapper.xml中的标签的statement 的ID完全相同。

  4. Mapper接口方法的输入参数类型与Mapper.xml的每个sql的parameterType的类型相同。

  5. Mapper接口方法的输出参数与Mapper.xml的每个sql的resultType的类型相同。

  6. Mapper文件中的namespace的值是接口的完全限定名称。

  7. 在SqlMapConfig.xml文件中注册时,使用class属性=接口的完全限定名。

1.8.1使用动态代理开发项目

1.8.1.1数据表
USE ssm;
-- ----------------------------
-- Table structure for `users`
-- ----------------------------
DROP TABLE IF EXISTS `users`;
CREATE TABLE `users` (
  `id` INT(11) NOT NULL AUTO_INCREMENT,
  `username` VARCHAR(32) COMMENT '用户名称',
  `birthday` DATE DEFAULT NULL COMMENT '生日',
  `sex` CHAR(2) DEFAULT NULL COMMENT '性别',
  `address` VARCHAR(256) DEFAULT NULL COMMENT '地址',
  PRIMARY KEY (`id`)
) ENGINE=INNODB AUTO_INCREMENT=27 DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of user
-- ----------------------------
INSERT INTO `users` VALUES (1, '王五', '2000-09-10', '2', '安徽');
INSERT INTO `users` VALUES (2, '张三', '2001-07-12', '1', '北京市');
INSERT INTO `users` VALUES (3, '张小明', '1999-02-22', '1', '河南');
INSERT INTO `users` VALUES (4, '陈小亮', '2002-11-19', '1', '辽宁');
INSERT INTO `users` VALUES (5, '张三丰', '2001-03-10', '1', '上海市');
INSERT INTO `users` VALUES (6, '陈小明', '2002-01-19', '1', '重庆市');
INSERT INTO `users` VALUES (7, '王五四', '2001-05-13', '2', '天津市');
SELECT * FROM users;
1.8.1.2创建项目

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ixKtxu0J-1660321060455)(C:\Users\13417\AppData\Roaming\Typora\typora-user-images\image-20220812144229759.png)]

1.8.1.3拷贝文件

将jdbc.properties拷贝到项目下

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YuY0VrED-1660321060455)(C:\Users\13417\AppData\Roaming\Typora\typora-user-images\image-20220812144426085.png)]

1.8.1.4创建实体类
package com.bue.vue.pojo;

import java.util.Date;

/**
 * @ClassName Users
 * @Description TODO
 * @Author Jiang
 * @Date 2022/8/12 21:42
 * @Version 1.0
 **/
public class Users {
    private Integer id;
    private String username;
    private Date birthday;
    private String sex;
    private String address;

    @Override
    public String toString() {
        return "Users{" +
                "id=" + id +
                ", username='" + username + '\'' +
                ", birthday=" + birthday +
                ", sex='" + sex + '\'' +
                ", address='" + address + '\'' +
                '}';
    }

    public Integer getId() {
        return id;
    }

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

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public Date getBirthday() {
        return birthday;
    }

    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public Users(Integer id) {
        this.id = id;
    }

    public Users(Integer id, String username, Date birthday, String sex, String address) {
        this.id = id;
        this.username = username;
        this.birthday = birthday;
        this.sex = sex;
        this.address = address;
    }
}
1.8.1.5 配置sqlMapperConfig.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>
<!--    读取配置文件-->
    <properties resource="jdbc.properties"></properties>
<!--    注册别名-->
    <typeAliases>
        <package name="com.bue.vue.pojo"/>
    </typeAliases>
<!--    配置环境变量-->
   <environments default="development">
       <environment id="development">
           <transactionManager type="JDBC"></transactionManager>
           <dataSource type="POOLED">
               <property name="driver" value="${jdbc.driverClassName}"></property>
               <property name="url" value="${jdbc.url}"></property>
               <property name="username" value="${jdbc.username}"></property>
               <property name="password" value="${jdbc.password}"></property>
           </dataSource>
       </environment>
   </environments>
    
<!--    注册mapper文件-->
    <mappers>
        <package name="com.bue.vue.mapper"/>
    </mappers>
</configuration>

1.8.1.6配置UserMapper与UserMapper.xml文件

UserMapper与UserMapper.xml文件应在同一个mapper包下

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ChipUMf9-1660321060456)(C:\Users\13417\AppData\Roaming\Typora\typora-user-images\image-20220812221156632.png)]

UserMapper接口编写了一个方法,查询了所有用户的信息。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-83qbxW9w-1660321060457)(C:\Users\13417\AppData\Roaming\Typora\typora-user-images\image-20220812221250264.png)]

UserMapper.xml文件编写sql语句

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-64OE8jgq-1660321060457)(C:\Users\13417\AppData\Roaming\Typora\typora-user-images\image-20220812221348872.png)]

1.8.1.7测试功能
public class MyTest {
    //动态代理对象
    private SqlSession sqlSession;
    private SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd");
    private UserMapper userMapper;
    @Before
    public void opensqlSession() throws IOException {
        //1.读取核心配置文件
        InputStream in = Resources.getResourceAsStream("SqlMapConfig.xml");
        //2.创建工厂对象
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
        //3.取出sqlSession
        sqlSession = factory.openSession(true);//自动提交事务
        //4.取出动态代理的对象,完成接口中方法的调用,实则是调用xml文件中相的标签的功能
        userMapper = sqlSession.getMapper(UserMapper.class);
    }
    @After
    public void closeSqlSession(){
        sqlSession.close();
    }


    @Test
    public void getAllUsers(){
        List<Users> allUsers = userMapper.getAllUsers();
        allUsers.forEach(user-> System.out.println(user));
    }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-C2ifozA6-1660321060458)(C:\Users\13417\AppData\Roaming\Typora\typora-user-images\image-20220812221503091.png)]

同样可以编写增删改查操作(不一一列出)

<?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.bjpowernode.mapper.UsersMapper">

    <!--
      //查询全部用户信息
    List<Users> getAll();
    -->
    <select id="getAll" resultType="users" >
        select id,username,birthday,sex,address
        from users
    </select>

    <!--
      //根据用户主键查用户
    Users getById(Integer id);
    -->
    <select id="getById" parameterType="int" resultType="users">
        select id,username,birthday,sex,address
        from users
        where id=#{zar}
    </select>

    <!--
       //根据用户名模糊查询用户
    List<Users> getByName(String name);
    -->
    <select id="getByName" parameterType="string" resultType="users">
        select id,username,birthday,sex,address
        from users
        where username like '%${zar}%'
    </select>
    <!--
       //用户的更新
    int update(Users users);
    private Integer id;
    private String userName;
    private Date birthday;
    private String sex;
    private String address;
    -->
    <update id="update" parameterType="users" >
        update users set username = #{userName},birthday=#{birthday},sex=#{sex},address=#{address}
        where id=#{id}
    </update>


    <!--
      //增加用户
    int insert(Users users);
    -->
    <insert id="insert" parameterType="users" >
    <selectKey  keyProperty="id" resultType="int" order="AFTER">
        select last_insert_id()
    </selectKey>
        insert into users (username, birthday, sex, address) values(#{userName},#{birthday},#{sex},#{address})
    </insert>

    <!--
       //根据主键删除用户
    int delete(Integer id);
    -->
    <delete id="delete" parameterType="int" >
        delete from users
        where id=#{id}
    </delete>

    <!--
       //优化后的模糊查询
    List<Users> getByNameGood(String name);
    -->
    <select id="getByNameGood" parameterType="string" resultType="users">
        select id,username,birthday,sex,address
        from users
        where username like concat('%',#{name},'%')
    </select>

    <!--
    //模糊用户名和地址查询
    //如果参数超过一个,则parameterType不写
    List<Users> getByNameOrAddress(
            @Param("columnName")
            String columnName,
            @Param("columnValue")
            String columnValue);
    -->
    <select id="getByNameOrAddress" resultType="users">
        select id,username,birthday,sex,address
        from users
        where ${columnName} like concat('%',#{columnValue},'%')
    </select>
</mapper>
1.8.1.8总结

UsersMapper.java和UsersMapper.xml文件必须在同一个目录下,且必须同名。

在UsersMapper.xml文件中添加namespace属性为接口的完全路径名。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yiIIOzAq-1660321060458)(C:\Users\13417\AppData\Roaming\Typora\typora-user-images\image-20220812222144754.png)]

1.9 #{}和${}

#{}是对非字符串拼接的参数的占位符,如果入参是简单数据类型,#{}里可以任意写,但是如果入参是对象类型,则#{}里必须是对象的成员变量的名称,#{}可以有效防止sql注入。

主要是针对字符串拼接替换,如果入参是基本数据类型, {}主要是针对字符串拼接替换,如果入参是基本数据类型, 主要是针对字符串拼接替换,如果入参是基本数据类型,{}里必须是value,但是如果入参是对象类型,则 里必须是对象的成员变量的名称。 {}里必须是对象的成员变量的名称。 里必须是对象的成员变量的名称。{}还可以替换列名和表名,存在sql注入风险,尽量少用。

1.9.1#{}演示

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Lp5nRUjF-1660321060458)(C:\Users\13417\AppData\Roaming\Typora\typora-user-images\image-20220812222456471.png)]

1.9.2${}演示

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-50aLBLNC-1660321060459)(C:\Users\13417\AppData\Roaming\Typora\typora-user-images\image-20220812222604560.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-A1XgwHH5-1660321060459)(C:\Users\13417\AppData\Roaming\Typora\typora-user-images\image-20220812222637641.png)]

2.0动态sql

动态 SQL 是 MyBatis 的强大特性之一。如果你使用过 JDBC 或其它类似的框架,你应该能理解根据不同条件拼接 SQL 语句有多痛苦,例如拼接时要确保不能忘记添加必要的空格,还要注意去掉列表最后一个列名的逗号。利用动态 SQL,可以彻底摆脱这种痛苦。使用动态 SQL 并非一件易事,但借助可用于任何 SQL 映射语句中的强大的动态 SQL 语言,MyBatis 显著地提升了这一特性的易用性。

2.1 sql标签

当多种类型的查询语句的查询字段或者查询条件相同时,可以将其定义为常量,方便调用。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-98Z10KFi-1660321060460)(C:\Users\13417\AppData\Roaming\Typora\typora-user-images\image-20220812224044572.png)]

2.2 include标签

用于引用定义的常量。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FNWjGZFs-1660321060460)(C:\Users\13417\AppData\Roaming\Typora\typora-user-images\image-20220812224157967.png)]

2.3 if标签

进行条件判断。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9c8r8aZ0-1660321060460)(C:\Users\13417\AppData\Roaming\Typora\typora-user-images\image-20220812224226914.png)]

2.4 where标签

一般开发复杂业务的查询条件时,如果有多个查询条件,通常会使用标签来进行控制。 标签可以自动的将第一个条件前面的逻辑运算符 (or ,and) 去掉,正如代码中写的,id 查询条件前面是有“and”关键字的,但是在打印出来的 SQL 中却没有,这就是 的作用。

<select id="getByCondition" resultType="users" parameterType="users">
    select <include refid="allColumns"></include>
    from users
    <where>
        <if test="userName != null and userName != '' ">
            and username like concat('%',#{userName},'%')
        </if>
        <if test="birthday != null ">
            and birthday = #{birthday}
        </if>
        <if test="sex != null and sex !=''">
            and sex = #{sex}
        </if>
        <if test="address != null and address !=''">
            and address like concat('%',#{address},'%')
        </if>
    </where>
</select>

2.5 set标签

使用set标签可以将动态的配置 SET 关键字,并剔除追加到条件末尾的任何不相关的逗号。使用 if+set 标签修改后,在进行表单更新的操作中,哪个字段中有值才去更新,如果某项为 null 则不进行更新,而是保持数据库原值。切记:至少更新一列

<update id="updateBySet" parameterType="users">
    update users
    <set>
        <if test="userName != null and userName != ''">
            username = #{userName},
        </if>
        <if test="birthday != null">
            birthday = #{birthday},
        </if>
        <if test="sex != null and sex != ''">
            sex =#{sex},
        </if>
        <if test="address != null and address !=''">
            address = #{address}
        </if>
    </set>
    where id = #{id}
</update>

2.6 foreach标签

主要用来进行集合或数组的遍历,主要有以下参数:

collection:用来指定入参的类型,如果是List集合,则为list,如果是Map集合,则为map,如果是数组,则为array.
item:每次循环遍历出来的值或对象
separator:多个值或对象或语句之间的分隔符
open:整个循环外面的前括号
close:整个循环外面的后括号

2.7循环遍历参数集合

<select id="getByIds" resultType="users">
    select <include refid="columns"></include>
    from users
    where id in
        <foreach collection="list" item="id" separator="," open="(" close=")">
           #{id}
        </foreach>
</select>

2.8批量删除

<delete id="deleteBatch" >
    delete from users where id in
    <foreach collection="array" item="id" close=")" open="(" separator=",">
        #{id}
    </foreach>
</delete>

2.9案例

2.9.1UserMapper接口
package com.bjpowernode.mapper;

import com.bjpowernode.pojo.Users;
import org.apache.ibatis.annotations.Param;

import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 *  数据访问层的接口,规定的数据库中可进行的各种操作
 */
public interface UsersMapper {
    //查询全部用户信息
    List<Users> getAll();

    //根据用户主键查用户
    Users getById(Integer id);

    //根据用户名模糊查询用户
    List<Users> getByName(String name);

    //优化后的模糊查询
    List<Users> getByNameGood(String name);
    //用户的更新
    int update(Users users);
    //增加用户
    int insert(Users users);
    //根据主键删除用户
    int delete(Integer id);
    //模糊用户名和地址查询
    List<Users> getByNameOrAddress(
            @Param("columnName")
            String columnName,
            @Param("columnValue")
            String columnValue);

    //按指定的条件进行多条件查询
    List<Users> getByCondition(Users users);

    //有选择的更新
    int updateBySet(Users users);

    //查询多个指定id的用户信息
    List<Users> getByIds(Integer []arr);

    //批量删除
    int deleteBatch(Integer []arr);

    //批量增加
    int insertBatch(List<Users> list);

    //查询指定日期范围内的用户
    List<Users> getByBirthday(Date begin, Date end);

    //入参是map
    List<Users> getByMap(Map map);

    //返回值是map(一行)
    Map getReturnMap(Integer id);

    //返回多行的map
    List<Map> getMulMap();

}
2.9.2UserMapper.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 namespace="com.bjpowernode.mapper.UsersMapper">

    <!--定义代码片断-->
    <sql id="allColumns">
        id,username,birthday,sex,address
    </sql>

    <!--
      //查询全部用户信息
    List<Users> getAll();
    -->
    <select id="getAll" resultType="users" >
        select <include refid="allColumns"></include>
        from users
    </select>

    <!--
      //根据用户主键查用户
    Users getById(Integer id);
    -->
    <select id="getById" parameterType="int" resultType="users">
        select <include refid="allColumns"></include>
        from users
        where id=#{zar}
    </select>

    <!--
       //根据用户名模糊查询用户
    List<Users> getByName(String name);
    -->
    <select id="getByName" parameterType="string" resultType="users">
        select <include refid="allColumns"></include>
        from users
        where username like '%${zar}%'
    </select>
    <!--
       //用户的更新
    int update(Users users);
    private Integer id;
    private String userName;
    private Date birthday;
    private String sex;
    private String address;
    -->
    <update id="update" parameterType="users" >
        update users set username = #{userName},birthday=#{birthday},sex=#{sex},address=#{address}
        where id=#{id}
    </update>


    <!--
      //增加用户
    int insert(Users users);
    -->
    <insert id="insert" parameterType="users" >
    <selectKey  keyProperty="id" resultType="int" order="AFTER">
        select last_insert_id()
    </selectKey>
        insert into users (username, birthday, sex, address) values(#{userName},#{birthday},#{sex},#{address})
    </insert>

    <!--
       //根据主键删除用户
    int delete(Integer id);
    -->
    <delete id="delete" parameterType="int" >
        delete from users
        where id=#{id}
    </delete>

    <!--
       //优化后的模糊查询
    List<Users> getByNameGood(String name);
    -->
    <select id="getByNameGood" parameterType="string" resultType="users">
        select <include refid="allColumns"></include>
        from users
        where username like concat('%',#{name},'%')
    </select>

    <!--
    //模糊用户名和地址查询
    //如果参数超过一个,则parameterType不写
    List<Users> getByNameOrAddress(
            @Param("columnName")
            String columnName,
            @Param("columnValue")
            String columnValue);
    -->
    <select id="getByNameOrAddress" resultType="users">
        select <include refid="allColumns"></include>
        from users
        where ${columnName} like concat('%',#{columnValue},'%')
    </select>
    <!--
      //按指定的条件进行多条件查询
    List<Users> getByCondition(Users users);
    根据实体类中的成员变量是否有值来决定是否添加条件
    private Integer id;  null
    private String userName;  null
    private Date birthday;  null
    private String sex;  null
    private String address;  null
    private int num;  o
    private boolean flag; false
    private double d ;  0.0
    -->
    <select id="getByCondition" parameterType="users" resultType="users">
        select <include refid="allColumns"></include>
        from users
        <where>
            <if test="userName != null and userName != ''">
               and username like concat('%',#{userName},'%')
            </if>
            <if test="birthday != null">
               and birthday = #{birthday}
            </if>
            <if test="sex != null and sex != ''">
               and sex = #{sex}
            </if>
            <if test="address != null and address != ''">
                and address like concat('%',#{address},'%')
            </if>
        </where>
    </select>
    <!--
       //有选择的更新
    int updateBySet(Users users);
    -->
    <update id="updateBySet" parameterType="users">
        update users
        <set>
            <if test="userName != null and userName != ''">
               username = #{userName},
            </if>
            <if test="birthday != null">
                birthday = #{birthday},
            </if>
            <if test="sex != null and sex != ''">
                sex = #{sex},
            </if>
            <if test="address != null and address != ''">
                address =#{address} ,
            </if>
        </set>
        where id = #{id}
    </update>

    <!--
       //查询多个指定id的用户信息
    List<Users> getByIds(Integer []arr);
    -->
    <select id="getByIds" resultType="users">
        select <include refid="allColumns"></include>
        from users
        where id in
           <foreach collection="array" item="id" separator="," open="(" close=")">
               #{id}
           </foreach>
    </select>
    <!--
      //批量删除
    int deleteBatch(Integer []arr);
    -->
    <delete id="deleteBatch" >
        delete from users
        where id in
        <foreach collection="array" item="id" separator="," open="(" close=")">
            #{id}
        </foreach>
    </delete>
    <!--
      //批量增加
    int insertBatch(List<Users> list);
        private Integer id;  null
        private String userName;  null
        private Date birthday;  null
        private String sex;  null
        private String address;  null
    -->
    <insert id="insertBatch">
        insert into users(username, birthday, sex, address) values
        <foreach collection="list" item="u" separator="," >
            (#{u.userName},#{u.birthday},#{u.sex},#{u.address})
        </foreach>
    </insert>

    <!--
      //查询指定日期范围内的用户
    List<Users> getByBirthday(Date begin, Date end);
    -->
    <select id="getByBirthday" resultType="users">
        select <include refid="allColumns"></include>
        from users
        where birthday between #{arg0} and #{arg1}
    </select>

    <!--
       //入参是map
    List<Users> getByMap(Map map);
    #{birthdayBegin}:就是map中的key
    -->
    <select id="getByMap" resultType="users" >
        select <include refid="allColumns"></include>
        from users
        where birthday between #{birthdayBegin} and #{birthdayEnd}
    </select>

    <!--
       //返回值是map(一行)
    Map getReturnMap(Integer id);
    -->
    <select id="getReturnMap" parameterType="int" resultType="map">
        select username nam,address a
        from users
        where id=#{id}
    </select>
    <!--
      //返回多行的map
    List<Map> getMulMap();
    -->
    <select id="getMulMap" resultType="map">
        select username,address
        from users
    </select>
</mapper>

2.1指定参数位置

可以不使用对象的属性名进行参数值绑定,使用下标值。 mybatis-3.3 版本和之前的版本使用#{0},#{1}方式, 从 mybatis3.4 开始使用#{arg0}方式。

如果入参是多个,可以通过指定参数位置进行传参. 是实体包含不住的条件.实体类只能封装住成员变量的条件.如果某个成员变量要有区间范围内的判断,或者有两个值进行处理,则实体类包不住.

2.1.1查询指定日期范围内的用户信息.

 <!--
      //查询指定日期范围内的用户
    List<Users> getByBirthday(Date begin, Date end);
    -->
    <select id="getByBirthday" resultType="users">
        select <include refid="allColumns"></include>
        from users
        where birthday between #{arg0} and #{arg1}
    </select>   

2.1.2入参是map(重点掌握)

birthdayBegin就是map中的key

 List<Users> getByMap(Map map);
     
<select id="getByMap" resultType="users" >
        select <include refid="allColumns"></include>
        from users
        where birthday between #{birthdayBegin} and #{birthdayEnd}
    </select> 

2.2@Param指定参数名称

在这里插入图片描述

2.3列名与类中成员变量名称不一致

使用标签进行映射。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-opg31jwJ-1660321060461)(C:\Users\13417\AppData\Roaming\Typora\typora-user-images\image-20220812231425296.png)]

2.4表的关联关系

我们通常说的关联关系有以下四种,一对多关联,多对一关联,一对一关联,多对多关联。关联关系是有方向的。如果是高并发的场景中,不适合做表的关联。

在多对一和一对多的关联关系中,我们使用订单表和客户表。

2.4.1一对一

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sFnF87Xz-1660321060462)(C:\Users\13417\AppData\Roaming\Typora\typora-user-images\image-20220812231708332.png)]

2.4.2一对多关联

在一对多关联关系中,一方(客户)中有多方(订单)的集合,所以要使用标签来映射多方的属性。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LYrKnSoY-1660321060462)(C:\Users\13417\AppData\Roaming\Typora\typora-user-images\image-20220812231950897.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pAKlL6t3-1660321060463)(C:\Users\13417\AppData\Roaming\Typora\typora-user-images\image-20220812232000836.png)]在这里插入图片描述

总结:无论是什么关联关系,如果某方持有另一方的集合,则使用标签完成映射,如果某方持有另一方的对象,则使用标签完成映射。

2.5事务

Mybatis 框架是对 JDBC 的封装,所以 Mybatis 框架的事务控制方式有两种,一种是容器进行事务管理的,一种是程序员手工决定事务的提交与回滚。

SqlMapConfig.xml文件中设定的事务处理的方式。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cpLnlRtc-1660321060463)(C:\Users\13417\AppData\Roaming\Typora\typora-user-images\image-20220812232325264.png)]

Connection 对象的 setAutoCommit()方法来设置事务提交方式的。自动提交和手工提交。该标签用于指定MyBatis 所使用的事务管理器。

MyBatis 支持两种事务管理器类型:JDBC 与 MANAGED

JDBC:使用 JDBC 的事务管理机制。即,通过 Connection 的 commit()方法提交,通过 rollback()方法回滚。但默认情况下,MyBatis 将自动提交功能关闭了,改为了手动提交。即程序中需要显式的对事务进行提交或回滚。从日志的输出信息中可以看到。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gnh6gvXO-1660321060464)(C:\Users\13417\AppData\Roaming\Typora\typora-user-images\image-20220812232341088.png)]

在获得SqlSession的时候,如果openSession()是无参或者是false,则必须手工提交事务,如果openSession(true),则为自动提交事务,在执行完增删改后无须commit(),事务自动提交。

session = factory.openSession(true);

2.6缓存

将用户经常查询的数据放在缓存(内存)中,用户去查询数据就不用从磁盘上(关系型数据库数据文件)查询,从缓存中查询,从而提高查询效率,解决了高并发系统的性能问题。mybatis提供查询缓存,用于减轻数据库压力,提高数据库性能。

在进行数据库访问时,首先去访问缓存,如果缓存中有要访问的数据,则直接返回客户端,如果没有则去访问数据库,在库中得到数据后,先在缓存放一份,再返回客户端。如下图。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-b1GhWuyL-1660321060464)(C:\Users\13417\AppData\Roaming\Typora\typora-user-images\image-20220812232655149.png)]

mybaits提供一级缓存和二级缓存。默认开启一级缓存。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LEaxt5ab-1660321060464)(C:\Users\13417\AppData\Roaming\Typora\typora-user-images\image-20220812232715950.png)]

2.7Mybaties总结图

在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是MyBatis框架学习笔记MyBatis是一种基于Java的持久层框架,它通过XML描述符或注解将对象映射到数据库中。它提供了自定义SQL、存储过程和高级映射等功能,使得开发人员可以更加灵活地控制SQL语句的执行过程。 MyBatis的核心组件包括SqlSessionFactory、SqlSession和Mapper。其中,SqlSessionFactory是MyBatis的核心接口,它负责创建SqlSession对象。SqlSession是MyBatis的核心类,它提供了执行SQL语句、获取Mapper接口等功能。Mapper是MyBatis的映射器接口,它定义了SQL语句和Java方法之间的映射关系。 MyBatis的优点包括: 1. 灵活性高:MyBatis提供了自定义SQL、存储过程和高级映射等功能,使得开发人员可以更加灵活地控制SQL语句的执行过程。 2. 易于使用:MyBatis的API简单易用,开发人员可以快速上手。 3. 易于维护:MyBatis的SQL语句和Java方法之间的映射关系清晰明了,易于维护。 4. 性能高:MyBatis采用了预编译和缓存等技术,可以提高SQL语句的执行效率。 以下是一个使用MyBatis框架的Java代码示例: ```java // 创建SqlSessionFactory对象 String resource = "mybatis-config.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); // 创建SqlSession对象 SqlSession sqlSession = sqlSessionFactory.openSession(); try { // 获取Mapper接口 UserMapper userMapper = sqlSession.getMapper(UserMapper.class); // 执行SQL语句 User user = userMapper.selectUserById(1); // 输出结果 System.out.println(user); } finally { // 关闭SqlSession对象 sqlSession.close(); } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值