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>