MyBatis 简介
MyBatis 是⼀个持久层框架,用于简化 JDBC 的开发
持久层指的就是持久化操作的层,通常指数据访问层 (dao),是用来操作数据库的
- 字段名统一小写,单词之间使用下划线 _ 分割
- 建表字段必须包含:自增字段、更新时间和创建时间,不管有没有用到这些字段
单元测试
SpringBoot 工程中 src 的 test 目录下已经自动创建好一个测试类(绿色背景部分),我们可以直接用这个测试类来进行测试
测试类上添加了注解 @SpringBootTest,它在运行时会自动加载 Spring 的运行环境我们通过 @Autowired 这个注解, 注入要测试的类, 就可以进行测试了
MyBatis 基础操作
1. 添加依赖:mybatis、MySQL 驱动
在新建项目的时候勾选这两个
2. 配置数据库
添加下面这段 yml 的配置文件
spring:
datasource:
url: jdbc:mysql://127.0.0.1:3306/mybatis_test?characterEncoding=utf8&useSSL=false
username: root
password: 1234
driver-class-name: com.mysql.cj.jdbc.Driver
mvc:
favicon:
enable: false
profiles: #多平台配置
active: dev
# 设置 Mybatis 的 xml 保存路径
mybatis:
mapper-locations: classpath:mapper/*Mapper.xml
configuration: # 配置打印 MyBatis 执行的 SQL
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
map-underscore-to-camel-case: true #自动驼峰转换
# 配置打印 MyBatis 执行的 SQL
logging:
file:
name: logs/springboot.log
logback:
rollingpolicy:
max-file-size: 1KB
file-name-pattern: ${LOG_FILE}.%d{yyyy-MM-dd}.%i
level:
com:
example:
demo: debug
3. 编写持久层的代码,具体见下文
打印日志
添加下面的配置信息
mybatis:
configuration: # 配置打印 MyBatis ⽇志
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
传递参数
假设数据库中有如下四条记录,现在要查找数据库中年龄为 18 的人
@Mapper
public interface UserInfoMapper {
//根据 age 查询
@Select("select username,password,age,gender,phone from userinfo where age = #{age}")
public List<UserInfo> queryByAge(Integer age);
}
@Mapper
public interface UserInfoMapper {
//根据姓名查询
@Select("select username,password,age,gender,phone from userinfo where username = #{name}")
public List<UserInfo> queryByName(@Param("name") String name);
}
@SpringBootTest
class UserInfoMapperTest {
@Autowired
private UserInfoMapper userInfoMapper;
@Test
void queryByName() {
List<UserInfo> userInfoList = userInfoMapper.queryByName("zhangsan");
System.out.println(userInfoList);
}
}
运行结果:
curd
- 新增数据
@Mapper
public interface UserInfoMapper {
@Insert("insert into userinfo(username,password,age,gender,phone) " +
"values(#{username},#{password},#{age},#{gender},#{phone})")
public Integer insert(UserInfo userInfo);
}
@SpringBootTest
class UserInfoMapperTest {
@Autowired
private UserInfoMapper userInfoMapper;
@Test
void insert() {
UserInfo userInfo = new UserInfo();
userInfo.setUsername("Script");
userInfo.setPassword("Script");
userInfo.setGender(1);
userInfo.setAge(24);
userInfo.setPhone("11111111111");
userInfoMapper.insert(userInfo);
}
}
运行结果:
可以看到这条记录已经顺利插入:
2. 删除数据
delete from userinfo where...
@Mapper
public interface UserInfoMapper {
//根据 id 删除数据
@Delete("delete from userinfo where id = #{id}")
public Integer delete(Integer id);
}
@SpringBootTest
class UserInfoMapperTest {
@Autowired
private UserInfoMapper userInfoMapper;
@Test
void delete() {
userInfoMapper.delete(2);
}
}
删除前:
删除后:
3. 修改
SQL 语句如下:
update userinfo set username="zhaoliu" where id=5
@Update("update userinfo set username=#{username} where id=#{id}")
void update(UserInfo userInfo);
4. 查询
查询的时候,我们会发现一些字段为空,也就是说它们是没有赋值的。只有 Java 对象属性和数据库字段一模一样时才会赋值(忽略大小写)
@Select("select id, username, `password`, age, gender, phone, delete_flag,
create_time, update_time from userinfo")
List<UserInfo> queryAllUser();
从图中可以看出,下面这三个字段查询结果都为空
这是因为当自动映射查询结果时,MyBatis 会获取数据库中的对应列名并在Java类中查找同名的属性(忽略大小写)然后赋值。比如说对于 ID 列和 id 属性,MyBatis 会将 ID 这一列的值赋给 id 属性
有三种解决办法:
1. 起别名
在SQL语句中给列名起别名,使它和实体类属性名⼀样
@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();
注意:发现 SQL 语句太长时,可以用 + 把每部分拼接起来,每部分之间记得留空格
2. 结果映射
就这样:
@Select("select id, username, `password`, age, gender, phone, delete_flag,
create_time, update_time from userinfo")
@Results({
@Result(column = "delete_flag",property = "deleteFlag"),
@Result(column = "create_time",property = "createTime"),
@Result(column = "update_time",property = "updateTime")
})
public List<UserInfo> queryAllUser2();
3. 使用驼峰命名
mybatis:
configuration: # 配置打印 MyBatis 执行的 SQL
map-underscore-to-camel-case: true #配置驼峰自动转换