【JavaEE进阶】——Mybatis操作数据库(使用注解和XML方式)

目录

🚩三层架构

🎈JDBC操作回顾

🚩什么是MyBatis

🚩MyBatis⼊⻔

🎈准备工作

📝创建⼯程

📝数据准备

🎈配置数据库连接字符串

🎈写持久层代码

🎈单元测试

🚩MyBatis的基础操作

🎈打印日志

🎈参数传递

🎈增(Insert)

📝返回主键(实现自增效果)

🎈删(delete)

🎈改(Update)

🎈查(Select)

📝起别名

📝结果映射

📝开启驼峰命名(推荐)

[🚩MyBatis XML配置文件](#🚩MyBatis XML配置文件)

🎈配置连接字符串和MyBatis

🎈写持久层代码

[📝添加 mapper 接⼝](#📝添加 mapper 接⼝)

[📝添加 UserInfoXMLMapper2.xml](#📝添加 UserInfoXMLMapper2.xml)

[📝查询所有⽤⼾的具体实现 :](#📝查询所有⽤⼾的具体实现 :)

📝单元测试

🎈增删改查操作

📝增(Insert)

📝删(Delete)

📝改(Update)

📝查(Select)


本节⽬标

  • 1. 使⽤MyBatis完成简单的增删改查操作, 参数传递.
  • 2. 掌握MyBatis的两种写法: 注解 和 XML⽅式
  • 3. 掌握MyBatis 相关的⽇志配置

🚩三层架构

在应⽤分层学习时, 我们 了解到web应⽤程序⼀般分为三层,即:Controller、Service、Dao .

  • 表现层:Controller 参数接收,参数校验,参数格式转换,结果格式转换,结果返回等等
  • 业务逻辑层:Service 介于表现层和数据层之间,业务逻辑相关的处理
  • 数据层:Dao 与数据相关的,数据的增删改查

之前的案例中,请求流程如下:
浏览器发起请求, 先请求Controller, Controller接收到请求之后, 调⽤ Service进⾏业务逻辑处理, Service再调⽤Dao, 但是Dao层的数据是Mock的, 真实的数据应该从数据库中读取.
我们学习MySQL数据库时,已经学习了JDBC来操作数据库, 但是JDBC操作太复杂了.

🎈JDBC操作回顾

我们先来回顾⼀下 JDBC 的操作流程:

    1. 创建数据库连接池 DataSource
    1. 通过 DataSource 获取数据库连接 Connection
    1. 编写要执⾏带 ? 占位符的 SQL 语句
    1. 通过 Connection 及 SQL 创建操作命令对象 Statement
    1. 替换占位符:指定要替换的数据库字段类型,占位符索引及要替换的值
    1. 使⽤ Statement 执⾏ SQL 语句
    1. 查询操作:返回结果集 ResultSet,更新操作:返回更新的数量
    1. 处理结果集
    1. 释放资源

展⽰了通过 JDBC 的 API 向数据库中添加⼀条记录,修改⼀条记录,查询⼀条记录的操作。
从上述的操作流程中可以看出,对于JDBC来说,整个操作非常的繁琐,不但要拼接每一个参数,而且还要按照模板代码的方式,一步步的操作数据库,并且在每次操作完,还要手动关闭连接等,而所有的这些操作步骤都需要在每个方法中重复书写,那有没有一种方法,可以更简单,更方便的操作数据库呢?
答案是肯定的,这就是我们要学习 MyBatis 的真正原因,它可以帮助我们更⽅便、更快速的操作数据库.


🚩什么是MyBatis

MyBatis是一款优秀的 持久层 框架,用于简化JDBC的开发

在上⾯我们提到⼀个词:持久层
• 持久层:指的就是持久化操作的层, 通常指数据访问层(dao), 是⽤来操作数据库的

简单来说 MyBatis是更简单完成程序和数据库交互的框架,也就是更简单的操作和读取数据库工具,接下来,我们就通过一个入门程序,让大家感受一下通过MyBatis如何来操作数据库


🚩MyBatis⼊⻔

Mybatis操作数据库的步骤:

    1. 准备⼯作(创建springboot⼯程、数据库表准备、实体类)
    1. 引⼊Mybatis的相关依赖,配置Mybatis(数据库连接信息)
    1. 编写SQL语句(注解/XML)
    1. 测试

🎈准备工作

📝创建⼯程

创建springboot⼯程,并导⼊ mybatis的起步依赖、mysql的驱动包

Mybatis 是⼀个持久层框架, 具体的数据存储和数据操作还是在MySQL中操作的, 所以需要添加MySQL驱动。


项⽬⼯程创建完成后,⾃动在pom.xml⽂件中,导⼊Mybatis依赖和MySQL驱动依赖 。

<!--Mybatis 依赖包-->
 <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>3.0.3</version>
 </dependency>

<!--mysql驱动包-->
<dependency>
      <groupId>com.mysql</groupId>
      <artifactId>mysql-connector-j</artifactId>
      <scope>runtime</scope>
</dependency>

📝数据准备

创建⽤⼾表, 并创建对应的实体类User

-- 创建数据库
DROP DATABASE IF EXISTS mybatis_test;
CREATE DATABASE mybatis_test DEFAULT CHARACTER SET utf8mb4;
-- 使⽤数据数据
USE mybatis_test;
-- 创建表[⽤⼾表]
DROP TABLE IF EXISTS userinfo;
CREATE TABLE `userinfo` (
 `id` INT ( 11 ) NOT NULL AUTO_INCREMENT,
 `username` VARCHAR ( 127 ) NOT NULL,
 `password` VARCHAR ( 127 ) NOT NULL,
 `age` TINYINT ( 4 ) NOT NULL,
 `gender` TINYINT ( 4 ) DEFAULT '0' COMMENT '1-男 2-⼥ 0-默认',
 `phone` VARCHAR ( 15 ) DEFAULT NULL,
 `delete_flag` TINYINT ( 4 ) DEFAULT 0 COMMENT '0-正常, 1-删除',
 `create_time` DATETIME DEFAULT now(),
 `update_time` DATETIME DEFAULT now(),
 PRIMARY KEY ( `id` ) 
) ENGINE = INNODB DEFAULT CHARSET = utf8mb4; 
-- 添加⽤⼾信息
INSERT INTO mybatis_test.userinfo ( username, `password`, age, gender, phone )
VALUES ( 'admin', 'admin', 18, 1, '18612340001' );
INSERT INTO mybatis_test.userinfo ( username, `password`, age, gender, phone )
VALUES ( 'zhangsan', 'zhangsan', 18, 1, '18612340002' );
INSERT INTO mybatis_test.userinfo ( username, `password`, age, gender, phone )
VALUES ( 'lisi', 'lisi', 18, 1, '18612340003' );
INSERT INTO mybatis_test.userinfo ( username, `password`, age, gender, phone )
VALUES ( 'wangwu', 'wangwu', 18, 1, '18612340004' );

创建对应的实体类 UserInfo
实体类的属性名与表中的字段名⼀⼀对应

package com.example.mybatis_test.model;

import lombok.Data;

import java.util.Date;

@Data
public class UserInfo {
    private Integer id;
    private String username;
    private String password;
    private Integer age;
    private Integer gender;
    private String phone;
    private Integer deleteFlag;
    private Date createTime;
    private Date updateTime;
}

🎈配置数据库连接字符串

# 数据库连接配置
spring:
  datasource:
    url: jdbc:mysql://127.0.0.1:3306/mybatis_test?characterEncoding=utf8&useSSL=false
    username: root
    password: root
    driver-class-name: com.mysql.cj.jdbc.Driver

注意事项:
如果使⽤ MySQL 是 5.x 之前的使⽤的是"com.mysql.jdbc.Driver",如果是⼤于 5.x 使⽤的
是"com.mysql.cj.jdbc.Driver".


🎈写持久层代码

在项⽬中, 创建持久层接⼝UserInfoMapper2.

package com.example.mybatis_test.mapper;

import com.example.mybatis_test.model.UserInfo;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;

import java.util.List;

@Mapper
public interface UserInfoMapper2 {
    //查询所有用户的信息
    @Select("select * from userinfo")
    List<UserInfo>getUserInfoAll();
}

Mybatis的持久层接⼝规范⼀般都叫 XxxMapper

  • @Mapper注解:表⽰是MyBatis中的Mapper接⼝ ,程序运行时,框架会自动生成接口的实现类对象(代理对象),并交给Spring的IOC容器管理.(也就是在程序运行的时候,框架会自动生成UserInfoMapper2接口,然后交给了spring的ioc容器中让spring进行管理,等需要了就注入)
  • @Select注解:代表的就是select查询,也就是注解对应方法的具体实现内容(而select就是执行sql语句,注解里面的内容就是具体实现内容)

🎈单元测试

在创建出来的SpringBoot⼯程中,在src下的test⽬录下,已经⾃动帮我们创建好了测试类 ,我们可以直接使⽤这个测试类来进⾏测试.

package com.example.mybatis_test.mapper;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
class UserInfoMapper2Test {
    @Test
    void getUserInfoAll() {

    }
}

此时的测试单元类就自动生成了,再src/test/java/Mapper里面自动生成了测试类。

package com.example.mybatis_test.mapper;

import com.example.mybatis_test.model.UserInfo;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.List;

import static org.junit.jupiter.api.Assertions.*;

@SpringBootTest
class UserInfoMapper2Test {
    @Autowired
    private UserInfoMapper2 userInfoMapper2;
    @Test
    void getUserInfoAll() {
        List<UserInfo>userInfos=userInfoMapper2.getUserInfoAll();
        for (UserInfo userInfo:userInfos) {
            System.out.println(userInfo);
        }
    }
}

记得加 @SpringBootTest 注解, 加载Spring运⾏环境,否则会报错
测试类上添加了注解 @SpringBootTest,该测试类在运⾏时,就会⾃动加载Spring的运⾏环境.
我们通过@Autowired这个注解, 注⼊我们要测试的类, 就可以开始进⾏测试了 。

返回结果中, 可以看到, 只有SQL语句中查询的列对应的属性才有赋值。sql语句和查询的列属性不对应那么就默认为空值。


🚩MyBatis的基础操作

上⾯我们学习了Mybatis的查询操作, 接下来我们学习MyBatis的增, 删, 改操作 ,在学习这些操作之前, 我们先来学习MyBatis⽇志打印。

🎈打印日志

在Mybatis当中我们可以借助⽇志, 查看到sql语句的执⾏、执⾏传递的参数以及执⾏结果 ,在配置⽂件中进⾏配置即可。

#配置mybatis日志,为了后续观察sql语句的执行
mybatis:
  configuration:
      log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
  • ①: 查询语句 preparing:select*from userinfo
  • ②: 传递参数及类型 Parameters
  • ③: SQL执⾏结果 cloums以下
    我们看到,配置日志文件后,我们就可以观察到,sql语句的执行,以及执行结果,每一行都标注的清清楚楚,并且标注影响的行数。

🎈参数传递

#{}动态参数传递
需求: 查找id=4的⽤⼾,对应的SQL就是: select * from userinfo where id=4

//查询id=4的用户
    @Select("select * from userinfo where id=#{id}")
    UserInfo queryById(Integer id);

如果给where id=4表示只能查找id=4 的数据, 所以SQL语句中的id值不能写成固定数值,需要变为动态的数值 解决⽅案:在queryById⽅法中添加⼀个参数(id), 将⽅法中的参数,传给SQL语句
使⽤ #{} 的⽅式获取⽅法中的参数,使静态数据转成动态数据
如果mapper接⼝⽅法形参只有⼀个普通类型的参数,#{...} ⾥⾯的属性名可以随便写,如:#{id}、# {value}。 建议和参数名保持⼀致
🍭添加测试样例:

  @Test
    void queryById() {
        UserInfo userInfo=userInfoMapper2.queryById(4);
        System.out.println(userInfo);
    }

🍭控制台结果

也可以通过 @Param , 设置参数的别名 , 如果使⽤ @Param 设置别名, #{...}⾥⾯的属性名必须和 @Param 设置的⼀样


🎈增(Insert)

   //增加一个用户
    @Insert("insert into userinfo (username,`password`,age,gender) values" +
            "(#{username},#{password},#{age},#{gender})")
    Integer insert(UserInfo userInfo);

如果语句过长,我们可以直接敲回车,idea会自动给你换行。

🍭添加测试样例

    @Test
    void insert() {
        UserInfo userInfo=new UserInfo();
        userInfo.setUsername("zyf");
        userInfo.setPassword("1005");
        userInfo.setAge(20);
        userInfo.setGender(1);
        Integer count=userInfoMapper2.insert(userInfo);
        System.out.println(count);
    }

🍭控制台结果

如果设置了 @Param 属性, #{...} 需要使⽤ 参数.属性 来获取

  //增加一个用户
    @Insert("insert into userinfo (username,`password`,age,gender) values" +
            "(#{userinfo.username},#{userinfo.password},#{userinfo.age},#{userinfo.gender})")
    Integer insert(@Param("userinfo") UserInfo userInfo);

📝返回主键(实现自增效果)

自增id @Options(useGeneratedKeys = true, keyProperty = "id")

  • useGeneratedKeys:这会令 MyBatis 使⽤ JDBC 的 getGeneratedKeys ⽅法来取出由数据库内 部⽣成的主键(⽐如:像 MySQL 和 SQL Server 这样的关系型数据库管理系统的⾃动递增字 段),默认值:false.
  • • keyProperty:指定能够唯⼀识别对象的属性,MyBatis 会使⽤ getGeneratedKeys 的返回值或insert 语句的 selectKey ⼦元素设置它的值,默认值:未设置(unset)
    Insert 语句默认返回的是 受影响的⾏数
    但有些情况下, 数据插⼊之后, 还需要有后续的关联操作, 需要获取到新插⼊数据的id
    ⽐如订单系统
    当我们下完订单之后, 需要通知物流系统, 库存系统, 结算系统等, 这时候就需要拿到订单ID
    如果想要拿到⾃增id, 需要在Mapper接⼝的⽅法上添加⼀个Options的注解

注意: 设置 useGeneratedKeys=true 之后, ⽅法返回值依然是受影响的⾏数, ⾃增id 会设置在上 述 keyProperty 指定的属性中.


🎈删(delete)

📝使用注解:

  @Delete("delete from userinfo where id=#{id}")
    Integer delete(Integer id);

📝添加测试样例

此时的表中就删除了id=4的用户。


🎈改(Update)

📝使用注解

    //更新一个用户的姓名
    @Update("update userinfo set username=#{username} where id=#{id}")
    Integer update(String username,Integer id);

📝添加测试样例

   @Test
    void update() {
        Integer count=userInfoMapper2.update("zyf",5);
        System.out.println(count);
    }



🎈查(Select)

我们在上⾯查询时发现, 有⼏个字段是没有赋值的, 只有Java对象属性和数据库字段⼀模⼀样时, 才会进⾏赋值 ,接下来我们多查询⼀些数据
📝使用注解

    @Select("select id, username, `password`, age, gender, phone, delete_flag, create_time, update_time from userinfo")
    List<UserInfo> queryAllUser();

📝添加测试样例

 @Test
    void queryAllUser() {
        List<UserInfo>infoList=userInfoMapper2.queryAllUser();
        for (UserInfo userInfo:infoList) {
            System.out.println(userInfo);
        }
    }


从运⾏结果上可以看到, 我们SQL语句中, 查询了delete_flag, create_time, update_time, 但是这⼏个属性却没有赋值.


原因分析:
当⾃动映射查询结果时, MyBatis 会获取结果中返回的列名并在 Java 类中查找相同名字的属性(忽略⼤⼩写) 。 这意味着如果发现了 ID 列和 id 属性,MyBatis 会将列 ID 的值赋给 id 属性

但是有三个属性和表的列名不一致,就不会进行赋值。


解决办法:

    1. 起别名
    1. 结果映射
    1. 开启驼峰命名

MyBatis 会根据⽅法的返回结果进⾏赋值.

  • ⽅法⽤对象 UserInfo接收返回结果, MySQL 查询出来数据为⼀条, 就会⾃动赋值给对象.
  • ⽅法⽤List<UserInfo>接收返回结果, MySQL 查询出来数据为⼀条或多条时, 也会⾃动赋值给List.
  • 但如果MySQL 查询返回多条, 但是⽅法使⽤UserInfo接收, MyBatis执⾏就会报错

📝起别名

在SQL语句中, 给列名起别名,保持别名和实体类属性名⼀样。
delete_flag as deleteFlag, create_time as createTime, update_time as updateTime
🍭使用注解

    @Select("select id, username, `password`, age, gender, phone, delete_flag as deleteFlag, create_time as createTime, update_time as updateTime from userinfo")
    List<UserInfo> queryAllUser2();

SQL语句太⻓时, 使⽤加号 + 进⾏字符串拼接(直接按回车idea自动给你换行)

🍭添加测试

  @Test
    void queryAllUser2() {
        List<UserInfo>infoList=userInfoMapper2.queryAllUser2();
        for (UserInfo userInfo:infoList) {
            System.out.println(userInfo);
        }
    }

📝结果映射

 @Select("select id, username, `password`, age, gender, phone, delete_flag, create_time, update_time from userinfo")
    @Results({
            @Result(column = "delete_flag",property = "deleteFlag"),
            @Result(column = "create_time",property = "createTime"),
            @Result(column = "update_time",property = "updateTime")
    })
    List<UserInfo> queryAllUser();

如果其他SQL, 也希望可以复⽤这个映射关系, 可以给这个Results定义⼀个名,这样我们再queryById方法中我们要想得到id=4的用户,他查询之后的结果也是那三个属性不对应,我们就可以复用下面的@Results注解,用@RestultMap注解定位到@Results注解中id。
使⽤ id 属性给该 Results 定义别名, 使⽤ @ResultMap 注解来复⽤其他定义的 ResultMap

🍭测试结果


📝开启驼峰命名(推荐)

通常数据库列使⽤蛇形命名法进⾏命名(下划线分割各个单词), Java 属性⼀般遵循驼峰命名法约定.
驼峰命名规则: abc_xyz => abcXyz

  • • 表中字段名:abc_xyz

  • • 类中属性名:abcXyz
    为了在这两种命名⽅式之间启⽤⾃动映射,需要将 mapUnderscoreToCamelCase 设置为 true。

    mybatis:
    configuration:
    map-underscore-to-camel-case: true #配置驼峰⾃动转换

🍭配置驼峰自动转换

   //查询所有用户的信息
    @Select("select * from userinfo")
    List<UserInfo>getUserInfoAll();

🍭添加测试样例

    @Test
    void getUserInfoAll() {
        List<UserInfo>userInfos=userInfoMapper2.getUserInfoAll();
        for (UserInfo userInfo:userInfos) {
            System.out.println(userInfo);
        }
    }

相比于起别名和结果映射,开启驼峰命名更加的简单,只需要再配置文件中配置一下,即可。


🚩MyBatis XML配置文件

上⾯学习了注解的⽅式, 接下来我们学习XML的⽅式
使⽤Mybatis的注解⽅式,主要是来完成⼀些简单的增删改查功能. 如果需要实现复杂的SQL功能,建议使⽤XML来配置映射语句,也就是将SQL语句写在XML配置⽂件中.
MyBatis XML的⽅式需要以下两步:

    1. 配置数据库连接字符串和MyBatis
    1. 写持久层代码

🎈配置连接字符串和MyBatis

此步骤需要进⾏两项设置,数据库连接字符串设置和 MyBatis 的 XML ⽂件配置。 如果是application.yml⽂件, 配置内容如下:

# 配置 mybatis xml 的⽂件路径,在 resources/mapper 创建所有表的 xml ⽂件
mybatis:
 mapper-locations: classpath:mapper/**Mapper.xml

spring:
  datasource:
    url: jdbc:mysql://127.0.0.1:3306/mybatis_test?characterEncoding=utf8&useSSL=false
    username: root
    password: 105528clzyf.
    driver-class-name: com.mysql.cj.jdbc.Driver
#配置mybatis日志,为了后续观察sql语句的执行
mybatis:
  configuration:
      log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
##配置驼峰⾃动转换
      map-underscore-to-camel-case: true    
# 配置 mybatis xml 的⽂件路径,在 resources/mapper 创建所有表的 xml ⽂件
  mapper-locations: classpath:mapper/UserInfoMapper2.xml

配置mybatis.xml文件,我们需要在src/main/resources/mapper目录下创建xml文件。


🎈写持久层代码

持久层代码分两部分

  • 1. ⽅法定义 Interface
  • 2. ⽅法实现: UserInfoMapper2.xml

    Interface用于方法定义,xxx.xml用于方法的实现,实现sql语句。

📝添加 mapper 接⼝

数据持久层的接⼝定义:

package com.example.mybatis_test.mapper;

import com.example.mybatis_test.model.UserInfo;
import org.apache.ibatis.annotations.Mapper;

import java.util.List;

@Mapper
public interface UserInfoXmlMapper2 {
    List<UserInfo>queryAllUser();
}

📝添加 UserInfoXMLMapper2.xml

数据持久成的实现,MyBatis 的固定 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.example.mybatis_test.mapper.UserInfoXmlMapper2">
    
</mapper>


创建UserInfoXMLMapper2.xml, 路径参考yml中的配置

# 配置 mybatis xml 的⽂件路径,在 resources/mapper 创建所有表的 xml ⽂件
  mapper-locations: classpath:mapper/UserInfoMapper2.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.example.mybatis_test.mapper.UserInfoXmlMapper2">
    <select id="queryAllUser">
        select username,`password`,age,gender,phone, from userinfo
    </select>
</mapper>

以下是对以上标签的说明:

  • • <mapper> 标签:需要指定 namespace 属性,表⽰命名空间,值为 mapper 接⼝的全限定名,包括全包名.类名。
  • • <select> 查询标签:是⽤来执⾏数据库的查询操作的:

◦ id :是和 Interface (接⼝)中定义的⽅法名称⼀样的 ,表⽰对接⼝的具体实现⽅法。
◦ resultType :是返回的数据类型,也就是开头我们定义的实体类.


📝单元测试

@SpringBootTest
class UserInfoMapper2Test {
    @Autowired
    private UserInfoMapper2 userInfoMapper2;
    @Test
    void getUserInfoAll() {
        List<UserInfo>userInfos=userInfoMapper2.getUserInfoAll();
        for (UserInfo userInfo:userInfos) {
            System.out.println(userInfo);
        }
    }
}


🎈增删改查操作

📝增(Insert)

🍭UserInfoMapper2接⼝:

 ///增
    Integer insertUser(UserInfo userInfo);

🍭UserInfoMapper.xml实现

 <insert id="insertUser">
        insert into userinfo (username,`password`,age,gender,phone)values (#{username},#{password},#{age},#{gender},#{phone})
    </insert>

如果使⽤@Param设置参数名称的话, 使⽤⽅法和注解类似
🍭UserInfoMapper接⼝:

   ///增
    Integer insertUser(@Param("userinfo") UserInfo userInfo);

🍭UserInfoMapper.xml实现:

    <insert id="insertUser">
        insert into userinfo (username,`password`,age,gender,phone)values (#{userinfo.username},#{userinfo.password},#{userinfo.age},#{userinfo.gender},#{userinfo.phone})
    </insert>

返回⾃增 id
接⼝定义不变, Mapper.xml 实现 设置useGeneratedKeys 和keyProperty属性

<insert id="insertUser" useGeneratedKeys="true" keyProperty="id">
        insert into userinfo (username,`password`,age,gender,phone)values (#{userinfo.username},#{userinfo.password},#{userinfo.age},#{userinfo.gender},#{userinfo.phone})
    </insert>



📝删(Delete)

🍭UserInfoMapper接⼝

  //删
    Integer deleteUser(Integer id);

🍭UserInfoMapper.xml实现:

<delete id="deleteUser">
        delete from userinfo where id=#{id};
    </delete>

🍭测试

  @Test
    void deleteUser() {
        Integer count=userInfoXmlMapper2.deleteUser(2);
        System.out.println(count);
    }



📝改(Update)

🍭UserInfoMapper接⼝

//改
    Integer updateUser(String username,Integer id);

🍭UserInfoMapper.xml实现:

   <update id="updateUser">
        update userinfo set username=#{username} where id=#{id}
    </update>

🍭测试

  @Test
    void updateUser() {
       Integer count=userInfoXmlMapper2.updateUser("zzzzz",7);
        System.out.println(count);
    }



📝查(Select)

同样的, 使⽤XML 的⽅式进⾏查询, 也存在数据封装的问题 ,我们把SQL语句进⾏简单修改, 查询更多的字段内容
🍭UserInfoMapper接⼝

  //查
    List<UserInfo>selectUser();

🍭UserInfoMapper.xml实现:

  <select id="selectUser">
        select id, username,`password`, age, gender, phone, delete_flag,
               create_time, update_time from userinfo
    </select>

🍭测试

 @Test
    void selectUser() {
        List<UserInfo>infoList=userInfoXmlMapper2.selectUser();
        for (UserInfo userInfo:infoList) {
            System.out.println(userInfo);
        }
    }

结果显⽰: deleteFlag, createTime, updateTime 也没有进⾏赋值.

解决办法和注解类似

    1. 起别名
    1. 结果映射
    1. 开启驼峰命名

其中1,3的解决办法和注解⼀样,不再多说, 接下来看下xml如果来写结果映射

🍭结果映射

    <resultMap id="BaseMap" type="com.example.mybatis_test.model.UserInfo">
        <id column="id" property="id"></id>
        <result column="delete_flag" property="deleteFlag"></result>
        <result column="create_time" property="createTime"></result>
        <result column="update_time" property="updateTime"></result>
    </resultMap>
    <select id="selectUser" resultMap="BaseMap">
        select id, username,`password`, age, gender, phone, delete_flag,
               create_time, update_time from userinfo
    </select>

注解方式和XML方式结果映射区别



六一快乐~今天吃了自助餐,几年没有穿裙子今天买了个裙子,给张老师买了白色上袖为it文化节准备上台。

相关推荐
容器( ु⁎ᴗ_ᴗ⁎)ु.。oO6 分钟前
MySQL事务
数据库·mysql
cyt涛2 小时前
MyBatis 学习总结
数据库·sql·学习·mysql·mybatis·jdbc·lombok
Rookie也要加油2 小时前
01_SQLite
数据库·sqlite
liuxin334455662 小时前
教育技术革新:SpringBoot在线教育系统开发
数据库·spring boot·后端
看山还是山,看水还是。3 小时前
MySQL 管理
数据库·笔记·mysql·adb
fishmemory7sec3 小时前
Koa2项目实战2(路由管理、项目结构优化)
数据库·mongodb·koa
momo小菜pa3 小时前
【MySQL 09】表的内外连接
数据库·mysql
Jasonakeke4 小时前
【重学 MySQL】四十九、阿里 MySQL 命名规范及 MySQL8 DDL 的原子化
数据库·mysql
程序猿小D4 小时前
第二百六十九节 JPA教程 - JPA查询OrderBy两个属性示例
java·开发语言·数据库·windows·jpa
小宇成长录4 小时前
Mysql:数据库和表增删查改基本语句
数据库·mysql·数据库备份