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>&nbsp;
                </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语句,仍然能查询出数据库中数据。