【MyBatis】MyBatis基础操作

在这里插入图片描述

文章目录

  • 前言
  • 注解方式书写 MyBatis
    • 打印 MyBatis 日志
    • 参数传递
    • MyBatis 增加操作
      • 返回主键
    • MyBatis 删除操作
    • MyBatis 修改操作
    • MyBatis 查找操作
      • 1. 对查询结果进行别名
      • 2. @Results注解
      • 3. 开启驼峰命名(推荐)
  • XML 配置文件方法书写 MyBatis
    • 配置数据库的相关配置
    • 指定XML的文件路径
    • xml 实现
      • 增加操作
      • 删除操作
      • 修改操作
      • 查找操作
        • 1. 别名
        • 2. 定义 result
        • 3. 开启驼峰命名

前言

前面我们学习了什么是 MyBatis,为什么要使用 MyBatis,如何创建 MyBatis 环境,并且了解了使用单元测试对代码功能进行测试。那么今天这篇文章将为大家分享关于 MyBatis 的基础操作。

书写 MyBatis 的方法有两种:注解和XML的方法,这里我们两种方法都是给大家写到。

注解方式书写 MyBatis

打印 MyBatis 日志

前面文章中也提到了日志对于我们开发人员的重要性,在使用 MyBatis 框架的过程中,我们同样也可以看到执行 MyBatis 代码的过程中产生的日志。

那么如何打印出 MyBatis 日志呢?我们需要在配置文件中添加配置项来告知 Spring,我们需要知道 MyBatis 代码执行过程中产生的日志。

mybatis:configuration: # 配置打印 MyBatis⽇志log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

添加这个配置了之后,我们在启动项目就会发现,MyBatis 执行过程中的日志就可以看到了。

在这里插入图片描述

参数传递

假设我们需要查询 id 为 4 的用户的信息的时候,对应的 SQL 语句就是 select * from userinfo where id=4;,对应到我们的 MyBatis 就是这样的。

@Select("select * from userinfo where id=4")
public UserInfo getById();

在这里插入图片描述

在这里插入图片描述
但是可以发现,这样写 SQL 语句的话,这个查询的条件就写死了,那么是否有一种方法可以根据我们用户传递的参数查询指定条件的数据呢?答案是可以的,这就需要用到 MyBatis 中参数传递的知识了。

MyBatis 中使用 #{} 来获取方法中的参数,当我们调用这个方法并且传入参数的时候通过这个 #{} 就能将传递过来的参数给 SQL 语句。

@Select("select * from userinfo where id=#{id}")
public UserInfo getById1(int id);
@Test
void getById1() {UserInfo userInfo = userInfoMapper.getById1(3);log.info(userInfo.toString());
}

在这里插入图片描述
如果 mapper 接口类型的方法只有一个普通类型的参数,#{…}里面的属性名可以随便写,但是还是建议和参数名保持一致。

@Select("select * from userinfo where id=#{userid}")
public UserInfo getById1(Integer id);

在这里插入图片描述
当然,如果我们觉得方法参数的名字不好的话,我们也可以使用 @Param 对方法的参数进行重命名,但是如果使用 @Param 对参数进行重命名的话,#{…}里面的属性名必须和别名是相同的。

@Select("select * from userinfo where id=#{userid}")
public UserInfo getById1(@Param("userid") Integer id);

在这里插入图片描述

@Select("select * from userinfo where id=#{id}")
public UserInfo getById1(@Param("userid") Integer id);

在这里插入图片描述

MyBatis 增加操作

数据库的主要操作无非就是增删改查,那么我们使用 MyBatis 如何实现数据库的增删改查呢?

MyBatis 增加操作需要使用到 @Insert 注解。

@Insert("insert into userinfo (username, `password`, age, gender, phone)" +"values (#{username}, #{password}, #{age}, #{gender}, #{phone})")
public Integer insert(UserInfo userInfo);
@Test
void insert() {UserInfo userInfo = new UserInfo();userInfo.setUsername("小美");userInfo.setPassword("小美");userInfo.setAge(18);userInfo.setGender(2);userInfo.setPhone("3139812381");int ret = userInfoMapper.insert(userInfo);log.info(ret + "行被更新");
}

这里可以选择将插入的数据封装成Java对象作为参数传入,也可以将这每个些信息当成一个参数进行传递。当以Java对象的形式作为参数进行传递的话,Java对象中的属性名需要保持和数据库中的列名相同,因为当传递的参数是对象的话,MyBatis 会进入到这个对象中,查看这个对象中的属性,然后与数据库中的列名做比较,如果相同就将Java对象中属性的值代入 SQL 语句中,不相同则不带入。

在这里插入图片描述

返回主键

Insert 语句默认返回的是受影响的行数,如果我们需要只需要将方法的返回类型声明为 int/Integer 就可以了,如果不需要,就将方法的返回类型声明为 void。

但是有些时候,我们不仅仅需要 insert 语句影响的行数,可能还需要获取到其他的信息,比如自增主键的值,那么我们如何获取到 insert 之后自增主键的值呢?如果我们直接拿到Java对象中与自增主键列同名的属性,能拿到吗?

log.info(ret + "行被更新" + userInfo.getId());

在这里插入图片描述
按理来说这个自增主键应该是 5 了,但是拿到的确实 0,说明这个还是初始值,那么应该进行什么操作才能拿到这个 insert 的一行的自增主键的值呢?

如果想要拿到自增主键的值,需要在 Mapper 接口的方法上添加一个 @Options 注解。

@Options(useGeneratedKeys = true, keyProperty = "id")
@Insert("insert into userinfo (username, `password`, age, gender, phone)" +"values (#{username}, #{password}, #{age}, #{gender}, #{phone})")
public Integer insert(UserInfo userInfo);
  • useGeneratedKeys:这会令 MyBatis 使⽤ JDB 的 getGeneratedKeys ⽅法来取出由数据库内部⽣成的主键(⽐如:像 MySQL 和 SQL Server 这样的关系型数据库管理系统的⾃动递增字段),默认值:false
  • keyProperty:指定能够唯⼀识别对象的属性,MyBatis 会使⽤ getGeneratedKeys 的返回值或 insert 语句的 selectKey ⼦元素设置它的值,默认值:未设置(unset)

useGeneratedKeys 参数是是否需要使用到自增主键,然后 keyProperty 参数表示将获取到的自增主键的值赋值给 Java 的哪个属性,因为这里我们传递的参数是 Java 对象,所以当获取到 insert 插入的那行的自增主键赋值给 id 之后,MyBatis 就会去这个对象的属性去找有没有 id 这个属性,如果有就赋值给它。如果传递的参数是多个普通类型参数的话,那么 MyBatis 就会在这些传递的参数中找,看是否有相同名称的参数,然后赋值给它。

在这里插入图片描述
因为我这里为大家演示的时候,多次插入了,所以获取到的自增主键的值是8,这影响不大,我们关键看是否 insert 插入的这行的自增主键赋值给了 userInfo 对象中的 id 属性。

如果传递的是对象,并且在接收参数的时候对这个参数进行了重命名的话,SQL 中的 #{} 参数就需要指定是哪个引用的哪个属性。

@Options(useGeneratedKeys = true, keyProperty = "id")
@Insert("insert into userinfo (username, `password`, age, gender, phone)" +"values (#{user.username}, #{user.password}, #{user.age}, #{user.gender}, #{user.phone})")
public Integer insert(@Param("user") UserInfo userInfo);

MyBatis 删除操作

使用 MyBatis 进行删除数据的操作需要使用到 @Delete 注解。

@Delete("delete from userinfo where id=#{id}")
public void delete(Integer id);
@Test
void delete() {userInfoMapper.delete(1);
}

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

MyBatis 修改操作

MyBatis 实现修改操作需要使用到 @Update 注解。

@Update("update userinfo set gender=#{gender} where id=#{id}")
public void update(Integer gender, Integer id);
@Test
void update() {userInfoMapper.update(0, 8);
}

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

MyBatis 查找操作

查询操作不就是 select 吗,还有什么需要讲的吗?

通过前面的查询我们可以发现,我们 Java 的 userInfo 对象中的 deleteFlag createTime updateTime 都是初识值,也就是说,这些属性并没有被赋值,那么这是为什么呢?我的 select SQL 语句不是查询出结果了吗?

还记得我们前面说了什么吗?需要保证 Java 中的属性名和数据库表中的列名保持一致,因为当 select 查询出结果之后,MyBatis 会根据方法的返回值类型,如果是普通类型的话,并且 select 查询出来的结果的类型和方法返回值的类型相同的话,那么就会直接将这个查询出来的结果进行返回;但是如果方法返回值的类型是 Java 对象的话,MyBatis 会将查询出来的结果按照列名与 Java 对象中的属性名进行匹配,如果相同就赋值给这个属性,没有相同的属性名,那么 Java 对象的这个属性就是初始值。

虽然保证数据库表中的列名和 Java 对象中的属性名保持一致很重要,但是由于 SQL 和 Java 的变量名命名规则和习惯存在差异,比如:在 SQL 中,deletflg 就是这样表示——delete_flag,而在 Java 中是以小驼峰的习惯进行命名,也就是——deleteFlag,那么这样的话,就无法保证名称一致了,那么这样该怎么办呢?有三种解决方法:

1. 对查询结果进行别名

前面我们学习 SQL 的时候肯定学过对查询结果进行重命名吧,我们可以将列名与Java属性名不相同的列进行重命名。

@Select("select id, username, password, age, gender, delete_flag as deleteFlag," +"create_time as createTime, update_time as updateTime from userinfo")
public List<UserInfo> selectAll1();
@Test
void selectAll1() {List<UserInfo> list = userInfoMapper.selectAll1();log.info(list.toString());
}

在这里插入图片描述

2. @Results注解

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
public @interface Results {String id() default "";Result[] value() default {};
}

@Results 注解的参数有两个,一个是 String 类型,这个参数的用法稍后给大家讲,第二个参数就是 Result[] 一个数组,数组中的每个元素都是一个 Result 类型,而 Result 中也有很多参数,但是这里我们主要用到两个:

在这里插入图片描述

@Results(value = {@Result(column = "delete_flag", property = "deleteFlag"),@Result(column = "create_time", property = "createTime"),@Result(column = "update_time", property = "updateTime")})
@Select("select id, username, password, age, gender, delete_flag," +"create_time, update_time from userinfo")
public List<UserInfo> selectAll2();
@Test
void selectAll2() {List<UserInfo> list = userInfoMapper.selectAll1();log.info(list.toString());
}

在这里插入图片描述
如果我们又想根据给定的 id 进行查询的话,因为表的列名和Java的属性名不同,那么是否又需要写跟上面一样的 @Results 注解吗?不是的,这就需要用到 @Results 注解的第一个参数了,通过指定 @Results 的第一个参数,可以使得这个 @Results 注解可以重复使用。

@Results(id = "BaseMap", value = {@Result(column = "delete_flag", property = "deleteFlag"),@Result(column = "create_time", property = "createTme"),@Result(column = "update_time", property = "updateTime")
})

如果后面的方法也想使用和这个 @Results 注解相同的配置的话,只需要在方法上加上 @ResultMap 注解就可以了。

@ResultMap("BaseMap")
@Select("select id, username, password, age, gender, delete_flag," +"create_time, update_time from userinfo where id=#{id}")
public UserInfo getById2(Integer id);

这个 @ResultMap 中的参数需要保证和 @Results 注解中的第一个参数 id 的值保持一致才可以使用该 @Results 的相同配置。

在这里插入图片描述

3. 开启驼峰命名(推荐)

通常数据库列使⽤蛇形命名法进⾏命名(下划线分割各个单词),⽽ Java 属性⼀般遵循驼峰命名法约定。为了在这两种命名⽅式之间启⽤⾃动映射,需要将 mapUnderscoreToCamelCase 设置为 true。

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

当在配置文件添加这个配置之后,我们再试一次看看结果:

@Select("select * from userinfo")
public List<UserInfo> selectAll3();
@Test
void selectAll3() {List<UserInfo> list = userInfoMapper.selectAll3();log.info(list.toString());
}

在这里插入图片描述
可以发现通过在配置文件中添加配置从而解决 SQL 和 Java 命名规则不同而导致的问题非常的方便,所以也建议大家使用这个做法。

XML 配置文件方法书写 MyBatis

配置数据库的相关配置

不管使用什么方法书写 MyBatis,首先就是需要配置数据库相关的信息,这里 XML 配置数据库信息的方式跟注解配置数据库的方式是一样的,我这里就不过多介绍了。

# 数据库连接配置
spring:datasource:url: jdbc:mysql://127.0.0.1:3306/mybatis_test?characterEncoding=utf8&useSSL=falseusername: rootpassword: rootdriver-class-name: com.mysql.cj.jdbc.Driver

指定XML的文件路径

当配置完成数据库相关配置之后,还需要指定我们的 MyBatis XML 的文件路径。

mybatis:mapper-locations: classpath:mapper/**Mapper.xml

这个路径在我们的项目中这样显示:

在这里插入图片描述
classpath 就是我们项目的 resources 文件夹,mapper 是我们自己创建的用来操作 MyBatis 的文件夹,这个文件夹中存放的都是 xml 文件,而这个配置中的 **Mapper.xml 则表示所有以 Mapper.xml 结尾的文件,如果想表示以 .xml 结尾的文件,则用 **.xml 来表示。通常我们的操作 MyBatis 的 XML 文件都是以 Mapper.xml 作为后缀。这里的 mapper 文件夹和 **Mapper.xml 都是程序员自定义的,只要能够对上就可以了。

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 <mapper namespace="com.example.mybatis20231226.Mapper.UserInfoXMLMapper"></mapper>

这里 namespace 中的值是我们的要实现的接口的全限定类名。

在这里插入图片描述

这里的接口就正常写,主要的操作在我们的 xml 文件中。

package com.example.mybatis20231226.Mapper;import com.example.mybatis20231226.Model.UserInfo;
import org.apache.ibatis.annotations.Mapper;import java.util.List;@Mapper
public interface UserInfoXMLMapper {public List<UserInfo> selectAll();
}

后面的实现就是写在 <mapper> 标签中的,假设我们这里还是查询,就可以这样写:

<mapper namespace="com.example.mybatis20231226.Mapper.UserInfoXMLMapper"><select id="selectAll" resultType="com.example.mybatis20231226.Model.UserInfo">select * from userinfo</select>
</mapper>

id 参数指定要实现的接口中的方法名称,resultType 指定该方法的返回的数据的类型的路径,这里不是 List,而是 List 中的元素的类型 UserInfo。

@Slf4j
@SpringBootTest
class UserInfoXMLMapperTest {@Autowiredprivate UserInfoXMLMapper userInfoXMLMapper;@Testvoid selectAll() {List<UserInfo> list = userInfoXMLMapper.selectAll();log.info(list.toString());}
}

在这里插入图片描述

增加操作

public Integer insert(UserInfo userInfo);
<insert id="insert">insert into userinfo (username, password, age, gender, phone)values(#{username}, #{password}, #{age}, #{gender}, #{phone})
</insert>
@Test
void insert() {UserInfo userInfo = new UserInfo();userInfo.setUsername("小帅");userInfo.setPassword("小帅");userInfo.setAge(28);userInfo.setGender(1);userInfo.setPhone("31737137128");int ret = userInfoXMLMapper.insert(userInfo);log.info(ret + "被更新");
}

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

获取插入数据的自增主键

要想获取到插入数据的自增主键,需要在 <insert> 标签中配置 userGenerateKeys 参数和 keyProperty 参数。

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

在这里插入图片描述

别名

xml 别名的操作和使用注解的操作是类似的。

public Integer insert(@Param("user") UserInfo userInfo);
<insert id="insert" useGeneratedKeys="true" keyProperty="id">insert into userinfo (username, password, age, gender, phone)values(#{user.username}, #{user.password}, #{user.age}, #{user.gender}, #{user.phone})
</insert>

删除操作

public void delete(Integer id);
<delete id="delete">delete from userinfo where id=#{id}
</delete>
@Test
void delete() {userInfoXMLMapper.delete(2);
}

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

修改操作

public void update(Integer gender, Integer id);
<update id="update">update userinfo set gender=#{gender} where id=#{id}
</update>
@Test
void update() {userInfoXMLMapper.update(0, 3);
}

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

查找操作

这里也是主要为了解决 SQL 命名规则和 Java 命名规则不同导致的问题,解决方法和通过注解是一样的。

1. 别名
public List<UserInfo> selectAll2();
<select id="selectAll2" resultType="com.example.mybatis20231226.Model.UserInfo">select id, username, password, age, gender, delete_flag as deleteFlag,create_time as createTime, update_time as updateTime from userinfo
</select>
@Test
void selectAll2() {List<UserInfo> list = userInfoXMLMapper.selectAll1();log.info(list.toString());
}

在这里插入图片描述

2. 定义 result
public List<UserInfo> selectAll1();
<resultMap id="XmlBaseMap" type="com.example.mybatis20231226.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="selectAll1" resultMap="XmlBaseMap">select * from userinfo
</select>

id标签用于标识主键列和Java对象的对应关系,<result>标签则用于标识非主键列和Java对象的对应关系

@Test
void selectAll1() {List<UserInfo> list = userInfoXMLMapper.selectAll1();log.info(list.toString());
}

在这里插入图片描述

3. 开启驼峰命名

这个和前面注解的做法是一样的,都是在配置文件中讲驼峰转换的配置的值设置为 true 就可以了。

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

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

本地部署Stable Diffusion教程,亲测可以安装成功

系列文章目录 Stable Diffusion界面参数及模型使用 谷歌Colab云端部署Stable Diffusion 进行绘图 文章目录 系列文章目录前言一、Stable Diffusion是什么&#xff1f;二、安装前的准备1.检查自己的电脑配置是否符合要求2.下载安装Git3.下载安装Python 三、下载stable-diffusi…

CSS基本知识

文章目录 1. CSS 是什么2. 基本语法规范3. 引入方式3.1 内部样式表3.2 行内样式表3.3 外部样式 4. 选择器4.1 选择器的功能4.2 选择器的种类4.3 基础选择器4.3.1 标签选择器4.3.2 类选择器4.3.3 id 选择器4.3.4 通配符选择器 4.4 复合选择器4.4.1 后代选择器4.4.2 伪类选择器 5…

硬件开发避坑日志

FT232 串口工具会,多发和漏发0x00. 对比之下STC工具更稳定。 红外接收关 5 V 和 3.3V 工作电压的接收波形不一样。 3.3V工作不正常&#xff0c;接收不正常 。 5V工作是标准的NEC协议

WPF DatePicker与Calendar的使用和样式修改

什么是DatePicker&#xff0c;Calendar Calendar&#xff1a;日历&#xff08;显示年月日视图控件&#xff09;DatePicker&#xff1a;日期选择器&#xff08;是一个更小的控件&#xff0c;点击控件时才会弹出一个日历&#xff09; Calendar使用 常用属性 DisplayMode&#…

上门小程序源码开发:从0到1的完全指南

在当今数字化时代&#xff0c;上门服务行业迎来了巨大的发展机遇。而开发上门小程序源码&#xff0c;则是实现定制化、高效化服务的关键步骤之一。作为该领域的专家&#xff0c;我将为您呈现从0到1的完全指南&#xff0c;助您轻松掌握上门小程序源码开发的核心要点和技巧。 什…

手把手教你用Python打造一个语音合成系统

目录 引言 一、了解语音合成技术 1.1 什么是语音合成技术 1.2 语音合成技术的分类 二、准备所需工具和库 2.1 Python编程语言 2.2 TensorFlow深度学习框架 2.3 WaveNet模型 三、搭建语音合成系统 3.1 数据准备 3.2 数据预处理 3.3 构建WaveNet模型 3.4 训练WaveNe…

PythonStudio=vb7国人写的python可视化窗体设计器IDE,可以替代pyqt designer等设计器了

【免费】PythonStudio-1.1.5-x86最新版国人开发的python界面ide&#xff0c;可以制作窗体资源-CSDN文库https://download.csdn.net/download/xiaoyao961/88688447 【免费】PythonStudio-1.1.5-x64-Setup.exe国人开发的python界面ide&#xff0c;可以制作窗体资源-CSDN文库https…

Windows下MongoDB启动及停止服务

1.CMD黑窗口输入启动命令&#xff1a; net start MongoDB 2.CMD黑窗口输入停止命令&#xff1a; net stop MongoDB

vue封装基础input组件(添加防抖功能)

先看一下效果&#xff1a; // 调用页面 <template><div><!-- v-model&#xff1a;伪双向绑定 --><my-input v-model"inputVal" label"姓名" type"textarea" /></div> </template><script> import…

如何将铁威马NAS设置为固定IP?

首先你需要配置正确的TNAS的网络设置&#xff0c;否则TNAS 将无法连接到互联网或无法被访问。 你可以在网络接口中设置TNAS的网络接口参数。TNAS设备可能配置有一个&#xff0c;两个或者两个以上的网络接口。你可以对网络接口逐一进行设置。 1、登录铁威马TOS系统&#xff0c…

C++——STL标准模板库——容器详解——stack+queue

一、基本概念 &#xff08;一&#xff09;stack&#xff08;栈或堆栈&#xff09; 一种只允许同一端进出的线性数据结构&#xff0c;数据先进后出。基本模型类似于瓶子。 &#xff08;二&#xff09;queue&#xff08;队列&#xff09; 一种只允许一端进、另一端出的线性数…

金智维KRPA问题集锦

KRPA问题集锦 1、打开浏览器错误 &#xff08;1&#xff09;浏览器插件问题&#xff0c;需要正确安装ChromePlug插件&#xff0c; &#xff08;2&#xff09;windows系统下需要正确配置chrome.exe运行环境变量