0
点赞
收藏
分享

微信扫一扫

125 mybatis手写分页插件

代码敲到深夜 2021-09-21 阅读 54

1,项目结构

https://github.com/wangjin123456/2020/tree/master/springboot/xuexi/mybatis

2,pom


<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.6.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.taotao</groupId>
    <artifactId>mybatis</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>mybatis</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!--mybatis-->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>1.3.2</version>
        </dependency>
        <!--阿里巴巴连接池-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.0.9</version>
        </dependency>

        <!-- mysql -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.47</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>


3,yml

mybatis:
  mapper-locations:  classpath:/mapper/*Dao.xml
  type-aliases-package:  com.taotao.mybatis.entity
server:
  port:  8089
spring:
  datasource:
    url: jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC&useSSL=false
    username: root
    password: root
    type: com.alibaba.druid.pool.DruidDataSource
    driver-class-name: com.mysql.jdbc.Driver
logging:
  level:
    com.taotao.mybatis.dao: debug



4,实体类 user

package com.taotao.mybatis.entity;

import java.io.Serializable;

/**
 * (User)实体类
 *
 * @author makejava
 * @since 2020-04-03 10:56:23
 */
public class User implements Serializable {
    private static final long serialVersionUID = -51863096759936799L;
    
    private Integer id;
    
    private String username;
    
    private String sex;
    
    private Object birthday;
    
    private String address;
    
    private String password;


    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public Object getBirthday() {
        return birthday;
    }

    public void setBirthday(Object birthday) {
        this.birthday = birthday;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

}

5,分页工具类
PageInfo

package com.taotao.mybatis.plung;

import java.io.Serializable;

/**
 * @author tom
 * @date 2020/4/3 0003 15:38
 */
public class PageInfo implements Serializable {
    private  static  final  long serialVersionUID =1L;
    private  int totalNumber;//当前表中总的数据
    private  int currentPage; //当前页的位置
    private int totalPage;//总页数
    private int pageSize;//页面大小
    private int startIndex;//检索的起始位置
    private  int totalSelect;//检索的总条目



    public int getTotalNumber() {
        return totalNumber;
    }

    public PageInfo setTotalNumber(int totalNumber) {
        this.totalNumber = totalNumber;
        return this;
    }

    public int getCurrentPage() {
        return currentPage;
    }

    public PageInfo setCurrentPage(int currentPage) {
        this.currentPage = currentPage;
        return this;
    }

    public int getTotalPage() {
        return totalPage;
    }

    public PageInfo setTotalPage(int totalPage) {
        this.totalPage = totalPage;
        return this;
    }

    public int getPageSize() {
        return pageSize;
    }

    public PageInfo setPageSize(int pageSize) {
        this.pageSize = pageSize;
        return this;
    }

    public int getStartIndex() {
        return startIndex;
    }

    public PageInfo setStartIndex(int startIndex) {
        this.startIndex = startIndex;
        return this;
    }

    public int getTotalSelect() {
        return totalSelect;
    }

    public PageInfo setTotalSelect(int totalSelect) {
        this.totalSelect = totalSelect;
        return this;
    }

    //计算
    public  void count(){
        int totalPageTemp =this.totalNumber / this.pageSize;
        int plus=(this.totalNumber % this.pageSize)== 0 ?0: 1;
        totalPageTemp= totalPageTemp + plus;
        if(totalPageTemp <=0){
            totalPageTemp=1;
        }
        this.totalPage =totalPageTemp;//总页数
        if(this.totalPage < this.currentPage){
            this.currentPage=this.totalPage;
        }
        if(this.currentPage <1){
            this.currentPage=1;
        }
        this.startIndex=(this.currentPage -1) * this.pageSize;//
        this.totalSelect =this.pageSize; //检索数量等于页面大小
    }
}



AllenPagePlung

package com.taotao.mybatis.plung;


import org.apache.ibatis.executor.parameter.ParameterHandler;
import org.apache.ibatis.executor.statement.StatementHandler;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.plugin.*;
import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.reflection.SystemMetaObject;
import org.springframework.stereotype.Component;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.Map;
import java.util.Properties;

/**
 * 分页插件
 * @author tom
 * @date 2020/4/3 0003 14:36
 */
@Intercepts({@Signature(
        type= StatementHandler.class,
        method ="prepare",
        args = {Connection.class,Integer.class}
)})
@Component
public class AllenPagePlung implements Interceptor {
    //插件核心业务
    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        /**
         * 1,拿到原始的sql语句
         * 2,修改原始的sql语句,增加分页 select * from user  limit 0,3
         * 3,执行jdbc 去查询总数
         */
        StatementHandler statementHandler=(StatementHandler)invocation.getTarget();
           //拿到原始sql语句
        BoundSql boundSql=statementHandler.getBoundSql();
        String sql=boundSql.getSql();
        System.out.println("原始sql:"+sql);
        //分页参数获取
        Object paramObj=boundSql.getParameterObject();
        //statementHandler 转换成 metaObject
        MetaObject metaObject= SystemMetaObject.forObject(statementHandler);
        //上下文 spring context.getBean("userbean")
        MappedStatement mappedStatement=(MappedStatement)metaObject.getValue("delegate.mappedStatement");
        //读取mapper 接口中的方法名称 selectUserByPage
        String mapperMethodName =mappedStatement.getId();
        //以ByPage 结尾的做分页操作
         if(mapperMethodName.matches(".*ByPage$")){
             Map<String,Object> params=(Map<String,Object>)paramObj;
              PageInfo pageInfo=(PageInfo)params.get("page");
              //select * from  user
              String countSql="select count(0) from ("+sql +") a";
             System.out.println("查询总数的sql:" + countSql);
              //执行jdbc 操作
             Connection connection=(Connection)invocation.getArgs()[0];
             PreparedStatement  countStatement=connection.prepareStatement(countSql);
             ParameterHandler parameterHandler=(ParameterHandler)metaObject.getValue("delegate.parameterHandler");
              parameterHandler.setParameters(countStatement);
             ResultSet rs=countStatement.executeQuery();
             if(rs.next()){
                 pageInfo.setTotalNumber(rs.getInt(1));
             }
             rs.close();
             countStatement.close();
            //改造sql  limit
             String pageSql= this.generatePageSql(sql, pageInfo);
             System.out.println("分页:"+pageSql);
             metaObject.setValue("delegate.boundSql.sql",pageSql);

         }
         //把执行流程交给 mybatis
        return invocation.proceed();
    }
     //把自定义的插件加入到mybatis中
    @Override
    public Object plugin(Object target) {
        return Plugin.wrap(target,this);
    }


    //设置属性
    @Override
    public void setProperties(Properties properties) {

    }


    //根据原始sql  生成limit sql
    public String generatePageSql(String sql, PageInfo pageInfo){
        StringBuilder sb=new StringBuilder();
        sb.append(sql);
        sb.append(" limit " + pageInfo.getCurrentPage()+ ","+ pageInfo.getPageSize());
        return  sb.toString();

    }
}



6, controller


package com.taotao.mybatis.controller;

import com.taotao.mybatis.entity.User;
import com.taotao.mybatis.plung.PageInfo;
import com.taotao.mybatis.service.UserService;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.List;

/**
 * (User)表控制层
 *
 * @author makejava
 * @since 2020-04-03 10:56:27
 */
@RestController
@RequestMapping("user")
public class UserController {
    /**
     * 服务对象
     */
    @Resource
    private UserService userService;

    /**
     * 通过主键查询单条数据
     *
     * @param id 主键
     * @return 单条数据
     */
    @GetMapping("selectOne")
    public User selectOne(Integer id) {
        return this.userService.queryById(id);
    }

    @GetMapping("ByPage")
    public List<User> ByPage(){
        return  this.userService.ByPage();

    }
}

7,service

package com.taotao.mybatis.service;

import com.taotao.mybatis.entity.User;
import java.util.List;

/**
 * (User)表服务接口
 *
 * @author makejava
 * @since 2020-04-03 10:56:26
 */
public interface UserService {

    /**
     * 通过ID查询单条数据
     *
     * @param id 主键
     * @return 实例对象
     */
    User queryById(Integer id);

    /**
     * 查询多条数据
     *
     * @param offset 查询起始位置
     * @param limit 查询条数
     * @return 对象列表
     */
    List<User> queryAllByLimit(int offset, int limit);

    /**
     * 新增数据
     *
     * @param user 实例对象
     * @return 实例对象
     */
    User insert(User user);

    /**
     * 修改数据
     *
     * @param user 实例对象
     * @return 实例对象
     */
    User update(User user);

    /**
     * 通过主键删除数据
     *
     * @param id 主键
     * @return 是否成功
     */
    boolean deleteById(Integer id);

    List<User> ByPage();
}

8,serviceimpl

package com.taotao.mybatis.service.impl;

import com.taotao.mybatis.entity.User;
import com.taotao.mybatis.dao.UserDao;
import com.taotao.mybatis.plung.PageInfo;
import com.taotao.mybatis.service.UserService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * (User)表服务实现类
 *
 * @author makejava
 * @since 2020-04-03 10:56:27
 */
@Service("userService")
public class UserServiceImpl implements UserService {
    @Resource
    private UserDao userDao;

    /**
     * 通过ID查询单条数据
     *
     * @param id 主键
     * @return 实例对象
     */
    @Override
    public User queryById(Integer id) {
        return this.userDao.queryById(id);
    }

    /**
     * 查询多条数据
     *
     * @param offset 查询起始位置
     * @param limit 查询条数
     * @return 对象列表
     */
    @Override
    public List<User> queryAllByLimit(int offset, int limit) {
        return this.userDao.queryAllByLimit(offset, limit);
    }

    /**
     * 新增数据
     *
     * @param user 实例对象
     * @return 实例对象
     */
    @Override
    public User insert(User user) {
        this.userDao.insert(user);
        return user;
    }

    /**
     * 修改数据
     *
     * @param user 实例对象
     * @return 实例对象
     */
    @Override
    public User update(User user) {
        this.userDao.update(user);
        return this.queryById(user.getId());
    }

    /**
     * 通过主键删除数据
     *
     * @param id 主键
     * @return 是否成功
     */
    @Override
    public boolean deleteById(Integer id) {
        return this.userDao.deleteById(id) > 0;
    }

    @Override
    public List<User> ByPage() {
        PageInfo pageInfo=new PageInfo();
        pageInfo.setCurrentPage(2);//第几页
        pageInfo.setPageSize(3);//一页多少条数据
        Map<String,Object> map=new HashMap<>();
        map.put("page",pageInfo);
        return this.userDao.ByPage(map);
    }
}

9,dao

package com.taotao.mybatis.dao;

import com.taotao.mybatis.entity.User;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
import java.util.Map;

/**
 * (User)表数据库访问层
 *
 * @author makejava
 * @since 2020-04-03 10:56:25
 */
@Mapper
public interface UserDao {

    /**
     * 通过ID查询单条数据
     *
     * @param id 主键
     * @return 实例对象
     */
    User queryById(Integer id);

    /**
     * 查询指定行数据
     *
     * @param offset 查询起始位置
     * @param limit 查询条数
     * @return 对象列表
     */
    List<User> queryAllByLimit(@Param("offset") int offset, @Param("limit") int limit);


    /**
     * 通过实体作为筛选条件查询
     *
     * @param user 实例对象
     * @return 对象列表
     */
    List<User> queryAll(User user);

    /**
     * 新增数据
     *
     * @param user 实例对象
     * @return 影响行数
     */
    int insert(User user);

    /**
     * 修改数据
     *
     * @param user 实例对象
     * @return 影响行数
     */
    int update(User user);

    /**
     * 通过主键删除数据
     *
     * @param id 主键
     * @return 影响行数
     */
    int deleteById(Integer id);

    List<User> ByPage(Map<String, Object> map);
}

10 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>
<plugins>
    <plugin interceptor=" com.taotao.mybatis.plung.AllenPagePlung">
      <property name="type" value="mysql"/>
    </plugin>
</plugins>



    
</configuration>

userDao.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.taotao.mybatis.dao.UserDao">

    <resultMap type="com.taotao.mybatis.entity.User" id="UserMap">
        <result property="id" column="id" jdbcType="INTEGER"/>
        <result property="username" column="username" jdbcType="VARCHAR"/>
        <result property="sex" column="sex" jdbcType="VARCHAR"/>
        <result property="birthday" column="birthday" jdbcType="OTHER"/>
        <result property="address" column="address" jdbcType="VARCHAR"/>
        <result property="password" column="password" jdbcType="VARCHAR"/>
    </resultMap>

    <select id="ByPage" resultMap="UserMap">
        select
                 *
        from test.user

    </select>
    <!--查询单个-->
    <select id="queryById" resultMap="UserMap">
        select
          id, username, sex, birthday, address, password
        from test.user
        where id = #{id}
    </select>

    <!--查询指定行数据-->
    <select id="queryAllByLimit" resultMap="UserMap">
        select
          id, username, sex, birthday, address, password
        from test.user
        limit #{offset}, #{limit}
    </select>

    <!--通过实体作为筛选条件查询-->
    <select id="queryAll" resultMap="UserMap">
        select
          id, username, sex, birthday, address, password
        from test.user
        <where>
            <if test="id != null">
                and id = #{id}
            </if>
            <if test="username != null and username != ''">
                and username = #{username}
            </if>
            <if test="sex != null and sex != ''">
                and sex = #{sex}
            </if>
            <if test="birthday != null">
                and birthday = #{birthday}
            </if>
            <if test="address != null and address != ''">
                and address = #{address}
            </if>
            <if test="password != null and password != ''">
                and password = #{password}
            </if>
        </where>
    </select>

    <!--新增所有列-->
    <insert id="insert" keyProperty="id" useGeneratedKeys="true">
        insert into test.user(username, sex, birthday, address, password)
        values (#{username}, #{sex}, #{birthday}, #{address}, #{password})
    </insert>

    <!--通过主键修改数据-->
    <update id="update">
        update test.user
        <set>
            <if test="username != null and username != ''">
                username = #{username},
            </if>
            <if test="sex != null and sex != ''">
                sex = #{sex},
            </if>
            <if test="birthday != null">
                birthday = #{birthday},
            </if>
            <if test="address != null and address != ''">
                address = #{address},
            </if>
            <if test="password != null and password != ''">
                password = #{password},
            </if>
        </set>
        where id = #{id}
    </update>

    <!--通过主键删除-->
    <delete id="deleteById">
        delete from test.user where id = #{id}
    </delete>

</mapper>


举报

相关推荐

0 条评论