Mybatis-Plus(简称MP)是一个 Mybatis 的增强工具,在 Mybatis 的基础上只做增强不做改变,为简化开发、提高效率而生。这是官方给的定义,关于mybatis-plus的更多介绍及特性,可以参考mybatis-plus官网。那么它是怎么增强的呢?其实就是它已经封装好了一些crud方法,我们不需要再写xml了,直接调用这些方法就行,就类似于JPA。
官网地址: https://mybatis.plus/guide/
1.8
3.3.2
com.baomidou
mybatis-plus-boot-starter
${mybatis-plus.version}
com.baomidou
mybatis-plus-generator
${mybatis-plus.version}
org.springframework.boot
spring-boot-starter-freemarker
org.projectlombok
lombok
CREATE TABLE sys_user (
id int AUTO_INCREMENT,
username varchar(20) COMMENT '用户名',
password varchar(20) COMMENT '密码',
create_time datetime COMMENT '创建时间',
grade int COMMENT '年纪',
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
通常会把一些通用的字段放入到超类中
@Data
public class BaseEntity {
private Integer id;
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date createTime;
}
public class MysqlGenerator {
//生成类的作者描述
private final static String AUTHOR="LeeJunMing";
private final static String DATASOURCE_URL="jdbc:mysql://localhost:3306/boot_master?useSSL=false&serverTimezone=GMT%2b8&characterEncoding=utf8&connectTimeout=10000&socketTimeout=3000&autoReconnect=true";
private final static String DATASOURCE_DRIVER_NAME="com.mysql.cj.jdbc.Driver";
private final static String DATASOURCE_USERNAME="root";
private final static String DATASOURCE_PASSWORD="123456";
//基础包名
private final static String BASE_PACKAGE="com.ljm.boot";
//生成的模块名称
private final static String MODEL_NAME="mybatisplus";
//超类的字段(不会出现在自动生成的表中)
private final static String[] SUERP_COLUMN=new String[]{"id","create_time"};
//要把哪些表生成模板代码
private final static String [] GENERATOR_TABLES=new String[]{"sys_user"};
public static void main(String[] args) {
// 代码生成器
AutoGenerator mpg = new AutoGenerator();
// 全局配置
GlobalConfig gc = new GlobalConfig();
String projectPath = System.getProperty("user.dir");
//聚合工程需要写工程的名字,普通工程写 '' 就行
String parantPath="/14_mybatis-plus";
gc.setOutputDir(projectPath + parantPath+"/src/main/java");
gc.setAuthor(AUTHOR);
gc.setOpen(false);
mpg.setGlobalConfig(gc);
// 数据源配置
DataSourceConfig dsc = new DataSourceConfig();
dsc.setUrl(DATASOURCE_URL);
dsc.setDriverName(DATASOURCE_DRIVER_NAME);
dsc.setUsername(DATASOURCE_USERNAME);
dsc.setPassword(DATASOURCE_PASSWORD);
mpg.setDataSource(dsc);
// 包配置
PackageConfig pc = new PackageConfig();
pc.setModuleName(MODEL_NAME);
pc.setParent(BASE_PACKAGE);
mpg.setPackageInfo(pc);
// 自定义配置
InjectionConfig cfg = new InjectionConfig() {
@Override
public void initMap() {
// to do nothing
}
};
List<FileOutConfig> focList = new ArrayList<>();
focList.add(new FileOutConfig("/templates/mapper.xml.ftl") {
@Override
public String outputFile(TableInfo tableInfo) {
// 自定义输入文件名称
return projectPath + parantPath+"/src/main/java/"+BASE_PACKAGE.replaceAll("\\.","/")+"/" + pc.getModuleName()
+ "/mapper/xml/" + tableInfo.getEntityName() + "Mapper" + StringPool.DOT_XML;
}
});
cfg.setFileOutConfigList(focList);
mpg.setCfg(cfg);
mpg.setTemplate(new TemplateConfig().setXml(null));
// 策略配置
StrategyConfig strategy = new StrategyConfig();
strategy.setNaming(NamingStrategy.underline_to_camel);
strategy.setColumnNaming(NamingStrategy.underline_to_camel);
strategy.setEntityLombokModel(true);
//设置控制器的超类
//strategy.setSuperControllerClass("com.baomidou.mybatisplus.samples.generator.common.BaseController");
//设置实体类的超类
strategy.setSuperEntityClass(BaseEntity.class);
//设置
strategy.setInclude(GENERATOR_TABLES);
strategy.setSuperEntityColumns(SUERP_COLUMN);
strategy.setControllerMappingHyphenStyle(true);
mpg.setStrategy(strategy);
// 选择 freemarker 引擎需要指定如下加,注意 pom 依赖必须有!
mpg.setTemplateEngine(new FreemarkerTemplateEngine());
mpg.execute();
}
}
看到下面的日志就代表模板文件生成成功了.
会把每个表生成一个controller->service->mapper>xml>entity
生成的结构如下
下面的代码会在模板生成器生成模板的时候会自动添加上
此处继承了ServiceImpl通用代码实现类
@Service
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> implements ISysUserService {
}
查看ServiceImpl 源码能看到已经定义了一些通用的代码
//新增 这个有点迷,我以为会和Jpa一样自动判断添加和修改,这个save只能添加
boolean save(T entity);
//根据id获取
T getById(Serializable id)
//根据条件查询
List<T> list(Wrapper<T> queryWrapper)
//分页查询
<E extends IPage<T>> E page(E page, Wrapper<T> queryWrapper);
//批量新增 (默认是1000条,可以调用saveBatch(Collection entityList, int batchSize)指定批量操作数量)
boolean saveBatch(Collection<T> entityList)
//添加或者修改
boolean saveOrUpdate(T entity);
//批量添加或者修改
boolean saveOrUpdateBatch(Collection<T> entityList)
//根据ID删除
removeById(Serializable id)
//根据Id批量删除
boolean removeByIds(Collection<? extends Serializable> idList)
此处继承BaseMappe 接口
public interface SysUserMapper extends BaseMapper<SysUser> {
}
接口采用了RESTful风格
@Controller
@RequestMapping("/user")
public class SysUserController {
@Autowired
ISysUserService userService;
/**
* 分页查询
*/
@GetMapping("/")
public String getUserBypage(PageParam<SysUser> pageParam, Model model) {
pageParam.initialization();
IPage<SysUser> iPage = userService.page(pageParam.getPage(), pageParam.getQueryWrapper());
System.out.printf("总页数:{%d},总记录数:{%d}", iPage.getPages(), iPage.getTotal());
model.addAttribute("page", new PageResult<>(iPage));
return "user/index";
}
/**
* ajax 分页查询
*/
@PostMapping(value = "/json")
@ResponseBody
public PageResult getUserJsonDataBypage(@RequestBody PageParam<SysUser> pageParam, Model model) {
pageParam.initialization();
IPage<SysUser> iPage = userService.page(pageParam.getPage(), pageParam.getQueryWrapper());
model.addAttribute("page", new PageResult<>(iPage));
return new PageResult<>(iPage);
}
/**
* 根据id获取user,并且跳转到数据修改页面
*/
@GetMapping("/{id}")
public String getUserById(@PathVariable Integer id, Model model) {
//id=-1的时候代表着是重添加用户按钮进来的请求
if (id != -1) {
SysUser user = userService.getById(id);
model.addAttribute("user", user);
}
return "user/save";
}
/**
* 添加用户
*/
@PostMapping("/")
@ResponseBody
public boolean addUser(SysUser user) {
return userService.save(user);
}
/**
* 修改用户
*/
@PutMapping("/")
@ResponseBody
public boolean modifyUser(SysUser user) {
return userService.saveOrUpdate(user);
}
/**
* 删除
*/
@DeleteMapping("/{ids}")
@ResponseBody
public boolean deleteUserById(@PathVariable String ids) {
String idarr[] = ids.split(",");
if (idarr.length == 1) {
return userService.removeById(idarr[0]);
} else {
return userService.removeByIds(Arrays.asList(idarr));
}
}
}
@Data
public class PageParam<T> {
private Integer DEFAULT_PAGE_SIZE=10;
private Page<T> page;
//查询条件构造器
private QueryWrapper<T> queryWrapper;
private Integer currentPage;
private Integer pageSize;
@JsonFormat(pattern="yyyy-MM-dd",timezone="Asia/Shanghai")
private Date beginDate;
@JsonFormat(pattern="yyyy-MM-dd",timezone="Asia/Shanghai")
private Date endDate;
private Map<String, Object> eq = new HashMap<>();
private Map<String, String> like = new HashMap<>();
/**
* 构建jpa需要的分页对象 初始化
*/
public void initialization() {
if(this.currentPage==null){
this.currentPage=1;
}
if(this.pageSize==null){
this.pageSize=this.DEFAULT_PAGE_SIZE;
}
this.page= new Page<>(this.currentPage, this.pageSize);
this.setCompare();
}
/**
* 注入查询条件参数
*/
private void setCompare() {
this.queryWrapper=new QueryWrapper<>();
if (!StringUtils.isEmpty(beginDate)) {
//大于或等于传入时间
queryWrapper.ge("create_time",beginDate);
}
if (!StringUtils.isEmpty(endDate)) {
//小于或等于传入时间
queryWrapper.le("create_time",beginDate);
}
String value = "";
//注入文本框的模糊查询参数
for (Map.Entry<String, String> entry : like.entrySet()) {
value = entry.getValue().trim();
if (StringUtils.isEmpty(value)) {
continue;
}
//过滤掉非法的符号,不然会影响模糊查询
value = value.replaceAll("%", "////%").replaceAll("_", "////_");
queryWrapper.like(entry.getKey(), value );
}
//注入下拉框或单选框的等值查询参数
for (Map.Entry<String, Object> entry : eq.entrySet()) {
if (StringUtils.isEmpty(entry.getValue())) {
continue;
}
queryWrapper.eq(entry.getKey(),entry.getValue());
}
}
}
util.getFromData=function(form) {
var root={}
var like={};
var eq={};
//注入页码和当前页
root["currentPage"]=$("[name='currentPage']").val();
root["pageSize"]=$("[name='pageSize']").val();
//文本框都用模糊查询
form.find("[type='text']").each(function(){
var value= $(this).val(); //input 值
var name= $(this).attr('name');
if(name.indexOf("Date")!=-1){
//日期字段用root注入
root[name]=value;
}else{
//其它文本字段注入到like参数中
like[name]=value;
}
});
//单选框 等值匹配
form.find("[type='radio']:checked").each(function(){
var value= $(this).val(); //input 值
var name= $(this).attr('name');
eq[name]=value;
});
//等值匹配
form.find("select").each(function(){
var value= $(this).val();
var name= $(this).attr('name');
//页码信息是用select装的,所有排除掉
if(name!="pageSize"){
eq[name]=value;
}
});
root['eq']=eq;
root['like']=like;
return root;
}
var $form=$("form");
$.ajax({
type: 'post',
url: url,
data: JSON.stringify(util.getFromData($form)),
contentType: "application/json",
success: function (page){
},
error:function () {
layer.msg("网络异常!", {icon: 2, time: 2000});
}
});
github地址: https://github.com/Dominick-Li/springboot-master
该demo已经实现了简单的CRUD+分页查询功能
由于生成模板需要用的freemarker模板引擎,所以页面的数据渲染也使用的freemarker模板引擎渲染
页面的ui库使用的h-ui,官网地址:http://www.h-ui.net/
github地址
要是觉得我写的对你有点帮助的话,麻烦在github上帮我点 Star
【SpringBoot框架篇】其它文章如下,后续会继续更新。