Mybatis简单使用+拦截器分页

当前环境:JDK:1.8 Maven项目

https://mybatis.org/mybatis-3/zh/

一、mybatis 简单使用

1、在pom.xml中添加依赖包

<dependencies>
        <!--mybatis-->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.6</version>
        </dependency>
        <!--mysql-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.22</version>
        </dependency>
        <!--Test-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13.1</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

2、在application.properties中配置数据连接

driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost/temp_db?serverTimezone=Asia/Shanghai&useSSL=false&useUnicode=true&characterEncoding=utf-8
username=root
password=123456

3、创建dao中的接口(添加,查询全部,分页查询)

public interface StudentDao {
    
    void addStudent(@Param("stu") Student student);

    List<Student> queryList();

    List<Student> queryByPage(@Param("page") Page<Student> page);
}

4、创建mybatis要映射的xml文件(没有和dao发在一起,发在了resources->mybatis文件夹下)

Tis:注意namespace地址的正确
会把自增的id插入到返回参数Studeng中的id中
分页查询的sql语句不要加分号;,在拼接sql查询总数时会出错,去掉就行了,或者在改拦截器把这里的;截取掉

<?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="cn.liang.dao.StudentDao">
    <insert id="addStudent" useGeneratedKeys="true" keyProperty="id">
        insert into t_student(id,name,sex,schoolId,create_time,update_time) values(#{stu.id},#{stu.name},#{stu.sex},#{stu.schoolId},#{stu.create_Time},#{stu.update_Time});
    </insert>
    <select id="queryList" resultType="cn.liang.pojo.Student">
        select * from t_student;
    </select>
    <select id="queryByPage" resultType="cn.liang.pojo.Student">
        select * from t_student
    </select>
</mapper>

5、添加分页拦截器(mybatis支持插件)

package cn.liang.config;

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.DefaultReflectorFactory;
import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.reflection.SystemMetaObject;

import java.awt.geom.Area;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.Map;
import java.util.Properties;

/**
 * @Intercepts 说明是一个拦截器
 */
@Intercepts({@Signature(type = StatementHandler.class, method = "prepare", args = {Connection.class, Integer.class})})
public class MyPageInterceptor implements Interceptor {

    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        StatementHandler  statementHandler = (StatementHandler) invocation.getTarget();
        MetaObject metaObject = MetaObject.forObject(statementHandler,
                SystemMetaObject.DEFAULT_OBJECT_FACTORY, SystemMetaObject.DEFAULT_OBJECT_WRAPPER_FACTORY,
                new DefaultReflectorFactory());

        MappedStatement mappedStatement = (MappedStatement) metaObject.getValue("delegate.mappedStatement");

        String id = mappedStatement.getId();
        //需要方法名称以Page结尾
        if (id.endsWith("Page")){
            BoundSql boundSql = statementHandler.getBoundSql();
            Map<String, Object> map = (Map<String, Object>) boundSql.getParameterObject();
            //需要在具体查询方法Page参数前添加@Param("page")
            Page<Area> page = (Page<Area>) map.get("page");
            String sql = boundSql.getSql();
            String countSql = "select count(*) from (" + sql + ") a";//PS:注意查询sql不要带分号;不然在下面组合sql时报错
            Connection connection = (Connection) invocation.getArgs()[0];
            PreparedStatement preparedStatement = connection.prepareStatement(countSql);
            ParameterHandler parameterHandler = (ParameterHandler) metaObject.getValue("delegate.parameterHandler");
            parameterHandler.setParameters(preparedStatement);
            ResultSet rs = preparedStatement.executeQuery();
            if (rs.next()){
                page.setTotalPage(rs.getInt(1));
            }
            String pageSql = sql + " limit " + (page.getIndexPage()-1)*page.getPageSize() + ", " + page.getPageSize();
            metaObject.setValue("delegate.boundSql.sql", pageSql);
        }
        return invocation.proceed();
    }


    //获取代理对象
    @Override
    public Object plugin(Object o) {
        //生成object对象的动态代理对象
        return Plugin.wrap(o,this);
    }

    //设置代理对象的参数
    @Override
    public void setProperties(Properties properties) {
    }
}
public class Page<T> implements Serializable {
    private static final long serialVersionUID = 1L;

    private Integer totalPage;
    private Integer pageSize = 10;
    private Integer indexPage = 1;
    private List<T> dataList;

    public Page() {}

    public Page(Integer pageSize, Integer indexPage) {
        this.pageSize = pageSize;
        this.indexPage = indexPage;
    }

    public Integer getTotalPage() {
        return totalPage;
    }

    public void setTotalPage(Integer totalPage) {
        this.totalPage = totalPage;
    }

    public Integer getPageSize() {
        return pageSize;
    }

    public void setPageSize(Integer pageSize) {
        this.pageSize = pageSize;
    }

    public Integer getIndexPage() {
        return indexPage;
    }

    public void setIndexPage(Integer indexPage) {
        this.indexPage = indexPage;
    }

    public List<T> getDataList() {
        return dataList;
    }

    public void setDataList(List<T> dataList) {
        this.dataList = dataList;
    }
}

Mybatis 插件

6、在resources 文件夹下添加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>
    <!--读取属性,也可自定义属性(注意位置)-->
    <properties resource="application.properties"/>

    <!--设置xml中全限定名的别名-->
    <typeAliases>
        <package name="cn.liang.pojo"/>
    </typeAliases>

    <!--注册自定义分页拦截器Interceptor-->
    <plugins>
        <plugin interceptor="cn.liang.config.MyPageInterceptor">
        </plugin>
    </plugins>

    <!--配置环境变量、事务和数据源-->
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="${driver}"/>
                <property name="url" value="${url}"/>
                <property name="username" value="${username}"/>
                <property name="password" value="${password}"/>
            </dataSource>
        </environment>
    </environments>

    <!--设置mapper映射的xml路径-->
    <mappers>
        <!--xml文件发在了resources->mybatis文件夹下-->
        <mapper resource="mybatis/StudentMapper.xml" />
    </mappers>

</configuration>

7、从 XML 中构建 SqlSessionFactory

package cn.liang.config;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import java.io.IOException;
import java.io.InputStream;

public class MybatisUtils {
    public static SqlSessionFactory sqlSessionFactory;
    static {
        String resource="mybatis-config.xml";
        try {
            InputStream inputStream=Resources.getResourceAsStream(resource);
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

8、测试执行

public class Mybatis3ApplicationTests {

    @Test
    public void testMybatisPageList(){
        SqlSession session = MybatisUtils.sqlSessionFactory.openSession();
        try{
            StudentDao mapper = session.getMapper(StudentDao.class);
            Page<Student> studentPage = new Page<Student>();
//            studentPage.setIndexPage(2);
//            studentPage.setPageSize(3);
            List<Student> list = mapper.queryByPage(studentPage);
            studentPage.setDataList(list);

            for (Student student : studentPage.getDataList()) {
                System.out.println(student.toString());
            }
            System.out.println(studentPage.getPageSize());
            System.out.println(studentPage.getTotalPage());
        }
        finally {
            session.close();
        }
    }

    @Test
    public void testMybatisList(){
        SqlSession session = MybatisUtils.sqlSessionFactory.openSession();
        try{
            StudentDao mapper = session.getMapper(StudentDao.class);
            List<Student> list = mapper.queryList();
            for (Student student : list) {
                System.out.println(student.toString());
            }
        }
        finally {
            session.close();
        }
    }

    @Test
    public void testMybatis() throws SQLException {
        SqlSession session = MybatisUtils.sqlSessionFactory.openSession();
        try {
            StudentDao mapper = session.getMapper(StudentDao.class);
            Student student = new Student("带老大2", "男", 1);
            mapper.addStudent(student);
            System.out.println(student.getId());
            session.commit();
        } finally {
            session.close();
        }

    }
}

项目目录结构


如果出现一下错误,请修改文件编码格式

Caused by: com.sun.org.apache.xerces.internal.impl.io.MalformedByteSequenceException: 1 字节的 UTF-8 序列的字节 1 无效

posted @ 2020-12-24 18:19  人间有妖气  阅读(545)  评论(1编辑  收藏  举报