MyBatis 框架学习(II)

news2024/9/29 21:29:11

MyBatis 框架学习(II)

文章目录

  • MyBatis 框架学习(II)
    • 1. 介绍
    • 2. 准备&测试
      • 2.1 配置数据库连接字符串和MyBatis
      • 2.2 编写持久层代码
    • 3. MyBatis XML基础操作
      • 3.1 Insert 操作
      • 3.2 Delete 操作
      • 3.3 Update 操作
      • 3.4 Select 操作
    • 4. #{} 与 ${}的使用
    • 5. 动态SQL操作
      • 5.1 < if >标签
      • 5.2 < trim >标签
      • 5.3 < where >标签
      • 5.4 < set >标签
      • 5.5 < foreach >标签
      • 5.6 < include >标签
    • 总结

在上一篇文章中,我们学习了通过 注解的方式( MyBatis 框架学习(I) )来进行 MyBatis开发,接下来我们来学习使用 XML的方式进行 MyBatis开发:

1. 介绍

使用MyBatis注解的方式主要是用来解决简单的SQL操作,如增删改查功能,如果需要实现复杂的SQL功能,建议使用XML来配置映射语句,也就是将SQL语句写在XML配置文件

2. 准备&测试

想要进行XML的使用,我们需要先完成以下配置:

  • 配置数据库连接字符串和MyBatis;
  • 编写持久层代码

2.1 配置数据库连接字符串和MyBatis

如果配置文件是application.properties,代码如下:

#驱动类名称
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
#数据库连接的url
spring.datasource.url=jdbc:mysql://localhost:3306/mybatis_test
#连接数据库的用户名
spring.datasource.username=root
#连接数据库的密码
spring.datasource.password=123456

#配置mybatis的日志, 指定输出到控制台
mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl

#开启mybatis的驼峰命名自动映射开关 a_column ------> aCloumn
mybatis.configuration.map-underscore-to-camel-case=true

# 配置 mybatis xml 的⽂件路径,在 resources/mapper 创建所有表的 xml ⽂件 --> 使用XML需要配置这个
mybatis.mapper-locations=classpath:mapper/**Mapper.xml

如果配置文件是application.yml,代码如下:

# 数据库连接配置 每个空格都不能省略,yml严格要求格式正确
spring:
  datasource:
    url: jdbc:mysql://127.0.0.1:3306/mybatis_test
    username: root
    password: 123456
    driver-class-name: com.mysql.cj.jdbc.Driver
# 配置打印 MyBatis⽇志
mybatis:
 configuration:
 log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

mybatis:
 configuration:
 map-underscore-to-camel-case: true #配置驼峰⾃动转换
 
# 配置 mybatis xml 的⽂件路径,在 resources/mapper 创建所有表的 xml ⽂件
mybatis:
 mapper-locations: classpath:mapper/**Mapper.xml

2.2 编写持久层代码

持久层代码分两部分:

  1. 方法定义:Interface
  2. 方法实现:XXX.xml

在这里插入图片描述

首先需要定义mapper接口

@Mapper
public interface UserInfoXmlMapper {
    // 查询所有用户
    public List<UserInfo> queryAllUser();
    
}

之后创建xml文件

在这里插入图片描述

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="org.example.blog_mybatis.mapper.UserInfoXmlMapper">
    <select id="queryAllUser" resultType="org.example.blog_mybatis.pojo.UserInfo">
        select username, password, id, username, 
               password, age, gender, phone, delete_flag, 
               create_time, update_time from userinfo
    </select>
</mapper>

对上述内容进行分析:

  • <mapper>标签:需要指定namespace属性,表示命名空间,值为mapper接口的全限定名称,即包括全包名.类名,可以通过以下方式直接获取:

    在这里插入图片描述

  • < select >标签:查询标签,用于进行数据库中的查询操作:

    • id是和mapper接口中定义的方法名称一致,表示对接口的具体实现方法;
    • resultType:返回的数据类型,也就是我们定义的实体类(也需要为全限定名称)

在这里插入图片描述

最后编写测试代码:

package org.example.blog_mybatis.mapper;

import org.example.blog_mybatis.pojo.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;

@SpringBootTest
class UserInfoXmlMapperTest {

    @Autowired
    private UserInfoXmlMapper userInfoXmlMapper;

    @Test
    void queryAllUser() {
        List<UserInfo> list = userInfoXmlMapper.queryAllUser();
        System.out.println(list);
    }
}

在这里插入图片描述

测试成功!!

3. MyBatis XML基础操作

3.1 Insert 操作

UserInfoXmlMapper中进行方法定义:

Integer InsertUser(UserInfo userInfo);

之后在XML文件中进行方法实现:

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

编写测试方法:

@Test
void insertUser() {

    UserInfo userInfo = new UserInfo();
    userInfo.setUsername("飞天虎");
    userInfo.setPassword("125");
    userInfo.setAge(38);
    userInfo.setGender(1);
    userInfo.setPhone("100");
    Integer count = userInfoXmlMapper.InsertUser(userInfo);
    System.out.println("添加数据条数:" + count);
}

在这里插入图片描述

在这里插入图片描述

如果使用@Param设置参数名称的话,使用方法和注解类似,同时若需要获取ID,可以在insert标签中添加属性useGeneratedKeyskeyProperty

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

在这里插入图片描述

3.2 Delete 操作

UserInfoXmlMapper中进行方法定义:

void DeleteUser(Integer id);

之后在XML文件中进行方法实现:

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

编写测试方法:

@Test
void deleteUser() {
    userInfoXmlMapper.DeleteUser(14);
}

在这里插入图片描述

在这里插入图片描述

3.3 Update 操作

UserInfoXmlMapper中进行方法定义:

Integer UpdateUser(UserInfo userInfo); 

之后在XML文件中进行方法实现:

<update id="UpdateUser">
    update userinfo set username = #{username}, age = #{age} where id = #{id}
</update>

编写测试方法:

@Test
void updateUser() {
    UserInfo userInfo = new UserInfo();
    userInfo.setId(12);
    userInfo.setUsername("张三丰");
    userInfo.setAge(100);
    Integer count = userInfoXmlMapper.UpdateUser(userInfo);
    System.out.println("修改数据:" + count);
}

在这里插入图片描述

在这里插入图片描述

3.4 Select 操作

UserInfoXmlMapper中进行方法定义:

UserInfo queryUser(Integer id);

之后在XML文件中进行方法实现:

<select id="queryUser" resultType="org.example.blog_mybatis.pojo.UserInfo">
    select id, username, password, age, 
           gender, phone, delete_flag, 
           create_time, update_time from userinfo where id = #{id}
</select>

编写测试方法:

@Test
void queryUser() {
    UserInfo userInfo = userInfoXmlMapper.queryUser(5);
    System.out.println(userInfo);
}

在这里插入图片描述

:这里能够正确的获取到全部数据是因为在配置文件里配置了自动进行驼峰命名,若没有添加这个配置则返回结果中后续几个属性值(deleteFlag开始)会为null,如何添加在上篇文章有介绍:[MyBaits 框架学习(I)]

4. #{} 与 ${}的使用

在前面我们使用#{}来进行参数传递,#{}本身属于预编译SQL机制,通过?占位的方式提前对SQL进行编译,然后把参数填充到SQL语句中,如下:

在这里插入图片描述

如果传进来的是String类型的参数,#{}也会根据类型自动添加引号

${}即时SQL,它的作用就是将参数直接拼接到SQL语句中:

在这里插入图片描述

如果传入的参数是字符串的话,需要手动给它添加上引号,否则传入${}的参数不会自动添加引号,进而报错,比如通过名称查询用户信息,若xml代码这样写:

<select id="queryUserByName" resultType="org.example.blog_mybatis.pojo.UserInfo">
    select id, username, password, age,
           gender, phone, delete_flag,
           create_time, update_time from userinfo where username = ${username}
</select>

在这里插入图片描述

可以看到运行结果会报错,此时就需要我们手动给${}添加引号:

<select id="queryUserByName" resultType="org.example.blog_mybatis.pojo.UserInfo">
    select id, username, password, age,
           gender, phone, delete_flag,
           create_time, update_time from userinfo where username = '${username}'
</select>

在这里插入图片描述

此时查询结果就正确了

5. 动态SQL操作

MyBatis为我们提供了一个强大的功能来解决复杂的SQL操作,那就是动态SQL,它能够完成不同条件下不同的sql拼接,接下来我们来学习相应的标签:

5.1 < if >标签

当我们需要根据特定条件进行语句判断时即可以使用if标签,比如之前通过Insert操作向数据库插入用户信息:

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

如果这个时候性别是非必填字段,希望根据用户有无传入这个属性来让sql编译时自动添加gender这个字段,则可以使用if标签来进行判断:

<insert id="InsertUser" useGeneratedKeys="true" keyProperty="id" >
    insert into userinfo(
            username,
            password,
            age,
            phone,
         <if test="gender != null">
            gender
         </if>
         )
    values (#{username},
            #{password},
            #{age},
            #{phone},
         <if test="gender != null">
            #{gender}
         </if>
        )
</insert>

在这里插入图片描述

此时因为没有传入gender参数所以sql语句编译时没有显示gender字段

5.2 < trim >标签

在上面的if语句中,其实存在着一个隐藏的问题,那就是字段后面的逗号(","),如果我的gender属性为null,则上述phone字段后面跟着的逗号也会一起被sql语句编译,这个时候就会出现问题了:

在这里插入图片描述

这个时候我们可以通过trim标签来解决这个问题:

insert into userinfo(
        <trim suffixOverrides=",">username,
                password,
                age,
                phone,
                <if test="
        gender != null">
                    gender
                </if>
                
            </trim>
        )
    values (
            <trim suffixOverrides=",">
                #{username},
                #{password},
                #{age},
                #{phone},
                <if test="gender != null">
                    #{gender}
                </if>
            </trim>
        )
</insert>

在这里插入图片描述

对于trim标签,它有以下属性:

  • prefix:表示整个语句块(从<trim>到</trim>),以prefix的值为前缀;
  • suffix:表示整个语句块,以suffix的值为后缀;
  • prefixOverrides:表示整个语句块要除掉的前缀;
  • suffixOverrides:表示整个语句块要除掉的后缀,比如上述代码中的","

在一般情况下,当我们需要对多个字段进行动态生成时即可使用trim标签

5.3 < where >标签

<where>标签只会在子元素有内容的情况下才会插入where子句,而且会自动去除子句开头的 ANDOR:

先在UserInfoXmlMapper中进行方法定义:

List<UserInfo> queryUserByCondition(Integer age, Integer gender, Integer deleteFlag);

之后在XML文件中进行方法实现:

<select id="queryUserByCondition" resultType="org.example.blog_mybatis.pojo.UserInfo">
    select username, password, id, username,
    password, age, gender, phone, delete_flag,
    create_time, update_time from userinfo
    <where>
        <if test="age != null">
            and age = #{age} 
        </if>
        <if test="gender != null">
            and gender = #{gender}
        </if>
        <if test="deleteFlag != null">
            and delete_flag = #{deleteFlag}
        </if>
    </where>
</select>

编写测试方法:

@Test
void queryUserByCondition() {
    List<UserInfo> list = userInfoXmlMapper.queryUserByCondition(18, 1,0);
    System.out.println(list);
}

在这里插入图片描述

test属性对应的参数为方法传入参数而不是字段名,且如果方法传入参数为空,where标签中子元素无内容,不会插入子句:

在这里插入图片描述

5.4 < set >标签

当我们需要根据用户传入的信息来修改内容时,可以通过set标签实现动态修改,如修改参数不为null的属性:

<update id="UpdateUser">
    update userinfo
        <set>
            <if test="username != null">
                username = #{username}
            </if>
            <if test="age != null">
                age = #{age},
            </if>
            <if test="deleteFlag != null">
                delete_flag = #{deleteFlag}
            </if>
        </set>
    where id = #{id}
</update>

在这里插入图片描述

set标签用于update语句中,并且会删除额外的逗号,以上标签也可以使用替换

5.5 < foreach >标签

当我们需要对集合进行遍历时可以使用该标签,foreach标签有以下属性:

  • collection:绑定方法参数中的集合,如List,Set,Map或数组对象;
  • item:遍历时的每一个对象;
  • open:遍历开始时加的前缀;
  • close:遍历结束时加的后缀;
  • separator:每次遍历之间间隔的字符串

如果我们现在需要批量删除用户信息,就可以使用foreach标签进行遍历删除,代码如下:

UserInfoXmlMapper中进行方法定义:

void DeleteUserById(List<Integer> ids);

之后在XML文件中进行方法实现:

<delete id="DeleteUserById">
    delete from userinfo
    <where>
        id in
        <foreach collection="ids" item="id" open="(" close=")" separator=",">
            #{id}
        </foreach>
    </where>
</delete>

编写测试代码:

void deleteUserById() {
    List<Integer> list = new ArrayList<>();
    list.add(15);
    list.add(16);
    list.add(17);
    userInfoXmlMapper.DeleteUserById(list);
}

在这里插入图片描述

在这里插入图片描述

5.6 < include >标签

XMl文件中配置sql,有时候会出现许多重复的字段,这样会造成一定的代码冗余:

在这里插入图片描述

对此,我们可以对重复的代码进行抽取,将其通过<sql>标签封装到一个SQL片段中,然后再通过<include>标签进行引用:

  • <sql>:定义可重复的SQL片段;
  • <include>:通过属性refid,指定包含的SQL片段

在xml文件中添加:

<sql id="allColum">
    id, username, password, age,
    gender, phone, delete_flag,
    create_time, update_time
</sql>

通过标签引用重复sql片段,且rafid属性的值与sql标签中id的属性值相同

<select id="queryUser" resultType="org.example.blog_mybatis.pojo.UserInfo">
    select <include refid="allColum"></include> from userinfo where id = #{id}
</select> 

在这里插入图片描述

总结

对于MyBatis XML方式的使用就介绍到这,对于注解和XML两者的使用范围并不固定,推荐在进行简单的SQL操作时可以使用注解更加方便快捷,而对于复杂的SQL操作则可以使用XML的方式来进行高效解决!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1614512.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

通过DaoCloud DCE的场景化应用看容器云平台的核心能力(三)

以下场景来自DaoCloud官方文档场景化视频&#xff0c;这里以文字形式简单提取下要点&#xff0c;包括操作步骤和一些问题。 一共13个场景&#xff0c;本篇包含5个&#xff1a;9.快速定位异常与排障、10.基于CICD的应用发布、11.基于GitOps持续部署云原生应用、12.使用中间件与…

5大自动化测试的Python框架 | 实用干货

自从2018年被评选为编程语言以来&#xff0c;Python在各大排行榜上一直都是名列前茅。 目前&#xff0c;它在Tiobe指数中排名第三个&#xff0c;仅次于Java和C。随着该编程语言的广泛使用&#xff0c;基于Python的自动化测试框架也应运而生&#xff0c;且不断发展与丰富。 因…

微信小程序:基于MySQL+Nodejs的汽车品牌管理系统

各位好&#xff0c;接上期&#xff0c;今天分享一个通过本地MySQLNodejs服务器实现CRUD功能的微信小程序&#xff0c;一起来看看吧~ 干货&#xff01;微信小程序通过NodeJs连接MySQL数据库https://jslhyh32.blog.csdn.net/article/details/137890154?spm1001.2014.3001.5502 …

阶段性学习汇报 4月19日

目录 一、毕业设计和毕业论文 二、学习python和vue 三、阅读知识图谱 四、下周规划 一、毕业设计和毕业论文 毕业设计后端功能基本实现&#xff0c;但是还有些具体的细节需要优化。前端小程序部分只有个前端页面以及部分交互逻辑&#xff0c;还需进一步完善。在疾病预测这里本…

力扣hot100(python解析)

文章目录 13. 合并区间14. 轮转数组 13. 合并区间 合并区间 数组 排序 思路&#xff1a; 代码&#xff1a; class Solution:def merge(self, intervals):result []if len(intervals) 0:return result # 区间集合为空直接返回intervals.sort() # 默认按照区间的左边界进…

个人开发 App 最简单方法:使用现代开发工具和平台

在移动应用市场的蓬勃发展下&#xff0c;个人开发者也有机会将自己的创意转化为实际的应用程序&#xff0c;并通过应用商店实现盈利。然而&#xff0c;对于许多初学者来说&#xff0c;如何开始个人开发一个应用可能会感到困惑。本文将介绍个人开发 App 的最简单方法&#xff0c…

【树莓派学习】系统烧录及VNC连接、文件传输

【树莓派学习】系统烧录及VNC连接、文件传输 Raspberry Pi is a series of small single-board computers (SBCs) developed in the United Kingdom by the Raspberry Pi Foundation in association with Broadcom. Since 2013, Raspberry Pi devices have been developed and…

Vitis HLS 学习笔记--优化指令-ARRAY_PARTITION

目录 1. ARRAY_PARTITION 概述 2. 语法解析 2.1 参数解释 2.1.1 variable 2.1.2 type 2.1.3 factor 2.1.4 dim 2.2 典型示例 2.2.1 dim1 2.2.2 dim2 2.2.3 dim0 3. 实例演示 4. 总结 1. ARRAY_PARTITION 概述 ARRAY_PARTITION 指令中非常重要&#xff0c;它用于优…

银河麒麟redis安装

一.编译和安装Redis wget http://download.redis.io/releases/redis-4.0.9.tar.gz 执行如下命令&#xff0c;解压包。 tar -zxvf redis-4.0.9.tar.gz 执行如下命令&#xff0c;进入deps目录 cd redis-4.0.9/deps 执行如下命令&#xff0c;编译Redis依赖库。 make -j4 hiredis l…

民航电子数据库:CAEMigrator迁移工具

目录 一、场景二、迁移步骤 一、场景 1、对接民航电子数据库 2、需要将mysql数据库迁移到民航电子数据库 3、使用CAEMigrator迁移工具 二、迁移步骤

VMware 15 虚拟机网络遇到的问题

剧情提要 通过Cent os7 的镜像文件&#xff0c;创建了一个虚拟机A&#xff08;后面简称A&#xff09;&#xff0c;事后发现&#xff0c;宿主机无法ping通A 在虚拟机中通过IP a 看到的IP信息也没有只管的ip信息如图 然后执行&#xff0c;宿主机才能访问A。 sudo dhclient ens…

MySQL 基础语法(2)

文章目录 创建表查看表修改表表数据插入 本文为表结构相关的基础语言库相关的基础语句 创建表 CREATE TABLE table_name ( field1 datatype comment xxx, field2 datatype, field3 datatype ) character set 字符集 collate 校验规则 engine 存储引擎;CREATE TABLE&#xff1…

白蚁自动化监测系统解放方案

一、系统介绍 白蚁自动化监测系统是基于物联网的各项白蚁监测点数据的采集形成智能控制系统。提供白蚁实时预警及解决方案&#xff0c;真正实现区域内白蚁种群消灭。白蚁入侵&#xff0c;系统第一时间自动报警&#xff0c;显示入侵位置&#xff0c;实现抓获白蚁于现场的关键环…

算法库应用-有序单链表插入节点

学习源头: 模仿贺利坚老师单链表排序文章浏览阅读5.9k次。  本文针对数据结构基础系列网络课程(2)&#xff1a;线性表中第11课时单链表应用举例。例&#xff1a;拆分单链表 &#xff08;linklist.h是单链表“算法库”中的头文件&#xff0c;详情单击链接…&#xff09;//本程…

JS 分片任务的高阶函数封装

前言 在我们的实际业务开发场景中&#xff0c;有时候我们会遇到渲染大量元素的场景&#xff0c;往往这些操作会使页面卡顿&#xff0c;给用户带来非常不好的体验&#xff0c;这时候我们就需要给任务分片执行。 场景复现 我们看一段代码&#xff1a; <!DOCTYPE html> &l…

P2P面试题

1&#xff09;描述一下你的项目流程以及你在项目中的职责&#xff1f; 一个借款产品的发布&#xff0c;投资人购买&#xff0c;借款人还款的一个业务流程&#xff0c;我主要负责测注册&#xff0c;登录&#xff0c;投资理财这三个模块 2&#xff09;你是怎么测试投资模块的&am…

T1级,生产环境事故—Shell脚本一键备份K8s的YAML文件

大家好&#xff0c;我叫秋意零。 最近对公司进行日常运维工作时&#xff0c;出现了一个 T1 级别事故。导致公司的“酒云网”APP的无法使用。我和我领导一起搞了一个多小时&#xff0c;业务也停了一个多小时。 起因是&#xff1a;我的部门直系领导&#xff0c;叫我**删除一个 …

vcruntime140.dll文件丢失的解决办法,为什么导致vcruntime140.dll文件丢失

废话少说&#xff0c;今天这篇文章直接和大家聊聊vcruntime140.dll文件丢失的解决办法&#xff0c;同时给大家分析vcruntime140.dll文件为什么会导致文件丢失。一起来看看吧。 vcruntime140.dll文件缺失的可能原因 A. 文件损坏或删除&#xff1a;vcruntime140.dll文件可能会…

《人工智能》大作业反馈

0 写在前面 春学期带了一门很有意思的课《人工智能与机器学习》&#xff0c;在学期初就在构思怎么才能把这门课上好&#xff0c;怎么才能让一群土木大类专业的小孩对人工智能这个领域感兴趣&#xff0c;怎么才能让他们将这个专业与自己专业结合起来。我对自己的要求就是希望自…

【C++类和对象】初始化列表与隐式类型转换

&#x1f49e;&#x1f49e; 前言 hello hello~ &#xff0c;这里是大耳朵土土垚~&#x1f496;&#x1f496; &#xff0c;欢迎大家点赞&#x1f973;&#x1f973;关注&#x1f4a5;&#x1f4a5;收藏&#x1f339;&#x1f339;&#x1f339; &#x1f4a5;个人主页&#x…