【JavaEE】Spring(5):Mybatis(上)

news2025/1/31 6:15:26


一、什么是Mybatis

Mybatis是一个持久层的框架,它用来更简单的完成程序和数据库之间的交互,也就是更简单的操作和读取数据库中的数据

在讲解Mybatis之前,先要进行一些准备工作:

1. 为项目添加 Mybatis 相关依赖

2. 创建用户表以及对应的实体类

-- 创建数据库
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' );

实体类中的属性名要表中的字段名一一对应

@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;
}

3. 配置数据库连接

如果使⽤ MySQL 是 5.x 之前的使用的是"com.mysql.jdbc.Driver",如果是大于 5.x 使⽤的
是“com.mysql.cj.jdbc.Driver”
 

二、Mybatis基础操作

2.1打印日志

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

mybatis:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl #??sql??

2.2 参数传递

比如要查询id为3的用户信息,就需要在方法中添加一个参数,然后将这个参数告诉SQL语句,通过 #{} 的方式将参数传递给SQL

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

编写测试代码:

@Test
void queryById() {
    UserInfo userInfo = userInfoMapper.queryById(3);
    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);

2.3 增(Insert)

Mapper接口:

@Insert("insert into userinfo (username, `password`, age, gender, phone) values (#{username},#{password},#{age},#{gender},#{phone})")
Integer insert(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);
}

Updates:1就代表影响了一行数据,说明插入成功

如果对对象采用@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);

返回主键

默认情况,插入方法返回的是影响行数,如果想要拿到自增id,可以在方法上方添加@Options注解

@Options(useGeneratedKeys = true, keyProperty = "id")
@Insert("insert into userinfo (username, `password`, age, gender, phone) values (#{username},#{password},#{age},#{gender},#{phone})")
Integer insert(UserInfo userInfo); //返回的是影响的行数
  • useGeneratedKeys:这会令 MyBatis 使用JDBC的getGeneratedKeys方法来取出由数据库内部生成的主键
  • keyProperty:指定能够唯⼀识别对象的属性,MyBatis会使用 getGeneratedKeys 的返回值或insert语句的selectKey子元素设置它的值
     

测试数据

@Test
void insert() {
    UserInfo userInfo = new UserInfo();
    userInfo.setUsername("sans");
    userInfo.setPassword("sans");
    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 指定的属性中
 

2.4 删(Delete)

Mapper接口:

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

测试代码:

@Test
void delete() {
    Integer row = userInfoMapper.delete(6);
    System.out.println(row);
}

2.5 改(Update)

Mapper接口:

@Update("update userinfo set username = #{username} where id = #{id}")
Integer update (String username, Integer id);

测试代码:

@Test
void update() {
    Integer row = userInfoMapper.update("sans", 5);
    System.out.println(row);
}

2.6 查(Select)

查询所有用户信息:

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

测试代码:

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

可以看到有部分值为null,这是因为在自动结果映射时,Mybatis会获取结果中返回的列名并在Java类中查找相同的属性名并赋值(忽略大小写)如果发现了表中的ID列和实体类中的id属性,此时Mybatis就会把ID列的值赋给id属性

这里我们的列和属性名分别如下:

由于无法正确结果映射,所以没有进行赋值

解决方法:

2.6.1 起别名

使用 as 给列名起别名,让列名和属性名相同

@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();

此时再运行测试代码:

都已正确赋值

2.6.2 结果映射

@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();

通过id可以给@Results起别名,其他方法使用@ResultMap就可以复用该映射关系

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

2.6.3 开启驼峰命名

通过在配置文件中配置,将列名转换为驼峰命名,驼峰命名也是Java属性遵循的命名约定

mybatis:
  configuration:
    map-underscore-to-camel-case: true

Java代码不用做任何改变


🙉本篇文章到此结束

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

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

相关文章

记录 | MaxKB创建本地AI智能问答系统

目录 前言一、重建MaxKBStep1 复制路径Step2 删除MaxKBStep3 创建数据存储文件夹Step4 重建 二、创建知识库Step1 新建知识库Step2 下载测试所用的txtStep3 上传本地文档Step4 选择模型补充智谱的API Key如何获取 Step5 查看是否成功 三、创建应用Step1 新建应用Step2 配置AI助…

【Spring】Spring启示录

目录 前言 一、示例程序 二、OCP开闭原则 三、依赖倒置原则DIP 四、控制反转IOC 总结 前言 在软件开发的世界里&#xff0c;随着项目的增长和需求的变化&#xff0c;如何保持代码的灵活性、可维护性和扩展性成为了每个开发者必须面对的问题。传统的面向过程或基于类的设计…

八股——Java基础(四)

目录 一、泛型 1. Java中的泛型是什么 ? 2. 使用泛型的好处是什么? 3. Java泛型的原理是什么 ? 什么是类型擦除 ? 4.什么是泛型中的限定通配符和非限定通配符 ? 5. List和List 之间有什么区别 ? 6. 可以把List传递给一个接受List参数的方法吗&#xff1f; 7. Arra…

基于STM32的循迹小车设计与实现

1 系统方案设计 根据系统设计功能&#xff0c;展开基于STM32的循迹小车设计&#xff0c;整体设计框图如图2.1所示。系统采用STM32单片机作为控制器,通过L298驱动器控制两个直流电机实现对小车的运动控制&#xff0c;两路红外模块实现黑线的检测&#xff0c;HC-SR04超声波模块实…

AI刷题-蛋糕工厂产能规划、优质章节的连续选择

挑两个简单的写写 目录 一、蛋糕工厂产能规划 问题描述 输入格式 输出格式 解题思路&#xff1a; 问题理解 数据结构选择 算法步骤 关键点 最终代码&#xff1a; 运行结果&#xff1a;​编辑 二、优质章节的连续选择 问题描述 输入格式 输出格式 解题思路&a…

达梦拷贝DM_HOME的复制安装

近期一个项目需求&#xff0c;需要在没有安装包的情况下&#xff0c;将达梦数据库安装到虚机上&#xff08;生产机上安装了达梦&#xff09;&#xff0c;故采用直接打包生产机DM_HOME的方式拷贝至虚机&#xff0c;再依次执行达梦的部分指令完成安装。以下为验证的步骤&#xff…

网络工程师 (3)指令系统基础

一、寻址方式 &#xff08;一&#xff09;指令寻址 顺序寻址&#xff1a;通过程序计数器&#xff08;PC&#xff09;加1&#xff0c;自动形成下一条指令的地址。这是计算机中最基本、最常用的寻址方式。 跳跃寻址&#xff1a;通过转移类指令直接或间接给出下一条指令的地址。跳…

第一届“启航杯”网络安全挑战赛WP

misc PvzHE 去这个文件夹 有一张图片 QHCTF{300cef31-68d9-4b72-b49d-a7802da481a5} QHCTF For Year 2025 攻防世界有一样的 080714212829302316092230 对应Q 以此类推 QHCTF{FUN} 请找出拍摄地所在位置 柳城 顺丰 forensics win01 这个软件 云沙盒分析一下 md5 ad4…

DeepSeek R1与OpenAI o1深度对比

文章目录 引言技术原理DeepSeek R1OpenAI o1 性能表现官方数据推理任务知识密集型任务通用能力 价格对比应用场景科研与技术开发自然语言处理&#xff08;NLP&#xff09;企业智能化升级教育与培训数据分析与智能决策 部署与集成DeepSeek R1OpenAI o1 伦理考量DeepSeek R1OpenA…

图漾Halcon版本SDK使用教程【V1.1.0新版本】

1.下载并安装 Halcon 1.1 下载Halcon软件 在 Halcon 官网(https://www.mvtec.com/downloads) 下载 Halcon (Windows 版) 安装包&#xff0c;并根据官方文档安装 Halcon&#xff0c;下载HALCON24.11Progress-Steady。 1.2 安装Halcon 1.解压HALCON 24.11.1.0的安装包压缩文件…

20.Word:小谢-病毒知识的科普文章❗【38】

目录 题目​ NO1.2.3文档格式 NO4.5 NO6.7目录/图表目录/书目 NO8.9.10 NO11索引 NO12.13.14 每一步操作完&#xff0c;确定之后记得保存最后所有操作完记得再次删除空行 题目 NO1.2.3文档格式 样式的应用 选中应用段落段落→开始→选择→→检查→应用一个一个应用ctr…

算法题(49):反转链表II

审题&#xff1a; 需要我们对指定范围的链表进行反转&#xff0c;并返回反转后链表的头结点 思路&#xff1a; 方法一&#xff1a;vector法 我们先遍历一次链表&#xff0c;并把数据对应的存在数组中&#xff0c;然后利用数组的reverse方法进行反转数据&#xff0c;最后再遍历一…

基于SpringBoot多数据源解决方案

最近在学习SpringBoot的时候&#xff0c;需要同时用两个不同的数据库连接服务&#xff0c;在网上学习了之后&#xff0c;下文以连接一个MySQL数据库和一个SqlServer数据库为例。 配置数据源连接信息 在配置文件中&#xff0c;配置对应的数据库连接信息&#xff0c;相比于单数…

通过案例研究二项分布和泊松分布之间关系(2)

通过案例研究二项分布和泊松分布之间关系 2. 汽车出事故的概率p与保险公司盈利W之间的关系3.通过遗传算法多次迭代计算控制p为多少时公司盈利最大(1) 计算过程(2) 结果及分析(计算过程详见附录二程序) 4.改变思路求解固定p为0.01时,保险费用如何设置公司可获得最大利润(1)计算过…

RISC-V读书笔记4

目录 乘法与除法 RV32F 和 RV32D&#xff1a;单精度和双精度浮点数 原子操作 压缩指令 向量 乘法与除法 RV32M属于扩展的指令&#xff0c;主要扩展的就是便捷的乘法和除法指令。 除法&#xff1a; 商 (被除数− 余数) 除数 被除数 除数 商 余数 余数 被除数− (商 …

【Uniapp-Vue3】request各种不同类型的参数详解

一、参数携带 我们调用该接口的时候需要传入type参数。 第一种 路径名称?参数名1参数值1&参数名2参数值2 第二种 uni.request({ url:"请求路径", data:{ 参数名:参数值 } }) 二、请求方式 常用的有get&#xff0c;post和put 三种&#xff0c;默认是get请求。…

大数据学习之SCALA分布式语言三

7.集合类 111.可变set一 112.可变set二 113.不可变MAP集合一 114.不可变MAP集合二 115.不可变MAP集合三 116.可变map一 package com . itbaizhan . chapter07 //TODO 2. 使用 mutable.Map 前导入如下包 import scala . collection . mutable // 可变 Map 集合 object Ma…

基于微信小程序的电子商城购物系统设计与实现(LW+源码+讲解)

专注于大学生项目实战开发,讲解,毕业答疑辅导&#xff0c;欢迎高校老师/同行前辈交流合作✌。 技术范围&#xff1a;SpringBoot、Vue、SSM、HLMT、小程序、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、安卓app、大数据、物联网、机器学习等设计与开发。 主要内容&#xff1a;…

2000-2020年各省第二产业增加值占GDP比重数据

2000-2020年各省第二产业增加值占GDP比重数据 1、时间&#xff1a;2000-2020年 2、来源&#xff1a;国家统计局、统计年鉴 3、指标&#xff1a;行政区划代码、地区名称、年份、第二产业增加值占GDP比重 4、范围&#xff1a;31省 5、指标解释&#xff1a;第二产业增加值占GDP比重…

【Docker】Docker入门了解

文章目录 Docker 的核心概念Docker 常用命令示例&#xff1a;构建一个简单的 C 应用容器1. 创建 C 应用2. 创建 Dockerfile3. 构建镜像4. 运行容器 Docker 优势学习 Docker 的下一步 **一、Docker 是什么&#xff1f;****为什么 C 开发者需要 Docker&#xff1f;** **二、核心概…