开发工具idea
springboot 2.0.8
一、文件结构
很多人把mapper.xml放到resources下,我个人还是喜欢放到源码包下,
二、POM.xml
4.0.0
org.springframework.boot
spring-boot-starter-parent
2.0.8.RELEASE
com.urthink.upfs
springboot-mybatis
0.0.1-SNAPSHOT
springboot-mybatis
springboot-mybatis project for Spring Boot
1.8
org.springframework.boot
spring-boot-starter
org.springframework.boot
spring-boot-starter-logging
org.springframework.boot
spring-boot-starter-log4j2
org.springframework.boot
spring-boot-starter-web
com.alibaba
druid-spring-boot-starter
1.1.10
org.mybatis.spring.boot
mybatis-spring-boot-starter
1.3.2
mysql
mysql-connector-java
runtime
org.mybatis.generator
mybatis-generator-core
1.3.7
tk.mybatis
mapper-spring-boot-starter
2.1.4
com.github.pagehelper
pagehelper-spring-boot-starter
1.2.9
org.apache.commons
commons-lang3
3.8.1
org.springframework.boot
spring-boot-starter-test
test
org.springframework.boot
spring-boot-maven-plugin
org.mybatis.generator
mybatis-generator-maven-plugin
1.3.7
src/main/resources/generatorConfig.xml
true
true
mysql
mysql-connector-java
5.1.47
tk.mybatis
mapper
4.1.0
src/main/resources
**/*.properties
**/*.xml
**/*.yml
false
src/main/java
**/*.xml
false
三、application.yml
server:
port: 8080
spring:
application:
name: springboot-mybatis
datasource:
name: dataSource1 #如果存在多个数据源,监控的时候可以通过名字来区分开来。如果没有配置,将会生成一个名字,格式是:"DataSource-" + System.identityHashCode(this)
type: com.alibaba.druid.pool.DruidDataSource
#druid相关配置
druid:
#监控统计拦截的filters
filters: stat,wall
driver-class-name: com.mysql.jdbc.Driver
#基本属性
url: jdbc:mysql://127.0.0.1:3306/mytest?useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true&useSSL=false
username: root
password: root
#配置初始化大小/最小/最大
initial-size: 1
min-idle: 1
max-active: 20
#获取连接等待超时时间
max-wait: 60000
#间隔多久进行一次检测,检测需要关闭的空闲连接
time-between-eviction-runs-millis: 60000
#一个连接在池中最小生存的时间
min-evictable-idle-time-millis: 30000
validation-query: SELECT 'x'
test-while-idle: true
test-on-borrow: false
test-on-return: false
#打开PSCache,并指定每个连接上PSCache的大小。oracle设为true,mysql设为false。分库分表较多推荐设置为false
pool-prepared-statements: false
max-pool-prepared-statement-per-connection-size: 20
mybatis:
mapper-locations: classpath*:mapper/*.xml,classpath*:**/*Mapper.xml
type-aliases-package: com.urthink.upfs.springbootmybatis.entity
#IDENTITY: MYSQL #取回主键的方式
#notEmpty: false #insert和update中,是否判断字符串类型!=''
configuration:
#进行自动映射时,数据以下划线命名,如数据库返回的"order_address"命名字段是否映射为class的"orderAddress"字段。默认为false
map-underscore-to-camel-case: true
# 输出SQL执行语句 (log4j2本身可以输出sql语句)
#log-impl: org.apache.ibatis.logging.stdout.StdOutImpl #这种带结果集
pagehelper:
helper-dialect: mysql
offset-as-page-num: true
row-bounds-with-count: true #使用RowBounds分页,需要设置为true
#page-size-zero: false
reasonable: true
#params: pageNum=pageNum;pageSize=pageSize;count=countSql;reasonable=reasonable;pageSizeZero=pageSizeZero
#support-methods-arguments: false
#auto-runtime-dialect: false
#close-conn: false
#aggregate-functions:
mybatis相关配置
Spring boot Mybatis-XML方式通用Mapper插件(七)
https://www.jianshu.com/p/336c71c68a52
UUID:设置生成UUID的方法,需要用OGNL方式配置,不限制返回值,但是必须和字段类型匹配
IDENTITY:取回主键的方式
DB2: VALUES IDENTITY_VAL_LOCAL()
MYSQL: SELECT LAST_INSERT_ID()
SQLSERVER: SELECT SCOPE_IDENTITY()
CLOUDSCAPE: VALUES IDENTITY_VAL_LOCAL()
DERBY: VALUES IDENTITY_VAL_LOCAL()
HSQLDB: CALL IDENTITY()
SYBASE: SELECT @@IDENTITY
DB2_MF: SELECT IDENTITY_VAL_LOCAL() FROM >> * SYSIBM.SYSDUMMY1
INFORMIX: select dbinfo('sqlca.sqlerrd1') from systables where tabid=1
JDBC:这会令 MyBatis 使用 JDBC 的 getGeneratedKeys 方法来取出由数据库内部生成的主键(比如:像 MySQL 和 SQL Server 这样的关系数据库管理系统的自动递增字段)。
ORDER:中的order属性,可选值为BEFORE和AFTER
catalog:数据库的catalog,如果设置该值,查询的时候表名会带catalog设置的前缀
schema:同catalog,catalog优先级高于schema
seqFormat:序列的获取规则,使用{num}格式化参数,默认值为{0}.nextval,针对Oracle,可选参数一共4个,对应0,1,2,3分别为SequenceName,ColumnName, PropertyName,TableName
notEmpty:insert和update中,是否判断字符串类型!='',少数方法会用到
style:实体和表转换时的规则,默认驼峰转下划线,可选值为normal用实体名和字段名;camelhump是默认值,驼峰转下划线;uppercase转换为大写;lowercase转换为小写
enableMethodAnnotation:可以控制是否支持方法上的JPA注解,默认false。
pagehelper相关配置
https://github.com/pagehelper/Mybatis-PageHelper/blob/master/wikis/zh/HowToUse.md
四、generatorConfig.xml
右键运行或双击运行
mybatis-Generator相关配置
【项目管理】Mybatis-Generator之最完美配置详解
https://blog.csdn.net/zsq520520/article/details/50952830
MyBatis Generator 详解
https://blog.csdn.net/isea533/article/details/42102297
五、log4j2.xml
六、SpringbootMybatisApplication.java
package com.urthink.upfs.springbootmybatis;
import tk.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* springboot-mybatis测试
* MapperScan是tk.mybatis.spring.annotation.MapperScan
* 扫包扫到自定义BaseMapper会报错
* 解决方法,1:不扫包,自己的Mapper上加@Mapper注解(个人推荐)
* 2:把自定义BaseMapper放到扫包路径外 (一般做法)
* 3:配置markerInterface,(个人选择)
* @author zhao
* @date 2019.1.22
*/
@SpringBootApplication
@MapperScan(basePackages = {"com.urthink.upfs.springbootmybatis"}, markerInterface=com.urthink.upfs.springbootmybatis.base.BaseMapper.class)
public class SpringbootMybatisApplication {
public static void main(String[] args) {
SpringApplication.run(SpringbootMybatisApplication.class, args);
}
}
七、BaseEntity.java
package com.urthink.upfs.springbootmybatis.base;
import java.io.Serializable;
import java.util.Date;
/**
* 实体类基类
*
* @author zhao
* @date 2019.1.23
*/
public class BaseEntity implements Serializable {
//子类需要自己定义
//private static final long serialVersionUID = 1L;
public Serializable getId() {
throw new RuntimeException("UnOverride getId()");
}
protected Integer createBy; //创建人
protected Date createTime; //创建时间
public Integer getCreateBy() {
return createBy;
}
public void setCreateBy(Integer createBy) {
this.createBy = createBy;
}
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
}
八、BaseMapper.java
package com.urthink.upfs.springbootmybatis.base;
import tk.mybatis.mapper.common.Mapper;
import tk.mybatis.mapper.common.MySqlMapper;
import java.util.List;
import java.util.Map;
/**
* 基础Mapper
* @param
* @author zhao
* @date 2019.1.23
*/
public interface BaseMapper extends Mapper, MySqlMapper {
/**
* 通用分页查询
* @param map
* @return
*/
List getPageList(Map map);
}
九、BaseService.java
package com.urthink.upfs.springbootmybatis.base;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import tk.mybatis.mapper.entity.Example;
import java.util.List;
import java.util.Map;
/**
* 基础Service
* @param
* @author zhao
* @date 2019.1.23
*/
public class BaseService {
@Autowired
protected BaseMapper baseMapper;
public int deleteByPrimaryKey(Integer id){
return baseMapper.deleteByPrimaryKey(id);
}
public int insert(T entity){
return baseMapper.insert(entity);
}
public int insertSelective(T entity){
return baseMapper.insertSelective(entity);
}
public T selectByPrimaryKey(Object id){
return (T)baseMapper.selectByPrimaryKey(id);
}
public int updateByPrimaryKeySelective(T entity){
return baseMapper.updateByPrimaryKeySelective(entity);
}
public int updateByPrimaryKey(T entity){
return baseMapper.updateByPrimaryKey(entity);
}
/**
* 通用分页查询
* 通过Example设置条件
* @param map 需要包含pageNum,pageSize,example分页参数
* @return
*/
public PageInfo selectPageInfo(Map map) {
if(map.get("pageNum")!=null && map.get("pageSize")!=null) {
PageHelper.startPage((Integer) map.get("pageNum"), (Integer) map.get("pageSize"));
}
if (map.get("orderBy") != null) {
PageHelper.orderBy(map.get("orderBy").toString());
}
List list = null;
if(map.get("example") !=null) {
list = baseMapper.selectByExample((Example) map.get("example"));
} else {
list = baseMapper.selectAll();
}
PageInfo pageInfo = new PageInfo(list);
return pageInfo;
}
/**
* 通用分页查询
* @param map
* @return
*/
public PageInfo getPageInfo(Map map) {
if(map.get("pageNum")!=null && map.get("pageSize")!=null) {
PageHelper.startPage((Integer) map.get("pageNum"), (Integer) map.get("pageSize"));
}
if (map.get("orderBy") != null) {
PageHelper.orderBy(map.get("orderBy").toString());
}
List list = baseMapper.getPageList(map);
PageInfo pageInfo = new PageInfo(list);
return pageInfo;
}
}
十、建表语句sql
/*
Navicat Premium Data Transfer
Source Server : localhost
Source Server Type : MySQL
Source Server Version : 50724
Source Host : localhost:3306
Source Schema : mytest
Target Server Type : MySQL
Target Server Version : 50724
File Encoding : 65001
Date: 24/01/2019 11:25:07
*/
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for t_user
-- ----------------------------
DROP TABLE IF EXISTS `t_user`;
CREATE TABLE `t_user` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'ID',
`user_name` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '用户名',
`password` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '密码',
`mobile` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '手机号',
`enable` char(1) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '是否启用',
`create_by` int(11) NOT NULL COMMENT '创建人',
`create_time` timestamp(0) NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP(0) COMMENT '创建时间',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1013 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of t_user
-- ----------------------------
INSERT INTO `t_user` VALUES (1000, 'admin', 'xujiami', '13688888888', '1', 1, '2019-01-22 19:58:16');
INSERT INTO `t_user` VALUES (1001, 'test1', 'test', NULL, '1', 1, '2019-01-22 11:13:28');
INSERT INTO `t_user` VALUES (1002, 'test2', 'test', NULL, '1', 1, '2019-01-22 11:18:12');
INSERT INTO `t_user` VALUES (1003, 'test3', 'test', NULL, '1', 1, '2019-01-22 11:18:13');
INSERT INTO `t_user` VALUES (1004, 'test4', 'test', NULL, '1', 1, '2019-01-22 11:18:15');
INSERT INTO `t_user` VALUES (1005, 'test5', 'test', NULL, '1', 1, '2019-01-22 11:18:17');
INSERT INTO `t_user` VALUES (1006, 'test6', 'test', NULL, '1', 1, '2019-01-22 11:18:18');
INSERT INTO `t_user` VALUES (1007, 'test7', 'test', NULL, '1', 1, '2019-01-22 11:18:20');
INSERT INTO `t_user` VALUES (1008, 'test8', 'test', NULL, '1', 1, '2019-01-22 11:18:22');
INSERT INTO `t_user` VALUES (1009, 'test9', 'test', NULL, '1', 1, '2019-01-22 11:18:24');
INSERT INTO `t_user` VALUES (1010, 'test10', 'test', NULL, '1', 1, '2019-01-22 11:18:27');
INSERT INTO `t_user` VALUES (1011, 'test11', 'test', NULL, '1', 1, '2019-01-22 11:18:36');
INSERT INTO `t_user` VALUES (1012, 'test12', 'test', NULL, '1', 1, '2019-01-22 19:56:52');
SET FOREIGN_KEY_CHECKS = 1;
十一、实体类User.java
package com.urthink.upfs.springbootmybatis.entity;
import com.urthink.upfs.springbootmybatis.base.BaseEntity;
import java.util.Date;
import javax.persistence.*;
@Table(name = "t_user")
public class User extends BaseEntity {
/**
* ID
*/
@Id
private Integer id;
/**
* 用户名
*/
@Column(name = "user_name")
private String userName;
/**
* 密码
*/
private String password;
/**
* 手机号
*/
private String mobile;
/**
* 是否启用
*/
private String enable;
/**
* 创建人
*/
@Column(name = "create_by")
private Integer createBy;
/**
* 创建时间
*/
@Column(name = "create_time")
private Date createTime;
/**
* 获取ID
*
* @return id - ID
*/
public Integer getId() {
return id;
}
/**
* 设置ID
*
* @param id ID
*/
public void setId(Integer id) {
this.id = id;
}
/**
* 获取用户名
*
* @return user_name - 用户名
*/
public String getUserName() {
return userName;
}
/**
* 设置用户名
*
* @param userName 用户名
*/
public void setUserName(String userName) {
this.userName = userName == null ? null : userName.trim();
}
/**
* 获取密码
*
* @return password - 密码
*/
public String getPassword() {
return password;
}
/**
* 设置密码
*
* @param password 密码
*/
public void setPassword(String password) {
this.password = password == null ? null : password.trim();
}
/**
* 获取手机号
*
* @return mobile - 手机号
*/
public String getMobile() {
return mobile;
}
/**
* 设置手机号
*
* @param mobile 手机号
*/
public void setMobile(String mobile) {
this.mobile = mobile == null ? null : mobile.trim();
}
/**
* 获取是否启用
*
* @return enable - 是否启用
*/
public String getEnable() {
return enable;
}
/**
* 设置是否启用
*
* @param enable 是否启用
*/
public void setEnable(String enable) {
this.enable = enable == null ? null : enable.trim();
}
/**
* 获取创建人
*
* @return create_by - 创建人
*/
public Integer getCreateBy() {
return createBy;
}
/**
* 设置创建人
*
* @param createBy 创建人
*/
public void setCreateBy(Integer createBy) {
this.createBy = createBy;
}
/**
* 获取创建时间
*
* @return create_time - 创建时间
*/
public Date getCreateTime() {
return createTime;
}
/**
* 设置创建时间
*
* @param createTime 创建时间
*/
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
}
十二、UserMapper.java
package com.urthink.upfs.springbootmybatis.mapper;
import com.urthink.upfs.springbootmybatis.base.BaseMapper;
import com.urthink.upfs.springbootmybatis.entity.User;
//@Mapper
public interface UserMapper extends BaseMapper {
}
十三、UserMapper.xml
十四、UserService.java
package com.urthink.upfs.springbootmybatis.servcie;
import com.urthink.upfs.springbootmybatis.base.BaseService;
import com.urthink.upfs.springbootmybatis.entity.User;
import com.urthink.upfs.springbootmybatis.mapper.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
@Transactional
public class UserService extends BaseService {
@Autowired
private UserMapper userMapper;
}
十五、MybatisTest .java
package com.urthink.upfs.springbootmybatis;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.urthink.upfs.springbootmybatis.entity.User;
import com.urthink.upfs.springbootmybatis.mapper.UserMapper;
import com.urthink.upfs.springbootmybatis.servcie.UserService;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.session.RowBounds;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.annotation.Rollback;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* mybatis测试类
* https://github.com/pagehelper/Mybatis-PageHelper/blob/master/wikis/zh/HowToUse.md
* @author zhao
* @date 2019.1.21
*
*/
@RunWith(SpringRunner.class)
@SpringBootTest
@Transactional //支持事物,@SpringBootTest 事物默认自动回滚
@Rollback // 事务自动回滚,不自动回滚@Rollback(false)
public class MybatisTest {
@Autowired
private SqlSessionTemplate sqlSessionTemplate;
@Autowired
private UserService userService;
@Autowired
private UserMapper userMapper;
@Test
public void sqlSessionTemplateTest() {
User user = sqlSessionTemplate.selectOne("com.urthink.upfs.springbootmybatis.mapper.UserMapper.selectByPrimaryKey",1000);
System.out.println(user.getUserName());
}
@Test
public void selectTest() {
User user = userService.selectByPrimaryKey(1000);
System.out.println(user.getUserName());
}
@Test
public void insertTest() {
User user = new User();
user.setUserName("test");
user.setPassword("test"); //需加密
user.setEnable("1");
user.setCreateBy(1);
user.setCreateTime(new Date());
int r = userService.insert(user);
System.out.println(r);
}
@Test
public void pageTest1() {
//第一种,RowBounds方式的调用,需要把rowBoundsWithCount设置为true
List userList = sqlSessionTemplate.selectList("com.urthink.upfs.springbootmybatis.mapper.UserMapper.getPageList", null, new RowBounds(0, 10));
//用PageInfo对结果进行包装
PageInfo pageInfo = new PageInfo(userList);
//PageInfo包含了非常全面的分页属性
System.out.println("当前页:" + pageInfo.getPageNum());
System.out.println("每页的数量:" + pageInfo.getPageSize());
System.out.println("总记录数:" + pageInfo.getTotal());
System.out.println("结果集:" + pageInfo.getList());
}
@Test
public void pageTest2() {
//第二种,Mapper接口方式的调用,推荐这种使用方式。
PageHelper.startPage(1, 10);
//排序
PageHelper.orderBy("create_time asc, id asc");
List list = userMapper.getPageList(null);
//用PageInfo对结果进行包装
PageInfo pageInfo = new PageInfo(list);
//测试PageInfo全部属性
//PageInfo包含了非常全面的分页属性
System.out.println("当前页:" + pageInfo.getPageNum());
System.out.println("每页的数量:" + pageInfo.getPageSize());
System.out.println("当前页的数量:" + pageInfo.getSize());
System.out.println("当前页面第一个元素在数据库中的行号:" + pageInfo.getStartRow());
System.out.println("当前页面最后一个元素在数据库中的行号:" + pageInfo.getEndRow());
System.out.println("总页数:" + pageInfo.getPages());
System.out.println("前一页:" + pageInfo.getPrePage());
System.out.println("下一页:" + pageInfo.getNextPage());
System.out.println("是否为第一页:" + pageInfo.isIsFirstPage());
System.out.println("是否为最后一页:" + pageInfo.isIsLastPage());
System.out.println("是否有前一页:" + pageInfo.isHasPreviousPage());
System.out.println("是否有下一页:" + pageInfo.isHasNextPage());
System.out.println("导航页码数:" + pageInfo.getNavigatePages());
System.out.println("所有导航页号:" + pageInfo.getNavigatepageNums());
System.out.println("导航条上的第一页:" + pageInfo.getNavigateFirstPage());
System.out.println("导航条上的最后一页:" + pageInfo.getNavigateLastPage());
System.out.println("总记录数:" + pageInfo.getTotal());
System.out.println("结果集:" + pageInfo.getList());
System.out.println(list.size());
}
@Test
public void pageTest3() {
Map map = new HashMap();
map.put("pageNum", 1);
map.put("pageSize", 10);
map.put("orderBy", "create_time asc, id asc");
map.put("userName", "test"); //XML里要的查询条件
PageInfo pageInfo = userService.getPageInfo(map);
//PageInfo包含了非常全面的分页属性
System.out.println("当前页:" + pageInfo.getPageNum());
System.out.println("每页的数量:" + pageInfo.getPageSize());
System.out.println("总记录数:" + pageInfo.getTotal());
System.out.println("结果集:" + pageInfo.getList());
}
@Test
public void pageTest4() {
Map map = new HashMap();
map.put("pageNum", 1);
map.put("pageSize", 10);
map.put("orderBy", "create_time asc, id asc");
map.put("userName", "test"); //XML里要的查询条件
Example example = new Example(User.class);
Example.Criteria criteria = example.createCriteria();
if(StringUtils.isNotEmpty((String)map.get("id"))) {
criteria.andEqualTo("id", map.get("id"));
}
if(StringUtils.isNotEmpty((String)map.get("userName"))) {
criteria.andLike("userName", "%"+(String)map.get("userName")+"%");
}
map.put("example", example);
PageInfo pageInfo = userService.selectPageInfo(map);
//PageInfo包含了非常全面的分页属性
System.out.println("当前页:" + pageInfo.getPageNum());
System.out.println("每页的数量:" + pageInfo.getPageSize());
System.out.println("总记录数:" + pageInfo.getTotal());
System.out.println("结果集:" + pageInfo.getList());
}
}
idea mybatis相关插件推荐
插件
1.jrebel
动态加载类
2.free mybatis plugin
方便在mapper.java和mapper.xml 之间切换
3.mybatis log plugin 查看sql语句,把参数填充好
把 mybatis 输出的sql日志还原成完整的sql语句。
将日志输出的sql语句中的问号 ? 替换成真正的参数值。
通过 "Tools -> MyBatis Log Plugin" 菜单或快捷键 "Ctrl+Shift+Alt+O" 启用。
点击窗口左边的 "Filter" 按钮,可以过滤不想要输出的sql语句。
点击窗口左边的 "Format Sql" 按钮,可以格式化输出的sql语句。
选中console的sql日志,右击 "Restore Sql from Selection" 菜单可以还原sql语句。
前提条件:输出的sql日志必须包含"Preparing:"和"Parameters:"才能正常解析。
springboot 2.0 集成mybatis,mybatis-generator,pagehelper
https://blog.csdn.net/haveqing/article/details/86600341
参考:
spring boot 2.0 +mybatis + tk+MBG
https://blog.csdn.net/weixin_41876599/article/details/82665237
MyBatis 通用 Mapper4
https://github.com/abel533/Mapper