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

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


一、什么是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.kler.cn/a/522315.html

相关文章:

  • 独立成分分析 (ICA):用于信号分离或降维
  • 二叉树的最大深度(遍历思想+分解思想)
  • Python Matplotlib库:从入门到精通
  • 跨域问题及解决方案
  • 双层Git管理项目,github托管显示正常
  • RAG技术:通过向量检索增强模型理解与生成能力
  • 【单链表算法实战】解锁数据结构核心谜题——环形链表
  • 基于PostgreSQL的自然语义解析电子病历编程实践与探索(下)
  • vim多文件操作如何同屏开多个文件
  • 软件测试丨Airtest 游戏自动化测试框架
  • 电梯系统的UML文档12
  • LangChain:使用表达式语言优化提示词链
  • 论文阅读(三):微阵列数据的图形模型和多变量分析
  • UF_CAM常用函数
  • C++ - AVL平衡二叉树
  • 一. 初始 Redis(快速入门-00)
  • KMP算法原理 JAVA实现
  • 缓存穿透和缓存雪崩
  • C#/.NET/.NET Core技术前沿周刊 | 第 23 期(2025年1.20-1.26)
  • deepseek-r1技术报告解析
  • 在RHEL 8.10上安装开源工业物联网解决方案Thingsboard 3.9
  • 【Linux】互斥锁、基于阻塞队列、环形队列的生产消费模型、单例线程池
  • “基因合作:生命演化中的共生与目的性”
  • 【2024年华为OD机试】 (A卷,200分)- 开放日活动、取出尽量少的球(JavaScriptJava PythonC/C++)
  • 6. 使用springboot做一个音乐播放器软件项目【1.0版项目完结】附带源码~
  • Android SystemUI——最近任务列表启动(十八)