前面我们使用的数据持久化层是JPA,这篇就来讲一讲MyBatis的集成使用!
项目下载地址:https://download.csdn.net/download/baiyuliang2013/13059992
GitHub:https://github.com/baiyuliang/SpringBoot
pom.xml:
<!--mybatis-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.3</version>
</dependency>
为了跟前面的User类区分,我新建了一个MbUser,表示用于MyBatis:
public class MbUser implements Serializable {
private Integer id;
private String username;
private Integer roleId;
private String nickname;
private String realname;
private String password;
private String salt;
private Integer gender;
private Integer age;
private Integer status;
private Integer createtime;
private Integer createby;
...setter/getter
}
Dao(Mapper):
package com.byl.springboottest.dao;
import com.byl.springboottest.bean.MbUser;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
import java.util.List;
@Mapper
public interface UserMapper {
@Select("select * from user")
List<MbUser> getAllUser();
@Select("select * from user where id=#{id}")
MbUser getUserById(Integer id);
}
注意sql中参数的接收方式:#{参数名}!
@Mapper表示这是一个Mapper,一般的我们为了简化Mapper的注册,都会在项目入口处开始Mapper自动扫描@MapperScan:
@MapperScan("com.byl.springboottest.dao")//开启mapper扫描
@EnableCaching//启用缓存
@SpringBootApplication
public class SpringboottestApplication {
public static void main(String[] args) {
SpringApplication.run(SpringboottestApplication.class, args);
}
}
这样就可以不用在每个Mapper类上加注解了!
以上的Mapper实现方法只是第一种方式,以直接在方法上加@Select、@Instert、@Update、@Delete并写相应sql语句的方式实现,第二种方式就是在资源文件夹下配置对应的Mapper.xml,在xml做sql查询,下面会讲到,此时dao层就完事了,我们可以来测试一下这两个接口:
@Test
void testgetAllUser(){
List<MbUser> mbUserList=userMapper.getAllUser();
System.out.println(JSON.toJSON(mbUserList));
}
@Test
void testgetUserById(){
MbUser mbUser=userMapper.getUserById(1);
System.out.println(JSON.toJSON(mbUser));
}
就是这么简单!
接下来我们用第二种方式,在资源文件夹下创建UserMapper.xml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.byl.springboottest.dao.UserMapper">
<select id="getAllUser" resultType="MbUser">
select *
from user
</select>
<select id="getUserById" resultType="MbUser">
select *
from user
where id = #{id}
</select>
</mapper>
xml中的方法名要与UserMapper类中的方法名对应,resultType返回类型,根据方法的返回类型定义,需要注意的是,无论你只返回一个对象,或者返回一个List,类型都写为所对应的对象类名或Map即可!此时,UserMapper中的sql注解就不需要了:
public interface UserMapper {
List<MbUser> getAllUser();
MbUser getUserById(Integer id);
}
application.yml中添加mybatis属性配置:
mybatis:
mapper-locations: classpath:mybatis/mapper/*Mapper.xml
type-aliases-package: com.byl.springboottest.bean
config-location: classpath:mybatis/mybatis-config.xml
- mapper-locations:配置mybatis映射文件路径;
- type-aliases-package:配置mybatis对象(javabean)文件路径;
- config-location:配置mybatis配置文件路径;
mybatis-config.xml:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<settings>
<!--打印sql-->
<setting name="logImpl" value="STDOUT_LOGGING"/>
<!--开启数据库对象字段映射自动驼峰转换-->
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
</configuration>
测试testgetAllUser()和testgetUserById():
这样mybatis就接入完成了,还是很简单的,mybatis的功能远不止于此,详细可以参考官方文档,另外mybatis还支持二级缓存功能,开启后默认是select语句使用缓存数据,即查询过一次,以后再次查询就会从缓存中取,不再走数据库了,而当执行insert、update、delete时会强制刷新缓存,下次再查询时就重新从数据库取,以保证查询的准确性!但实际开发中,可能很少去用到mybatis的二级缓存,因为他的局限性太大,并且只适合操作频率极低且没有外键关联的表,感兴趣的可以看文档了解,根据实际开发需求决定是否使用!
最后,讲一下mybatis常用的分页插件pagehelper的使用:
pom.xml引入:
<!--mybatis分页插件-->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>5.2.0</version>
</dependency>
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-autoconfigure</artifactId>
<version>1.2.5</version>
</dependency>
向mybatis-config.xml中添加配置:
<plugins>
<plugin interceptor="com.github.pagehelper.PageInterceptor">
<property name="params" value="pageNum=page;pageSize=limit;"/>
<property name="supportMethodsArguments" value="true"/>
</plugin>
</plugins>
或在application.yml中配置:
pagehelper:
supportMethodsArguments: true
pageSizeZero: true
params: pageNum=page;pageSize=limit; #自定义 分页参数(默认的是pageNum,pageSize)
更多属性参考官方文档,原理简单来讲就是,当你的查询方法中传入的有分页参数时,mybatis就会在sql语句后自动添加分页语句 limit x,x,分页参数默认为pageNum和pageSize,这里我通过相关配置,修改为了page和limit!
现在我们来写一个分页查询方法:
UserMapper.java:
List<MbUser> getList(Map<String, Object> params);
UserMapper.xml:
<select id="getList" resultType="MbUser">
select *
from user
</select>
测试:
@Test
void testgetUserListWithPage() {
Map<String, Object> params = new HashMap<>();
params.put("page", 1);
params.put("limit", 10);
List<MbUser> mbUserList = userMapper.getList(params);
System.out.println(JSON.toJSON(mbUserList));
}
page=1,limit=10,数据库里的三条全部查出来了,ok,需要了解的是,mybatis接收参数时,可以不用明确指定参数类型,它会自己判断,另外注意控制台打印数据,有两条sql语句,一条是查寻找总数,一条是查询数据集合,那如何得到这个总数呢?
通过PageInfo类:
PageInfo<Object> p = new PageInfo<>(list);
我们再次测试:
@Test
void testgetUserListWithPage() {
Map<String, Object> params = new HashMap<>();
params.put("page", 1);
params.put("limit", 10);
List<MbUser> mbUserList = userMapper.getList(params);
PageInfo<MbUser> p = new PageInfo<>(mbUserList);
System.out.println(JSON.toJSON(p.getList()));
System.out.println("Total:" + p.getTotal());
}
我们为了测试分页准确性,将limit限制为2,看是否获取到的是2条数据:
@Test
void testgetUserListWithPage() {
Map<String, Object> params = new HashMap<>();
params.put("page", 1);
params.put("limit", 2);
List<MbUser> mbUserList = userMapper.getList(params);
PageInfo<MbUser> p = new PageInfo<>(mbUserList);
System.out.println(JSON.toJSON(p.getList()));
System.out.println("Total:" + p.getTotal());
}
查询出来的是2条,但总数是3条,Ok,就是这么简单!