# 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预览**

**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预览**

### 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