【Java EE】MyBatis使用注解操作数据库

embedded/2024/11/11 5:48:47/

文章目录

  • 🍀参数传递
  • 🌴增(Insert)
    • 🌸返回主键
  • 🍃删(Delete)
  • 🌳改(Update)
  • 🌲查(Select)
    • 🌸起别名
    • 🌸结果映射
    • 🌸开启驼峰命名(推荐)
  • ⭕总结

🍀参数传递

需求: 查找id=4的⽤⼾,对应的SQL就是: select * from userinfo where id=4

@Select("select username, `password`, age, gender, phone from userinfo where 
id= 4 ")
UserInfo queryById();

但是这样的话, 只能查找id=4 的数据, 所以SQL语句中的id值不能写成固定数值,需要变为动态的数值
解决⽅案:在queryById⽅法中添加⼀个参数(id),将⽅法中的参数,传给SQL语句

使⽤ #{} 的⽅式获取⽅法中的参数

@Select("select username, `password`, age, gender, phone from userinfo where 
id= #{id} ")
UserInfo queryById(Integer id);

如果mapper接⼝⽅法形参只有⼀个普通类型的参数,#{…} ⾥⾯的属性名可以随便写,如:#{id}、#
{value}。建议和参数名保持⼀致

添加测试⽤例

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

在这里插入图片描述

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

@Select("select username, `password`, age, gender, phone from userinfo where
id= #{userid} ")
UserInfo queryById(@Param("userid") Integer id);

🌴增(Insert)

SQL 语句:

insert into userinfo (username, `password`, age, gender, phone) values
("zhaoliu","zhaoliu",19,1,"18700001234")

把SQL中的常量替换为动态的参数
Mapper接⼝

@Insert("insert into userinfo (username, `password`, age, gender, phone) 
values (#{username},#{password},#{age},#{gender},#{phone})")
Integer insert(UserInfo userInfo);

直接使⽤UserInfo对象的属性名来获取参数
测试代码:

@Test
void insert() {UserInfo userInfo = new UserInfo();userInfo.setUsername("zhaoliu");userInfo.setPassword("zhaoliu");userInfo.setGender(2);userInfo.setAge(21);userInfo.setPhone("18612340005");userInfoMapper.insert(userInfo);
}

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

@Insert("insert into userinfo (username, `password`, age, gender, phone) 
values (#{userinfo.username},#{userinfo.password},#{userinfo.age},#
{userinfo.gender},#{userinfo.phone})")
Integer insert(@Param("userinfo") UserInfo userInfo);

🌸返回主键

Insert 语句默认返回的是 受影响的⾏数
但有些情况下, 数据插⼊之后, 还需要有后续的关联操作, 需要获取到新插⼊数据的id

⽐如订单系统
当我们下完订单之后, 需要通知物流系统, 库存系统, 结算系统等, 这时候就需要拿到订单ID

如果想要拿到⾃增id, 需要在Mapper接⼝的⽅法上添加⼀个Options的注解

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

测试数据:

void insert() {UserInfo userInfo = new UserInfo();userInfo.setUsername("zhaoliu");userInfo.setPassword("zhaoliu");userInfo.setGender(2);userInfo.setAge(21);userInfo.setPhone("18612340005");Integer count = userInfoMapper.insert(userInfo);System.out.println("添加数据条数:" +count +", 数据ID:" + userInfo.getId());
}

在这里插入图片描述

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

🍃删(Delete)

delete from userinfo where id=6

把SQL中的常量替换为动态的参数
Mapper接⼝

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

🌳改(Update)

update userinfo set username="zhaoliu" where id=5

把SQL中的常量替换为动态的参数
Mapper接⼝

@Update("update userinfo set username=#{username} where id=#{id}")
void update(UserInfo userInfo);

🌲查(Select)

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

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

在这里插入图片描述
从运⾏结果上可以看到, 我们SQL语句中, 查询了delete_flag, create_time, update_time, 但是这⼏个
属性却没有赋值

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

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

在这里插入图片描述
解决办法:

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

🌸起别名

在SQL语句中,给列名起别名,保持别名和实体类属性名⼀样

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

SQL语句太⻓时, 使⽤加号 + 进⾏字符串拼接

🌸结果映射

@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定义⼀个名称

@Select("select id, username, `password`, age, gender, phone, delete_flag, 
create_time, update_time from userinfo")
@Results(id = "resultMap",value = {@Result(column = "delete_flag",property = "deleteFlag"),@Result(column = "create_time",property = "createTime"),@Result(column = "update_time",property = "updateTime")
})
List<UserInfo> queryAllUser();
@Select("select id, username, `password`, age, gender, phone, delete_flag, 
create_time, update_time " +"from userinfo where id= #{userid} ")
@ResultMap(value = "resultMap")
UserInfo queryById(@Param("userid") Integer id);

使⽤ id 属性给该 Results 定义别名, 使⽤ @ResultMap 注解来复⽤其他定义的 ResultMap
在这里插入图片描述

🌸开启驼峰命名(推荐)

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

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

驼峰命名规则: abc_xyz => abcXyz
• 表中字段名:abc_xyz
• 类中属性名:abcXyz

Java 代码不做任何处理

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

⭕总结

感谢大家的阅读,希望得到大家的批评指正,和大家一起进步,与君共勉!


http://www.ppmy.cn/embedded/33024.html

相关文章

uni-app 从vue3项目创建到Pinia管理数据全局使用 持久化存储数据 详细教程

一、创建uni-app项目 1. 安装HBuilder X&#xff0c;下载地址&#xff1a;https://www.dcloud.io/hbuilderx.html 2. 打开HBuilder X&#xff0c;点击左上角的“文件”->“新建”->“项目”&#xff0c;选择“uni-app”项目模板&#xff0c;填写项目名称和项目路径&…

区块链 | IPFS:IPNS(实操版)

&#x1f98a;原文&#xff1a;Publishing IPNS names Publishing IPNS names with Kubo Step1&#xff1a; 启动你的 IPFS 守护进程&#xff08;如果尚未运行&#xff09;&#xff1a; $ ipfs daemon说明&#xff1a;以 $ 开头的是命令&#xff0c;以 > 开头的是执行结果…

Wpf DataGrid ComboBox 列

遇到的问题 最开始找到的例子要写 Convert, 感觉和 Vue-Elment 的差别比较大后面找到类似与 Vue-Element UI 的写法&#xff0c;开始时数值不更新 关键代码 <DataGridTemplateColumn Header"Digit" Width"100"><DataGridTemplateColumn.CellTem…

《QT实用小工具·五十四》果冻弹出效果的动画按钮

1、概述 源码放在文章末尾 该项目实现动画按钮&#xff0c;鼠标放在按钮上可以弹性拉出的三个按钮&#xff0c;使用贝塞尔曲线实现&#xff0c;项目demo显示如下所示&#xff1a; 项目部分代码如下所示&#xff1a; #ifndef WATERCIRCLEBUTTON_H #define WATERCIRCLEBUTTON…

MLP一夜被干掉?革命性新网络KAN【第一篇-base】

要看完哦&#xff0c;文末彩蛋&#xff01; 用“极市平台”的导读语来说&#xff1a;新网络KAN基于柯尔莫哥洛夫-阿诺德定理&#xff0c;带着更少的参数、更强的性能、更好的可解释性来了&#xff0c;深度学习架构革新进入新时代&#xff01; 目录 导语 ​编辑 KAN的基础理论…

公考学习平台|基于SprinBoot+vue的公考学习平台(源码+数据库+文档)

公考学习平台目录 目录 基于SprinBootvue的公考学习平台 一、前言 二、系统设计 三、系统功能设计 5.1用户信息管理 5.2 视频信息管理 5.3公告信息管理 5.1论坛信息管理 四、数据库设计 五、核心代码 六、论文参考 七、最新计算机毕设选题推荐 八、源码获取&…

系统如何做好数据质量管理

对数据从计划、获取、存储、共享、维护、应用、消亡生命周期的每个阶段里可能引发的各类数据质量问题&#xff0c;进行识别、监控、预警、处理等一系列管理活动&#xff0c;并通过改善和提高管理水平使得数据质量获 得进一步提高。 2术语和定义 2.1数据质量 data quality 2.2…

QSqlDatabase的数据库路径或名称问题

在Qt的数据库编程中&#xff0c;先是设置数据库的类型&#xff0c;然后是设置数据库文件的路径&#xff0c;或者数据库名称。若有数据库的用户名、密码&#xff0c;则分别调用setUserName(“”)、setPassword(“”)来设置用户名和密码&#xff1b;若没有&#xff0c;则省略用户…