一、什么是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代码不用做任何改变
🙉本篇文章到此结束