当前位置: 首页 > news >正文

【MyBatis】实现数据库的增、删、改、查

文章目录

  • 增(Insert)
    • 返回主键
  • 删(Delete)
  • 改(Update)
  • 查(Select)
    • 属性不一致
      • 1. 起别名
      • 2. 结果映射
      • 3. 自动驼峰转换(推荐)

增(Insert)

SQL 中的常量替换成动态的参数

Mapper 接口:

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

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

@Test  
void insert() {  UserInfo userInfo = new UserInfo();  userInfo.setUsername("zhaoliu");  userInfo.setPassword("zhaoliu");  userInfo.setAge(18);  userInfo.setGender(1);  Integer result = userInfoMapper.insert(userInfo);  System.out.println("result: "+result);  
}

运行后,观察数据库执行结果:

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

返回主键

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

  • 比如订单系统
  • 当我们下单之后,需要通知物流系统、库存系统、结算系统等,这时就需要拿到订单的 id

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

//数据库的“增”操作  
@Options(useGeneratedKeys = true, keyProperty = "id")  
@Insert("insert into userinfo (username, password, age, gender) values (#{username}, #{password}, #{age}, #{gender})")  
Integer insert(UserInfo userInfo);
  • useGeneratedKeys: 这会令 MyBatis 使用 JDBCgetGeneratedKeys 方法取出由数据库内部生成的主键(比如:像 MySQLSQL Server 这样的关系型数据库管理系统的自动递增字段),默认值:false
  • keyProperty:指定能够唯一识别对象的属性,MyBatis 会使用 getGeneratedKeys 的返回值或 insert 语句的 selectKey 子元素设置它的值,默认值:未设置(unset

测试数据:

@Test  
void insert() {  UserInfo userInfo = new UserInfo();  userInfo.setUsername("zhaoliu");  userInfo.setPassword("zhaoliu");  userInfo.setAge(18);  userInfo.setGender(1);  Integer result = userInfoMapper.insert(userInfo);  System.out.println("添加的数据: " + result + "数据id: " + userInfo.getId());  
}

运行结果:image.png

  • 注意:设置 useGeneratedKeys=true 之后,方法返回值依然是受影响的行数,自增 id 会设置在上述 Property 指定的属性中

删(Delete)

SQL 中的常量替换为动态的参数

Mapper 接口:

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

测试数据:

@Test  
void delete() {  System.out.println("删除数据:"+userInfoMapper.delete(4));  
}

改(Update)

SQL 中的常量替换为动态的参数

Mapper 接口:

@Update("update userinfo set password = #{password}, age = #{age}")  
Integer update(UserInfo userInfo);

测试数据:

@Test  
void update() {  UserInfo userInfo = new UserInfo();  userInfo.setPassword("123123");  userInfo.setAge(11);  System.out.println("更新数据为:"+userInfoMapper.update(userInfo));  
}

查(Select)

我们在上面查询时发现,有几个字段是没有赋值的,只有 Java 对象属性和数据库字段一模一样时,才会进行赋值

我们查询一些数据:

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

查询结果:image.png
从运行结果上可以看到,我们 SQL 语句中,查询了 delete_flagcreate_timeupdate_time,但是这几个属性却并没有赋值

  • MyBatis 会根据方法的返回结果进行赋值
  • 方法用对象 UserInfo 接收返回结果,MySQL 查询出来数据为一条,就会自动赋值给对象
  • 方法用 List<UserInfo> 接收返回结果,,MySQL 查询出来数据为一条或多条时时,也会自动赋值给 List
  • 但如果 MySQL 查询返回多条,但是方法使用 UserInfo 接收,MyBatis 执行就会报错

原因分析:

  • 当自动映射查询结果时,MyBatis 会获取结果中返回的列名,并在 Java 类中查找相同名字的属性(忽略大小写)
  • 这意味着如果发现了 ID 列和 id 属性,MyBatis 会将列 ID 的值赋给 id 属性
    如果数据库的字段,和 Java 对象属性一致,就自动赋值。要是不一致,就为 null

属性不一致

结果映射,数据库字段和 Java 属性不一致时,处理办法:

  1. 起别名
  2. 进行结果映射
  3. 驼峰自动转换

1. 起别名

返回来的结果对应不上
我们就可以通过起别名的方式,来将结果对应上

给列名起别名,保持别名和实体类属性名一样

Mapper 接口:

// 起别名  
@Select("SELECT id, username, password, age, gender, phone, delete_flag as deleteFlag, " +  "create_time as createTime, update_time as updateTime FROM userinfo")  
List<UserInfo> selectUserInfos();
  • SQL 语段太长,使用 + 进行字符串拼接

测试数据:

@Test  
void selectUserInfos() {  System.out.println(userInfoMapper.selectUserInfos());  
}

image.png

2. 结果映射

其实问题的本质就是 mybatis 不知道把那三个数据给谁。那我们就可以直接通过注解告诉 mybatis 把数据给谁就好了

这里我们**指定结果映射关系

// 2. 指定结果映射关系  
// 在开发中,尽量不要使用 * ,需要查询什么字段,就全部列出来  
@Results({  @Result(column = "delete_flag", property = "deleteFlag"),  @Result(column = "create_time", property = "createTime"),  @Result(column = "update_time", property = "updateTime")  
})  
@Select("SELECT * FROM userinfo")  
List<UserInfo> selectUserInfos2();
  • column 是数据库字段名;property 是 java 属性,也就是把这个字段的值,赋值给谁
  • 使用 Results 注解
    • Results 里面是多个 Result 注解
    • 数组定义:{1, 2, 3, 4}

3. 自动驼峰转换(推荐)

通常数据库使用蛇形命名法进行命名(下划线分割各个单词),而 java 属性一般遵循驼峰命名法约定。

为了在这两种命名方式之间启动自动映射,需要将 mapUnderscoreToCamelCase 设为 true

mybatis:  configuration: # 配置打印 MyBatis⽇志  map-underscore-to-camel-case: true  # 开启驼峰自动转换

驼峰命名规则:abc_xyz ==>> abcXyz

  • 表中的字段名:abc_xyz
  • 类中属性名:abcXyz

java 代码不需要做任何处理

// 3. 驼峰自动转换  
@Select("SELECT id, username, password, age, gender, phone, delete_flag, " +  "create_time, update_time FROM userinfo")  
List<UserInfo> selectUserInfo3();

image.png

http://www.dtcms.com/a/268034.html

相关文章:

  • 深度解析命令模式:将请求封装为对象的设计智慧
  • 儿童趣味记忆配对游戏
  • LeetCode 75. 颜色分类(荷兰国旗问题)
  • 一次佳能iX6780彩色喷墨打印机报5B00维修的记录
  • 【网络协议安全】任务13:ACL访问控制列表
  • 牛客周赛Round 99(Go语言)
  • 《kubernetes》k8s实战之部署PHP/JAVA网站
  • 中级统计师-经济学基础知识-第四章 国民收入核算
  • 单片机物联网应用中的 Pogopin、串口与外围模组通信技术解析
  • Java 大视界 -- Java 大数据在智能教育在线课程学习效果影响因素分析与优化设计(334)
  • Zotero中进行文献翻译【Windows11】
  • SpiceMix enables integrative single-cell spatial modeling of cell identity 文章解读
  • 【kafka-python使用学习笔记1:Python操作Kafka之环境准备(1)】
  • 2、Connecting to Kafka
  • css模块化以及rem布局
  • linux/ubuntu日志管理--/dev/log 的本质与作用
  • arm 精准总线错误与非精准总线错误
  • C#使用Qdrant实现向量存储及检索
  • 基于ARM+FPGA的光栅尺精密位移加速度测试解决方案
  • 【精密测量】基于ARM+FPGA的多路光栅信号采集方案
  • 【PyTorch 当前版本不支持 NVIDIA GeForce RTX 5060 Ti处理办法】
  • 求医十年,病因不明,ChatGPT:你看起来有基因突变
  • 群晖(Synology)存储ext4视频文件删除的恢复方法
  • Java--指定控制台System.out.println的颜色
  • 408第三季part2 - 计算机网络 - 应用层
  • 洛谷 P1005 [NOIP 2007 提高组] 矩阵取数游戏
  • CentOS-6如何配置网络设置IP? 笔记250706
  • brpc怎么解决C++静态初始化顺序难题的?
  • 2025年7月最新多语言模型研发效能分析(Gemini 2.5 vs Claude 4 vs GPT-4.1)
  • Monorepo+Turborepo+Next常问问题详解