SpringBoot整合原生Mybatis
导入mybatis的场景包
<!--mybatis场景包--> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>2.1.4</version> </dependency>
分析场景包中的自动配置类
1)核心的自动配置类,MybatisAutoConfiguration 2)绑定的资源文件类,MybatisProperties,该类与boot配置文件绑定通过,mybatis.xx 3)自动配置类中已经配置了SqlSessionFactory,使用的数据源从容器中获取的,只要我们配置了自己的 druid数据源,就可以被使用到。 4)自动配置类中导入了AutoConfiguredMapperScannerRegistrar组件,用于自动搜索mapper接口 @Import({MybatisAutoConfiguration.AutoConfiguredMapperScannerRegistrar.class}) 该类用于支持@MapperScan注解,@MapperScan注解标注在配置类上。 5)如果不使用@MapperScan注解,你也可以在每一个Mapper接口上使用@Mapper注解标注,表示对该接口进行解析 以上两种方式选其一 6)通过mybatis.config-location=classpath:mybatis/mybatis-config.xml指定全局配置文件位置 不过一般都不用写mybatis的核心配置文件,你同样可以在boot的配置文件中配置即可 通过配置mybatis.configuration.*下面的所有值,就相当于配置mybatis核心配置文件中的组件 7)通过mybatis.mapper-locations=classpath:mybatis/mapper/*.xml指定mapper映射文件的位置
使用mybatis框架步骤
1)导入mybatis场景包starter 2)编写mapper接口,标注@Mapper注解 3)编写Sql映射文件并绑定mapper接口 4)在application.yaml中指定mapper配置文件的位置,以及指定全局配置文件的信息 全局配置文件的位置可以不用指定,你可以直接配置mybatis.configuration下,默认开启状态。
注解模式的mybatis
注解模式的mybatis就是在Mapper接口上使用@Select,@insert注解标注在接口方法上, 使用@Options注解为其他注解添加属性项的,这种方式感觉一旦查询方法复杂起来,非常麻烦,注解不应该滥用
SpringBoot整合MybatisPlus
导入mybatisPlus场景包
<!-- mybatis-plus场景包 mybaitsPlus相对于mybatis在原来的基础上提供了更多的扩展功能 --> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.4.1</version> </dependency>
分析mybatisPlus自动配置类
1)核心自动配置类:MybatisPlusAutoConfiguration,参数绑定项,MybatisPlusProperties mybatis-plus: xxx,就是对mybatis-plus的定制 2)SqlSessionFactory自动配置好,底层是容器中默认的数据源,如果配置了druid就为druid数据源 3)mapperLocations自动配置好的,有默认值,classpath*:/mapper/**/*.xml 表示任意包的类路径下的所有mapper文件夹下任意路径下的所有xml都是sql映射文件, 建议以后sql映射文件(xxxMapper.xml),放在mapper目录下 4)容器中也自动配置了sqlSessionTemplate,该类就是sqlSession类 5)@Mapper标注的接口也会被自动扫描,或者在主类上使用@MapperScan指定mapper接口位置
mybatisPlus为我们提供其他的扩展功能
1)mybatisPlus提供了BaseMapper类,提供给mapper接口很多增删改查的方法, 我们的mapper接口只需要继承BaseMapper类就可拥有crud的基本功能。 2)为我们service层同样提供了很多的增删改查的方法,我们的service接口可以继承myabtisPlus提供的 IService接口,该接口有很多基本方法,我们的service实现类除了实现我们的service接口, 还可继承mybatisPlus提供的ServiceImpl类,该类同样有很多基础方法用以操作数据库 3)mybatisPlus同样对实体类进行了支持,使用@TableName注解标注在实体类上,用于指定当前的实体类 对应数据库中哪一个表,还有更多注解,待以后继续学习! 基本上导入了mybatisPlus的场景包,并不需要做任何事,mapper接口的位置配置已经被默认配置好了
MybatisPlus的分页查询案例
mybatisPlus提供了很多功能,比如分页的功能
向容器中注册mybatisPlus的分页插件(拦截器),用于对分页的支持
/*mybatis-plus分页插件*/ @Bean public MybatisPlusInterceptor mybatisPlusInterceptor() { MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); PaginationInnerInterceptor paginationInnerInterceptor = new PaginationInnerInterceptor(DbType.H2); //设置分页到最后一页,是否再次回到首页。 paginationInnerInterceptor.setOverflow(true); interceptor.addInnerInterceptor(paginationInnerInterceptor); return interceptor; }
前端页面
<!DOCTYPE html> <!--suppress ALL--> <html lang="zh-CN" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>用户分页查询</title> <style> li{ display: inline; padding-right: 10px; } </style> </head> <body> <table align="center" border="1"> <thead> <tr> <th>用户名</th> <th>密码</th> <th>邮箱</th> <th>生日</th> </tr> </thead> <tbody> <tr th:each="user:${page.records}"> <td th:text="${user.username}"></td> <td th:text="${user.password}"></td> <td th:text="${user.email}"></td> <td th:text="${user.birthday}"></td> </tr> </tbody> </table> <div align="center" th:border="2"> <ul style="padding: 0;"> <li>当前页码:[[${page.current}]]</li> <li>总页码:[[${page.pages}]]</li> <li>总记录数:[[${page.total}]]</li> <!--将页码遍历,从1到总页码--> <li th:each="num:${#numbers.sequence(1,page.pages)}"> <a th:href="@{/getUsers(pageNum=${num})}">[[${num}]]</a> </li> <!--thymeleaf携带参数使用小括号()--> <li><a th:href="@{/getUsers}">首页</a></li> <li><a th:href="@{/getUsers(pageNum=${page.current}-1)}">上一页</a></li> <li><a th:href="@{/getUsers(pageNum=${page.current}+1)}">下一页</a></li> </ul> </div> </body> </html>
后端控制器方法
@Controller public class UserController { @Autowired UserService userService; @ResponseBody @RequestMapping("/getUser") public User getUserByEmail(@RequestParam("email") String email){ return userService.getUserByEmail(email); } @RequestMapping("/getUsers") public String getUsers(Model model, @RequestParam(value = "pageNum",defaultValue = "1")Long pageNum){ //pageNum是前端传递过来的值,2表示每页查2条数据 Page<User> page = new Page<User>(pageNum,2); Page<User> userPage = userService.page(page, null); model.addAttribute("page",userPage); return "userInfo"; } }
Service接口
public interface UserService extends IService<User> { public User getUserByEmail(String email); }
Service接口实现类
@Service @Slf4j //泛型中,UserMapper表示mapper接口,User表示封装后的类型 public class UserServiceImpl extends ServiceImpl<UserMapper,User> implements UserService { @Autowired UserMapper userMapper; public User getUserByEmail(String email){ log.info("UserService:{}",email); return userMapper.getUserByEmail(email); } }
Mappe接口
@Mapper @Component public interface UserMapper extends BaseMapper<User> { User getUserByEmail(String email); }
Mapper映射文件
<?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"> <!-- namespace:接口的全类名。world.keyi.dao.UserDao id:接口中要被实现的方法名 resultType:接口方法的返回值类型,全类名,增删改不用写返回值类型 mybatis自动判断,如果是数字,返回int类型,如果是boolean,影响0行返回false,否则返回true --> <mapper namespace="world.keyi.boot.dao.UserMapper"> <!--通过邮箱查询用户--> <select id="getUserByEmail" resultMap="user"> select * from tb_user where email=#{email} </select> </mapper>
此时实验调用的是/getUsers方法,使用的是mybatisPlus提供的ServiceImpl中的方法
所以Mapper接口和Mapper映射文件中没有写任何sql语句,仍然能查询出数据库中数据。