目录
- 1. MyBatis是什么?
- 2.准备工作
- 2.1创建工程
- 2.2 数据准备
- 2.3 持久层代码
- 2.4 单元测试
- 3.Mybatis的增删改查操作(使用注解方式)
- 3.1 增(insert)
- 3.2 删(delete)
- 3.3 改(update)
- 3.4 查(select)
- 4.总结
1. MyBatis是什么?
MyBatis 是一个功能强大的持久层框架,专注于简化数据库操作。它通过配置文件或注解来管理 SQL 语句,支持动态 SQL,使开发更加灵活和高效。与 Hibernate 等 ORM(对象关系映射)框架不同,MyBatis 更加注重 SQL 的控制,允许开发者直接编写和优化 SQL 语句。
简单来说 MyBatis 是更简单完成程序和数据库交互的框架,也就是更简单的操作和读取数据库工具
接下来,我们就通过⼀个入门程序,让大家感受⼀下通过Mybatis如何来操作数据库。
2.准备工作
Mybatis操作数据库的步骤:
- 准备工作(创建springboot工程、数据库表准备、实体类)
- 引⼊Mybatis的相关依赖,配置Mybatis(数据库连接信息)
- 编写SQL语句(注解/XML)
- 测试
2.1创建工程
创建springboot工程,并导入 mybatis的起步依赖、mysql的驱动包。
项目工程创建完成后,自动在pom.xml文件中,导入Mybatis依赖和MySQL驱动依赖。
<!-- Mybatis 依赖包 --><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>3.0.4</version></dependency>
<!--数据库驱动--><dependency><groupId>com.mysql</groupId><artifactId>mysql-connector-j</artifactId><scope>runtime</scope></dependency>
2.2 数据准备
创建用户表(这里使用的是Navicat)
-- 创建数据库
DROP DATABASE IF EXISTS mybatis_test;CREATE DATABASE mybatis_test DEFAULT CHARACTER SET utf8mb4;-- 使用数据数据
USE mybatis_test;-- 创建表[用户表]
DROP TABLE IF EXISTS user_info;
CREATE TABLE `user_info` (`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() ON UPDATE now(),PRIMARY KEY ( `id` )
) ENGINE = INNODB DEFAULT CHARSET = utf8mb4; -- 添加用户信息
INSERT INTO mybatis_test.user_info( username, `password`, age, gender, phone )
VALUES ( 'admin', 'admin', 18, 1, '18612340001' );
INSERT INTO mybatis_test.user_info( username, `password`, age, gender, phone )
VALUES ( 'zhangsan', 'zhangsan', 18, 1, '18612340002' );
INSERT INTO mybatis_test.user_info( username, `password`, age, gender, phone )
VALUES ( 'lisi', 'lisi', 18, 1, '18612340003' );
INSERT INTO mybatis_test.user_info( username, `password`, age, gender, phone )
VALUES ( 'wangwu', 'wangwu', 18, 1, '18612340004' );
成功创建。
创建对应的实体类UserInfo
import lombok.Data;
import java.util.Date;
@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;
}
配置数据库连接字符串
Mybatis中要连接数据库,需要数据库相关参数配置
• MySQL驱动类
• 登录名
• 密码
• 数据库连接字符串
application.yml文件, 配置内容如下:
# 数据库连接配置datasource:url: jdbc:mysql://127.0.0.1:3306/mybatis_test?characterEncoding=utf8&useSSL=falseusername: rootpassword: rootdriver-class-name: com.mysql.cj.jdbc.Driver
也可以用.porperties配置文件进行配置,前面文章有介绍,本篇文章统一使用yml配置文件。
注意事项:
如果使用 MySQL 是 5.x 之前的使用的是"com.mysql.jdbc.Driver",如果是大于 5.x 使用的
是“com.mysql.cj.jdbc.Driver
2.3 持久层代码
创建一个Mapper接口(比如UserInfoMapper)
import com.sliqvers.model.UserInfo;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
import java.util.List;
// @Mapper 交给spring 进行管理@Mapper
public interface UserInfoMapper {@Select("SELECT * FROM user_info")List<UserInfo> selectAll();
}
Mybatis的持久层接口规范⼀般都叫 XxxMapper。
@Mapper注解:表⽰是MyBatis中的Mapper接口,交给Spring进行管理。
• 程序运行时, 框架会自动生成接口的实现类对象(代理对象),并给交Spring的IOC容器管理。
• @Select注解:代表的就是select查询,也就是注解对应方法的具体实现内容。
2.4 单元测试
在创建出来的SpringBoot工程中,在src下的test目录下,已经自动帮我们创建好了测试类 ,我们可以
直接使用这个测试类来进行测试。
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class UserInfoMapperTest {@Autowired
private UserInfoMapper userInfoMapper;@Testvoid selectAll() {System.out.println(userInfoMapper.selectAll());}
}
解释:
1.@Spring boot Test 加载Spring运行环境
2.@Autowired注解:为UserInfo进行赋值,否则userInfo为空,则程序报错。
3.@Test注解:这是一个测试方法,可以在测试类进行测试。
启动测试观察结果:
可以看到成功了。
idea 自动生成测试类的方法:
3.Mybatis的增删改查操作(使用注解方式)
在学习这些操作之前, 我们先来学习MyBatis日志打印
在前面的运行结果可以看到
这样子的日志并不直观,那怎么办呢?我们进行一下Mybatis的日志打印配置(在.yml
文件当中添加):
mybatis:configuration: # 配置打印 MyBatis日志log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
运行结果:
可以看到打印出来的结果比之前的打印结果更加直观了
3.1 增(insert)
增加之前:
SQL语句:
insert into user_info (username, `password`, age, gender, phone) values
("张三","张三",19,1,"1646566787");
java代码:
@Mapper
public interface UserInfoMapper {//插入@Insert("insert into user_info (username, password, age,phone) values (#{username},#{password},#{age},#{phone})")Integer insertUser(UserInfo userinfo);
}
测试代码:
@Testvoid insertUser() {UserInfo userInfo=new UserInfo();userInfo.setUsername("张三");userInfo.setPassword("张三");userInfo.setAge(19);userInfo.setPhone("1646566787");Integer result=userInfoMapper.insertUser(userInfo);System.out.println("影响行数" + result + " ,id" + userInfo.getId());}
运行结果:
刷新数据库,看是否插入成功了
可以看到插入成功了。
提出问题
我们同时看到那个数据库的id是主动自增了的,但是在控制台输出的id是null,那这个是怎么回事呢?
如果想要拿到⾃增id, 需要在Mapper接口的方法上添加一个Options的注解。
@Mapper
public interface UserInfoMapper {//插入@Options(useGeneratedKeys = true,keyProperty = "id")@Insert("insert into user_info (username, password, age,phone) values (#{username},#{password},#{age},#{phone})")Integer insertUser(UserInfo userinfo);
}
useGeneratedKeys:这会令 MyBatis使用 JDBC 的 getGeneratedKeys 方法来取出由数据库内
部生成的主键(比如:像 MySQL 和 SQL Server 这样的关系型数据库管理系统的自动递增字
段),默认值:false.
• keyProperty:指定能够唯⼀识别对象的属性,MyBatis 会使用 getGeneratedKeys 的返回值或
insert 语句的 selectKey 子元素设置它的值,默认值:未设置(unset)
我们在新增加一个数据,看是否可以在控制台获取到id的自增值。
增加之前的数据:
代码(insert):
@Testvoid insertUser() {UserInfo userInfo=new UserInfo();userInfo.setUsername("张si");userInfo.setPassword("张si");userInfo.setAge(19);userInfo.setPhone("1646566787");Integer result=userInfoMapper.insertUser(userInfo);System.out.println("影响行数" + result + " ,id:" + userInfo.getId());}
运行结果:
刷新数据库:
可以看到获取到了自增的值,至于为什么这个id是7,原因是因为我之前插入了一条数据,然把她删掉了,然后再插入的时候就是从6开始自增了,这是一个自增的知识点的断点问题。
3.2 删(delete)
SQL语句:
delete from user_info where id=7;
java代码:
@Mapper
public interface UserInfoMapper {//删除@Delete("delete from user_info where id=#{id}")void delete(Integer id);
}
测试代码:
@Testvoid delete() {userInfoMapper.delete(7);System.out.println("删除成功");}
运行结果:
打开数据库并且刷新看是否删除成功:
可以看到成功了。
3.3 改(update)
SQL语句:
update user_info set username="lisi" where id=5;
java代码:
@Mapper
public interface UserInfoMapper {//更新@Update("update user_info set username=#{username} where id=#{id}")void update(Integer id);
}
测试:
@Testvoid update() {UserInfo userInfo=new UserInfo();userInfo.setId(5);userInfo.setUsername("lisi");userInfoMapper.update(userInfo);System.out.println("更新成功");}
数据更新前:
启动项目:
运行结果:
打开数据库并且刷新查询是否更新数据成功:
可以看到更新成功了。
3.4 查(select)
SQL语句:
select * from user_info;
java代码:
@Mapper
public interface UserInfoMapper {//查询@Select("SELECT * FROM user_info")List<UserInfo> selectAll();}
测试:
@Autowired
private UserInfoMapper userInfoMapper;@Testvoid selectAll() {System.out.println(userInfoMapper.selectAll());}
运行结果:
可以看到查询成功了。
但是这里会有一个问题:我们先把Mybatis的日志配置取消掉为了便于观察:
启动项目:
我们可以看到这个这里这个没有获取到数据库表的数据。
这个原因是什么呢?
这是数据库表里的字段名字:
再看java代码当中的字段名字:
可以看到他们是有区别的。当自动映射查询结果时,MyBatis 会获取结果中返回的列名并在 Java 类中查找相同名字的属性(忽略大小写)。 这意味着如果发现了 ID 列和 id 属性,MyBatis 会将列 ID 的值赋给 id 属性那么怎么解决这个问题呢?
有三种方法:
1.起别名:
@Select("select id, username,`password`, age, gender, phone, " +"delete_flag as deleteFlag, create_time as createTime, update_time as updateTime" +" from user_info")
2.结果映射:
@Results(id = "BaseMap", value = {@Result(column = "delete_flag", property = "deleteFlag"),@Result(column = "create_time", property = "createTime"),@Result(column = "update_time", property = "updateTime")})
3.驼峰命名(推荐):
mybatis:configuration: # 配置打印 MyBatis日志map-underscore-to-camel-case: true #配置驼峰⾃动转换log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
4.总结
这篇博客详细介绍了使用MyBatis注解方式实现增删改查操作的全过程,并针对select查询时数据库数据获取不到的问题,提供了三种有效的解决方案:通过取别名、结果映射和设置驼峰大小转换。这些方法能够帮助开发者快速解决数据映射的问题,提高开发效率。下一篇博客中,我们将继续探讨MyBatis的另一配置方式——XML方式,并揭示它在增删改查操作中的独特优势。希望这篇博客能帮助大家更加全面地掌握MyBatis的核心功能,从而在实际项目中游刃有余。