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

ops/2025/2/5 6:58:10/


一、什么是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.ppmy.cn/ops/155802.html

相关文章

[MySQL]事务的理论、属性与常见操作

目录 一、事物的理论 1.什么是事务 2.事务的属性&#xff08;ACID&#xff09; 3.再谈事务的本质 4.为什么要有事务 二、事务的操作 1.事务的支持版本 2.事务的提交模式 介绍 自动提交模式 手动提交模式 3.事务的操作 4.事务的操作演示 验证事务的回滚 事务异常…

小程序设计和开发:如何研究同类型小程序的优点和不足。

一、确定研究目标和范围 明确研究目的 在开始研究同类型小程序之前&#xff0c;首先需要明确研究的目的。是为了改进自己的小程序设计和开发&#xff0c;还是为了了解市场趋势和用户需求&#xff1f;不同的研究目的会影响研究的方法和重点。例如&#xff0c;如果研究目的是为了…

Cocos Creator 3.8 2D 游戏开发知识点整理

目录 Cocos Creator 3.8 2D 游戏开发知识点整理 1. Cocos Creator 3.8 概述 2. 2D 游戏核心组件 (1) 节点&#xff08;Node&#xff09;与组件&#xff08;Component&#xff09; (2) 渲染组件 (3) UI 组件 3. 动画系统 (1) 传统帧动画 (2) 动画编辑器 (3) Spine 和 …

Android学习19 -- 手搓App

1 前言 之前工作中&#xff0c;很多时候要搞一个简单的app去验证底层功能&#xff0c;Android studio又过于重型&#xff0c;之前用gradle&#xff0c;被版本匹配和下载外网包折腾的堪称噩梦。所以搞app都只有找应用的同事帮忙。一直想知道一些简单的app怎么能手搓一下&#x…

基于SpringBoot养老院平台系统功能实现一

一、前言介绍&#xff1a; 1.1 项目摘要 随着全球人口老龄化的不断加剧&#xff0c;养老服务需求日益增长。特别是在中国&#xff0c;随着经济的快速发展和人民生活水平的提高&#xff0c;老年人口数量不断增加&#xff0c;对养老服务的质量和效率提出了更高的要求。传统的养…

oracle: 表分区>>范围分区,列表分区,散列分区/哈希分区,间隔分区,参考分区,组合分区,子分区/复合分区/组合分区

分区表 是将一个逻辑上的大表按照特定的规则划分为多个物理上的子表&#xff0c;这些子表称为分区。 分区可以基于不同的维度&#xff0c;如时间、数值范围、字符串值等&#xff0c;将数据分散存储在不同的分区 中&#xff0c;以提高数据管理的效率和查询性能&#xff0c;同时…

Nacos 的介绍和使用

1. Nacos 的介绍和安装 与 Eureka 一样&#xff0c;Nacos 也提供服务注册和服务发现的功能&#xff0c;Nacos 还支持更多元数据的管理&#xff0c; 同时具备配置管理功能&#xff0c;功能更丰富。 1.1. windows 下的安装和启动方式 下载地址&#xff1a;Release 2.2.3 (May …

2月3日星期一今日早报简报微语报早读

2月3日星期一&#xff0c;农历正月初六&#xff0c;早报#微语早读。 1、多个景区发布公告&#xff1a;售票数量已达上限&#xff0c;请游客合理安排行程&#xff1b; 2、2025春节档总票房破70亿&#xff0c;《哪吒之魔童闹海》破31亿&#xff1b; 3、美宣布对中国商品加征10…