# mybatis-generator **Repository Path**: manyhf16/mybatis-generator ## Basic Information - **Project Name**: mybatis-generator - **Description**: No description available - **Primary Language**: Java - **License**: Apache-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2017-09-19 - **Last Updated**: 2020-12-19 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # mybatis-generator ## 1. 初衷 项目开发时,每次都要重复劳动编写增删改查方法,因此... 最初的目标是想利用实体类,生成mybatis中```xml mapper```和```接口mapper``` 接下来感觉easyui的代码规律性也很强,索性一块生成```easyui页面```以及```springmvc的控制器类``` 将来还可以继续扩展,与更多前端ui框架适配 > **注意** 为什么不用org.mybatis.generator > * 它的粒度太粗了 > * 自己造轮子比较有意思 ## 2. 快速上手 ### 1) 添加依赖 **1.clone 项目至本地** ``` git clone https://gitee.com/manyhf16/mybatis-generator.git ``` **2.安装至本地仓库** ``` mvn install ``` **3.给你的项目添加依赖** ```xml org.yihang mybatis-generator 1.0.4 ``` ### 2) 创建表 ```sql drop table if exists my_person; create table my_person( id int auto_increment, name varchar(32), sex tinyint, birthday date, salary numeric(10,2), create_time datetime, update_time datetime, dept_id int, primary key(id) ); ``` > **注意** 目前仅支持oracle和mysql方言 ### 3) 创建实体类 ```java public class Person { private int id; private String name; private int sex; private LocalDate birthday; private LocalDateTime createTime; private LocalDateTime updateTime; private int deptId; // getter, setter 略 } ``` ### 4) 生成 ```java new MapperGenerator.Builder() .mapperPackage("org.yihang.mapper") .nameStrategy(NameStrategy.CamelUnderscore.tablePrefix("my_")) .build() .process(Person.class); ``` 结果会在```org.yihang.mapper```包下,生成PersonMapper.java 接口和PersonMapper.xml 映射文件,以及一个辅助的PersonVo类(用来充当查询条件) **PersonMapper.java** ```java import java.util.List; import org.yihang.entity.Person; import org.yihang.entity.vo.PersonVo; public interface PersonMapper { void save(Person person); // 新增 void update(Person person); // 修改 List findAll(); // 查询所有 int findCount(); // 查询总数 List findByVo(PersonVo vo); // 按条件(分页、排序等)查询 int findCountByVo(PersonVo vo); // 按条件(分页、排序等)查询总数 } ``` **PersonMapper.xml** ```xml insert into my_person (name,sex,birthday,create_time,update_time,dept_id) values (#{name},#{sex},#{birthday},#{createTime},#{updateTime},#{deptId}) update my_person name=#{name}, sex=#{sex}, birthday=#{birthday}, create_time=#{createTime}, update_time=#{updateTime}, dept_id=#{deptId}, where id=#{id} ``` > **注意** > 1. 属性名和列名根据 ```驼峰——下划线``` 规则进行了映射 > 2. 主键生成值被处理 > 3. update 是动态的 > 4. 根据数据库方言,考虑了物理分页 **PersonVo.java** ```java public class PersonVo { private int page=1; private int rows=10; private String sort; private String order; public int getPage() { return page; } public void setPage(int page) { this.page = page; } public int getRows() { return rows; } public void setRows(int rows) { this.rows = rows; } public String getSort() { return sort; } public void setSort(String sort) { this.sort = sort; } public String getOrder() { return order; } public void setOrder(String order) { this.order = order; } public int getOffset() { return rows*(page-1); } public int getLimit() { return rows; } } ``` ## 3. 注解 细心的同学应当注意到,前面生成的代码中没有常用的 findById, deleteById 等方法,这些需要配合注解才会生成。 **例1:** ```java public class Person { @FindBy @DeleteBy private int id; // ... ... } ``` 会多生成如下接口方法(包括xml中的sql): ```java void deleteById(int id); Person findById(int id); ``` **例2:** ```java public class Person { @FindBy(withMulti = true) @DeleteBy(withMulti = true) private int id; // ... ... } ``` 会多生成如下接口方法(包括xml中的sql): ```java void deleteById(int id); void deleteByIds(List id); Person findById(int id); List findByIds(List id); ``` **例3:** ```java public class Person { @FindByVo(voType = VoType.like) private String name; @FindByVo(voType = VoType.between) private LocalDate birthday; @FindByVo private int deptId; // ... ... ``` 不会多生成新的接口方法,但会提供```多条件组合查询```功能: vo对象中会多出来查询属性: ```java public class PersonVo { private java.lang.String name; private java.time.LocalDate minBirthday; private java.time.LocalDate maxBirthday; private java.lang.Integer deptId; // ... ... ``` xml中的findByVo方法也会新增判断条件 ```xml ``` ## 4. 生成选项 可以通过调用MapperGenerator.Builder中的方法控制生成时的选项 |方法名|作用|备注| |-|-|-| |idProperty|实体类中作为主键的属性名|默认为id,如果主键属性不叫id,必须设置此配置或在实体类上用@Id注解标注| |mapperPackage|控制生成的接口和类所在的java包|```必须```| |voPackage|控制生成的Vo类所在的java包|默认为实体类所在包的vo子包| |outputDir|输出文件夹|默认为当前项目| |structure|项目的目录结构|默认为Maven项目目录结构,还支持Eclipse动态Web项目目录结构| |include|控制包含哪些方法|-| |exclude|控制排除哪些方法|-| |dialect|数据库方言|默认为mysql| |nameStrategy|属性和列的转换规则|支持```驼峰——下划线规则```映射和```注解规则```映射(@Id @Column)| ## 5. 生成EasyUI页面 ### 1) 先加入一些测试数据 ```sql insert into my_person(id,name,sex,birthday,salary,create_time,update_time,dept_id) values(null,'a',0,'1980-5-3',2000.00,now(),now(),1); ``` ### 2) 给实体类添加注解 ```java public class Person { @DatagridColumn(title = "编号") private int id; @DatagridColumn(title = "姓名") private String name; @DatagridColumn(title = "性别") private int sex; @DatagridColumn(title = "生日") @JsonFormat(pattern="yyyy-MM-dd") private LocalDate birthday; @DatagridColumn(title = "创建时间") @JsonFormat(pattern="yyyy-MM-dd HH:mm:ss") private LocalDateTime createTime; @DatagridColumn(title = "修改时间") @JsonFormat(pattern="yyyy-MM-dd HH:mm:ss") private LocalDateTime updateTime; @DatagridColumn(title = "编号") private int deptId; // 略 } ``` > **注意** > 1. 为了看起来干净,略去了原本生成mapper时的注解(如@FindBy, @DeleteBy注解在生成EasyUI代码时仍需用到) > 2. @JsonFormat是用来控制返回json数据格式的,需要jackson相关的jar依赖 ### 3) 生成 ```java new EasyUIGenerator.Builder() .setControllerPackage("org.yihang.controller") .setMapperPackage("org.yihang.mapper") .build() .process(Person.class); ``` 结果包括person.html, PersonController.java > **注意** > * springmvc相关的配置,easyui需要的js,css等资源需要提前准备好,可以下载本站的模板项目。 **person.html预览** ![](https://gitee.com/manyhf16/mybatis-generator/raw/master/img/1.png) **PersonController.java** ```java package org.yihang.controller; import java.util.*; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; import org.yihang.entity.Person; import org.yihang.entity.vo.*; import org.yihang.mapper.PersonMapper; @RestController public class PersonController { @Autowired public PersonMapper personMapper; @GetMapping("/person/datagrid") public DataGridVo dataGrid(@RequestParam(defaultValue="1") int page, @RequestParam(defaultValue="10") int rows, PersonVo vo) { List list = personMapper.findByVo(vo); int total = personMapper.findCountByVo(vo); return new DataGridVo(list, total); } @PostMapping("/person/save") public Map save(Person person){ personMapper.save(person); Map map = new HashMap<>(); map.put("success", true); return map; } @PostMapping("/person/update") public Map update(Person person){ personMapper.update(person); Map map = new HashMap<>(); map.put("success", true); return map; } @GetMapping("/person/findById") public Person findById(int id){ return personMapper.findById(id); } @GetMapping("/person/deleteById") public Map delete(int id){ personMapper.deleteById(id); Map map = new HashMap<>(); map.put("success", true); return map; } @GetMapping("/person/deleteByIds") public Map delete(@RequestParam List id){ personMapper.deleteByIds(id); Map map = new HashMap<>(); map.put("success", true); return map; } } ``` > **注意** > * 有些属性的显示结果需要进一步格式化 > * 上一步生成的结果中,仅包含```分页查询```、```删除```和```删除选中```功能,这时因为刚刚的实体类上仅加了@DatagridColumn注解 > * 没有直接生成```新增```,```修改```表单是因为datagrid所显示的属性和新增修改所需属性不是一致的,因此分开来处理 > EasyUI相关的注解如下表,会在后面几个章节陆续介绍: > |注解名|作用|备注| |-|-|-| |@DatagridColumn|生成表格所需列|-| |@Search|生成搜索条件|必须配合@FindByVo使用,以提供Mapper上的支持| |@Input|生成新增、修改所需表单|-| |@LocalSource|为格式化提供翻译所需源数据|本地-会直接在网页上生成所需js数据| |@RemoteSource|为格式化提供翻译所需源数据|远程-从其它url获取所需js数据| |@RemoteSourceAdapter|为@RemoteSource提供springmvc控制器适配方法|-| ### 4) 本地格式化 给实体类补充注解 ```java @LocalSource(var="sexes", kvvar = "sexeskv", kv = {@KV(value="0",text = "男"),@KV(value="1",text = "女")}) public class Person { @DatagridColumn(title = "性别", formatter = @Formatter(type = FormatterType.SOURCE, value="sexeskv")) private int sex; // 略 } ``` @LocalSource 注解会在网页中生成如下js变量: ```javascript var sexeskv = {"0":"男","1":"女"}; // 给formatter用,翻译0,1->男,女 var sexes = [{"text":"男","value":0},{"text":"女","value":1}]; // 给combobox用,显示下拉列表的选项 ``` 而@DatagridColumn生成的表格列,会引用sexeskv变量,起到翻译的作用 > **注意** > * @KV 中的value 可以是 true|false; 也可以是0,1,2,3...的数字; 但如果想表达字符串,必须在两边加一对单引号,如: @KV(value="'bj'",text = "北京") 修改后重新运行 ```java new EasyUIGenerator.Builder() .setControllerPackage("org.yihang.controller") .setMapperPackage("org.yihang.mapper") .build() .process(Person.class); ``` 将刷新person.html **person.html预览** ![](https://gitee.com/manyhf16/mybatis-generator/raw/master/img/2.png) ### 5) 远程格式化 有些数据并不是固定不变的,例如Person中的deptId(部门编号)来自于另一张表,这时候需要查询所有可用的部门信息来完成deptId的翻译。 **1.新建部门表** ```sql create table my_dept( id int primary key auto_increment, name varchar(32) ); -- 插入测试数据,略 ``` **2.新建部门实体** ```java // valueField表示该实体类哪个属性是key,textField表示该实体类哪个属性是value @RemoteSourceAdapter(valueField="id", textField="name") public class Dept{ private int id; private String name; // getter,setter方法 略 } ``` **3.为部门实体生成mapper以及controller** ```java new MapperGenerator.Builder() .mapperPackage("org.yihang.mapper") .nameStrategy(NameStrategy.CamelUnderscore.tablePrefix("my_")) .build() .process(Dept.class); new EasyUIGenerator.Builder() .setControllerPackage("org.yihang.controller") .setMapperPackage("org.yihang.mapper") .build() .process(Dept.class); ``` 生成结果中大部分代码与之前Person相同(如DeptMapper.xml,DeptMapper.java,DeptController.java,dept.html等),但注意在Dept实体类上添加的@RemoteSourceAdapter注解,它会在controller中多生成两个方法: ```java // 主要配合combobox使用,生成的json格式:[{"text":"财务部","value":1},{"text":"研发部","value":2}] @GetMapping("/dept/findAllCombo") public List> findAllCombo(){ List list = deptMapper.findAll(); List> nlist = new ArrayList<>(); for(Dept s:list){ Map o = new HashMap<>(); o.put("value", s.getId()); o.put("text", s.getName()); nlist.add(o); } return nlist; } // 主要配合formatter使用,生成的json格式:{"1":"财务部","2":"研发部"} @GetMapping("/dept/findAllKV") public Map findAllKV(){ List list = deptMapper.findAll(); Map map = new HashMap<>(); for(Dept s:list){ map.put(String.valueOf(s.getId()), s.getName()); } return map; } ``` **4.在Person实体类上添加@RemoteSource** ```java @RemoteSource(var="depts", value="/dept/findAllKV") // 本例只用到它 @RemoteSource(var="deptsCombobox", value="/dept/findAll") public class Person{ @DatagridColumn(title="部门", formatter = @Formatter(type=FormatterType.SOURCE,value="depts")) private int categoryId; // ... ... 略 } ``` 这样就把部门编号的formatter与RemoteSource联系起来了,重新运行EasyUIGenerator更新person.html页面。 **person.html预览** ![](https://gitee.com/manyhf16/mybatis-generator/raw/master/img/3.png) ### 6) 组合搜索 ### 7) 新增与修改