diff --git a/README.md b/README.md
index 6969512214f2224d6d7bb924c52b2512027f1d4e..9fdf02c0e40637d147109d81825ae10825c9076a 100644
--- a/README.md
+++ b/README.md
@@ -1,38 +1,75 @@
-# robin
+# Robin
-#### 介绍
-robin是一个基于MyBatis提供增删改查功能的轻量级框架。
+## 介绍
+`Robin`是一个基于`MyBatis`框架, 提供基础的增删改查增强功能的轻量级框架。
Robin is a lightweight framework based on MyBatis that provides adding, deleting, modifying and querying capabilities
-#### 软件架构
-软件架构说明
+## 项目背景
+此项目参考了[mybatis-generator](http://mybatis.org/generator/)和[mybatis-plus](https://mybatis.plus/)。mybatis-generator会生成很多冗余代码,而mybatis-plus则不用生成冗余代码,功能也很强大,但是其对底层侵入太深,对mybatis的SqlSessionFactory进行了重写,不能直接集成到现有项目中使用;参考两者优秀之处`Robin诞生了,既不生成冗余代码,也不会对底层进行侵入,使用方便集成快速,适合快速开发,让coder将更多的时间用在业务逻辑上。
+### 此项目提供2个核心功能
+- 基础CRUD
+- 代码生成
-#### 安装教程
+### 基础CRUD `robin-base`
+通用Mapper和Service提供CRUD基本操作的支持 (`BaseMapper`, `BaseService` )
+### 代码生成 `robin-generator`
+提供代码生成功能,在表结构变动时可高效快速生成对应的实体对象
-1. xxxx
-2. xxxx
-3. xxxx
-#### 使用说明
+## 特性
+- **无侵入**:轻量级,只做增强不做改变,引入它不会对现有工程产生影响
+- **无损耗**:启动即会自动注入基本增删改查功能,性能无损耗,直接面向对象操作
+- **CRUD 操作**:内置BaseMapper、BaseService,无需任何配置直接继承 CRUD 操作
+- **支持 Lambda 形式调用**:通过 Lambda 表达式,方便的编写各类查询条件,无需再担心字段写错
+- **代码生成器**:可快速生成 Entity、Mapper、Service、Controller 层代码,支持自定义模板
+- **分页**:基于 MyBatis 物理分页,直接返回grus框架封装的分页对象, 同时也支持pagehelper分页插件
-1. xxxx
-2. xxxx
-3. xxxx
-#### 参与贡献
+## 软件架构
+```
+project 项目根目录
+├─robin-base 基础
+├─robin-generator 代码生成
+├─doc 文档
+└─
+```
-1. Fork 本仓库
-2. 新建 Feat_xxx 分支
-3. 提交代码
-4. 新建 Pull Request
+## 安装教程
+最新版本`last.version`=
+
+
+### 如仅需要增删改查的增强功能
+>仅依赖robin-base项目即可
+```xml
+
+ com.gitee.opensource4clive
+ robin-base
+ ${last.version}
+
+```
+### 如需要增删改查的增强功能和代码生成功能
+>依赖robin-base和robin-generator 其中 robin-generator的scrop建议设置为**test**
+```xml
+
+ com.gitee.opensource4clive
+ robin-generator
+ ${last.version}
+ test
+
+```
+## 项目文档
-#### 特技
+### [快速开始](doc/fast-start.md)
+
+### [CRUD 接口](doc/crud-interface.md)
+
+### [条件构造器](doc/conditional.md)
+
+### [代码生成器](doc/generator.md)
+
+### [常见问题](doc/faq.md)
+
+### [示例项目](https://gitee.com/opensource4clive/robin-example)
-1. 使用 Readme\_XXX.md 来支持不同的语言,例如 Readme\_en.md, Readme\_zh.md
-2. Gitee 官方博客 [blog.gitee.com](https://blog.gitee.com)
-3. 你可以 [https://gitee.com/explore](https://gitee.com/explore) 这个地址来了解 Gitee 上的优秀开源项目
-4. [GVP](https://gitee.com/gvp) 全称是 Gitee 最有价值开源项目,是综合评定出的优秀开源项目
-5. Gitee 官方提供的使用手册 [https://gitee.com/help](https://gitee.com/help)
-6. Gitee 封面人物是一档用来展示 Gitee 会员风采的栏目 [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/)
diff --git a/doc/conditional.md b/doc/conditional.md
new file mode 100644
index 0000000000000000000000000000000000000000..a9d10f4d3934eb4ab59e0e139d81437c3fc973d3
--- /dev/null
+++ b/doc/conditional.md
@@ -0,0 +1,214 @@
+# 条件构造器
+> - 不建议将带条件构造器的接口直接暴露出去,应写一个 DTO 进行传输
+> - 以下方法入参中的`R column`均表示数据库字段
+
+## Conditional 条件构造器
+
+### 创建并且条件
+
+```java
+// 创建条件: 如果条件列表为空则默认放入, 否则不放入
+Criteria createCriteria();
+// 创建Lambda条件: 如果条件列表为空则默认放入, 否则不放入
+LambdaCriteria createLambdaCriteria();
+```
+
+### 创建或者条件
+
+```java
+// 设置或者条件
+void or(GeneratedCriteria criteria);
+// 创建或者条件, 并放入条件列表
+Criteria or();
+```
+
+### 其他接口
+
+```java
+// 清除条件和设置值
+void clear();
+// 设置是否去重
+void setDistinct(boolean distinct);
+// 设置offset: limit ${offset}, ${limit}
+void setLimitStart(int limitStart);
+// 设置limit: limit ${offset}, ${limit}
+void setLimitEnd(int limitEnd);
+// 添加排序,如未添加排序,则默认排序是id DESC
+void addOrderBy(String columnName, boolean isAsc);
+```
+
+## Query 条件构造器, 继承于Conditional
+
+### 设置查询实体
+
+```java
+// 设置实体: 将所有非空字段加入eq条件列表
+void setEntity(T entity);
+// 此方法可与Criteria条件叠加使用
+```
+
+###
+
+----
+
+
+
+## Criteria 条件
+
+### eq
+
+``` java
+eq(R column, Object val)
+```
+- 等于 =
+- 例: `eq("name", "老王")`--->`name = '老王'`
+
+### ne
+``` java
+ne(R column, Object val)
+```
+- 不等于 <>
+- 例: `ne("name", "老王")`--->`name <> '老王'`
+
+### gt
+``` java
+gt(R column, Object val)
+```
+- 大于 >
+- 例: `gt("age", 18)`--->`age > 18`
+
+### ge
+``` java
+ge(R column, Object val)
+```
+- 大于等于 >=
+- 例: `ge("age", 18)`--->`age >= 18`
+
+### lt
+``` java
+lt(R column, Object val)
+```
+- 小于 <
+- 例: `lt("age", 18)`--->`age < 18`
+
+### le
+``` java
+le(R column, Object val)
+```
+- 小于等于 <=
+- 例: `le("age", 18)`--->`age <= 18`
+
+### between
+``` java
+between(R column, Object val1, Object val2)
+```
+- BETWEEN 值1 AND 值2
+- 例: `between("age", 18, 30)`--->`age between 18 and 30`
+
+### notBetween
+``` java
+notBetween(R column, Object val1, Object val2)
+```
+- NOT BETWEEN 值1 AND 值2
+- 例: `notBetween("age", 18, 30)`--->`age not between 18 and 30`
+
+### like
+``` java
+like(R column, Object val)
+```
+- LIKE '%值%'
+- 例: `like("name", "王")`--->`name like '%王%'`
+
+### notLike
+``` java
+notLike(R column, Object val)
+```
+- NOT LIKE '%值%'
+- 例: `notLike("name", "王")`--->`name not like '%王%'`
+
+### likeLeft
+``` java
+likeLeft(R column, Object val)
+```
+- LIKE '%值'
+- 例: `likeLeft("name", "王")`--->`name like '%王'`
+
+### likeRight
+``` java
+likeRight(R column, Object val)
+```
+- LIKE '值%'
+- 例: `likeRight("name", "王")`--->`name like '王%'`
+
+### isNull
+``` java
+isNull(R column)
+```
+- 字段 IS NULL
+- 例: `isNull("name")`--->`name is null`
+
+### isNotNull
+``` java
+isNotNull(R column)
+```
+- 字段 IS NOT NULL
+- 例: `isNotNull("name")`--->`name is not null`
+
+### in
+``` java
+in(R column, Collection> value)
+```
+- 字段 IN (value.get(0), value.get(1), ...)
+- 例: `in("age",{1,2,3})`--->`age in (1,2,3)`
+
+``` java
+in(R column, Object... values)
+```
+- 字段 IN (v0, v1, ...)
+- 例: `in("age", 1, 2, 3)`--->`age in (1,2,3)`
+
+### notIn
+``` java
+notIn(R column, Collection> value)
+```
+- 字段 NOT IN (value.get(0), value.get(1), ...)
+- 例: `notIn("age",{1,2,3})`--->`age not in (1,2,3)`
+
+``` java
+notIn(R column, Object... values)
+```
+- 字段 NOT IN (v0, v1, ...)
+- 例: `notIn("age", 1, 2, 3)`--->`age not in (1,2,3)`
+
+----
+
+## 示例
+
+```java
+// 创建条件构造器
+Example example = new ConditionExample<>();
+// 创建第一个条件:id in (1,2,3) and type is not null
+example.createCriteria().in("id", 1,2,3).isNotNull("name");
+// 创建第二个条件: 因为第二个条件起不会默认放入条件列表, title like %啄木鸟%
+LambdaCriteria criteria = example.createLambdaCriteria().like(User::getName, "啄木鸟");
+// 将第二个条件设置为或者条件
+example.or(criteria);
+// 创建第三个或者条件:timeCreated between '2020-09-11' and '2020-11-11'
+example.orLambdaCriteria().between(User::getCreatedAt, "2020-09-11", "2020-11-11");
+// 设置去重
+example.setDistinct(true);
+// 添加排序
+example.addOrderBy("username", true);
+example.addOrderBy("id", false);
+List list = userMapper.list(example);
+// 以上条件构造的SQL语句为:
+/*
+ SELECT DISTINCT `id`,`created_at`,`updated_at`,`username`,`password`,`name`
+ FROM `User`
+ WHERE ( `id` IN ( 1 , 2 , 3 ) and `name` IS NOT NULL )
+ OR ( `name` LIKE CONCAT('%','啄木鸟','%') )
+ OR ( `createdAt` BETWEEN '2020-09-11' and '2020-11-11' )
+ ORDER BY `username` ASC, `id` DESC;
+ */
+```
+
diff --git a/doc/crud-interface.md b/doc/crud-interface.md
new file mode 100644
index 0000000000000000000000000000000000000000..3dccc0da600c1ae92efef4469c328ea1b07153dc
--- /dev/null
+++ b/doc/crud-interface.md
@@ -0,0 +1,179 @@
+# CRUD 接口
+
+## Mapper CRUD 接口
+
+通用Mapper接口:`cn.cliveyuan.robin.base.BaseMapper.java`
+
+⚠️特别提醒:Mapper和xml中不能重载BaseMapper中的方法
+
+### 插入 Insert
+
+``` java
+// 选择性插入(仅插入非null字段)
+int insert(T entity);
+// 全字段插入(无论是否为null均进行插入)
+int insertAll(T entity);
+// 批量全字段插入(注:如表新加字段不为空时插入对象需要手动设置默认值)
+int batchInsert(List list);
+```
+
+### 删除 Delete
+
+``` java
+// 根据ID删除
+int delete(Long id);
+// 批量ID删除
+int batchDelete(List ids);
+// 根据条件删除
+int deleteByExample(Example example);
+```
+
+### 更新 Update
+
+``` java
+// 根据ID选择性更新
+int update(T entity);
+// 根据ID全字段更新 (无论是否为null均进行更新)
+int updateAll(T entity);
+// 根据条件选择性更新
+int updateByExample(T entity, Example example);
+// 根据条件全字段更新
+int updateByExampleAll(T entity, Example example);
+```
+
+### 获取 Get
+
+``` java
+// 根据ID获取实体
+T get(Long id);
+// 批量获取实体
+List batchGet(List ids);
+// 根据条件获取实体
+T getByExample(Example example);
+```
+
+### 查询数量 Count
+
+``` java
+// 根据条件数量查询
+int count(Example example);
+```
+
+### 查询列表 List
+
+``` java
+// 根据条件列表查询
+List list(Example example);
+```
+
+
+
+注:`Example`和`Query`都继承于`Conditional`, 在不同层面使用不同的接口:
+
+- mapper层: `Example` -> `ConditionExample`
+- service层: Query -> `QueryExample` , `PageQueryExample`
+
+示例
+
+```java
+// mapper: Example
+Example example = new ConditionExample<>();
+userMapper.getByExample(example);
+
+// service: Query
+Query query = new QueryExample<>();
+userService.getByExample(query);
+
+Query query1 = new PageQueryExample<>();
+userService.page(query1);
+```
+
+
+
+---
+
+
+
+## Service CRUD 接口
+
+通用Service接口:`cn.cliveyuan.robin.base.BaseService.java`
+
+⚠️特别提醒:继承BaseService前提需要对应的Mapper继承BaseMapper
+
+### 插入 Insert
+
+``` java
+// 选择性插入(仅插入非null字段)
+int insert(T entity);
+// 全字段插入(无论是否为null均进行插入)
+int insertAll(T entity);
+// 批量全字段插入(注:如表新加字段不为空时插入对象需要手动设置默认值)
+int batchInsert(List list);
+```
+### 删除 Delete
+
+``` java
+// 根据ID删除
+int delete(Long id);
+// 批量ID删除
+int batchDelete(List ids);
+// 根据条件删除
+int deleteByExample(Query query);
+```
+### 更新 Update
+
+``` java
+// 根据ID选择性更新
+int update(T entity);
+// 根据ID全字段更新 (无论是否为null均进行更新)
+int updateAll(T entity);
+// 根据条件选择性更新
+int updateByExample(T entity, Query query);
+// 根据条件全字段更新
+int updateByExampleAll(T entity, Query query);
+```
+### 保存 Save
+
+> `entity.id == null` -> 插入
+>
+> `entity.id != null` -> 更新
+
+``` java
+// 选择性保存
+int save(T entity);
+// 全字段保存
+int saveAll(T entity);
+```
+### 获取 Get
+
+``` java
+// 根据ID获取实体
+T get(Long id);
+// 批量获取实体
+List batchGet(List ids);
+// 根据条件获取实体
+T getByExample(Query query);
+```
+
+### 查询数量 Count
+
+``` java
+// 根据条件数量查询
+int count(Query query);
+```
+
+### 查询列表 List
+
+``` java
+// 根据条件列表查询
+List list(Query query);
+```
+### 查询分页 Page
+
+``` java
+// 根据条件查询分页
+Pagination page(PageQueryExample query);
+```
+
+
+
diff --git a/doc/faq.md b/doc/faq.md
new file mode 100644
index 0000000000000000000000000000000000000000..9fb2b4f0e05a7be3a765b268f91deb375d957a2b
--- /dev/null
+++ b/doc/faq.md
@@ -0,0 +1,78 @@
+# 常见问题
+
+
+
+## TINYINT(1)类型
+
+1个长度的tinyint为什么转为Boolean类型而不是Integer?
+
+> Mysql官方参考文档关于布尔类型的说明:BOO, BOOLEAN
+> These types are synonyms(同义词) for TINYINT(1). A value of zero is considered(认为是) false. Nonzero(不为0) values are considered true.
+
+ 解决方法:
+
+ 1. 如果需要将tinyint(1)转为Integer类型需要将配置文件中`jdbcConnection`的`tinyInt1isBit`属性显式设置为`false`
+ 2. 将数据表tinyint(1)改为tinyint(2)
+
+注:tinyint(1) 如果加了`unsigned `则jdbc读取到的长度是3,对应转换为Integer类型
+
+----
+
+
+
+## 常见异常
+
+### 1. Mapped Statements collection already contains value for
+ ```java
+java.lang.IllegalArgumentException: Mapped Statements collection already contains value for xxx.XxMapper.xxMethod
+ ```
+
+原因:
+
+a. Mapper继承了BaseMapper之后,如果在Mapper中重载了BaseMapper中的方法,在应用启动时会出现如上异常;
+
+b. Xml Mapper中定义了与BaseMapper同名sql的id
+
+解决: 重命名该方法
+
+### 2. No qualifying bean of type
+
+```java
+NoSuchBeanDefinitionException: No qualifying bean of type 'cn.cliveyuan.robin.base.BaseMapper' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)
+```
+
+原因:Mapper所在的包未被扫描到
+
+解决:将其配置到`Application.java`的`@MapperScan`中
+
+### 3. Invalid bound statement (not found)
+
+```java
+org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): xx.XxxService.xxMethod
+```
+
+原因:
+- 1. Mapper Xml文件未被扫描
+- 2. Mapper Xml中无对应方法
+- 3. Mapper Xml与Mapper的ResultType不一致
+- 4. MapperScan未直接配置Mapper的包,可能只配置了Mapper的父包
+
+解决:
+- 1. `application.properties`中配置xml路径 如:`mybatis.mapper-locations=classpath*:mapper/*.xml`
+- 2. 检查并加入对应方法
+- 3. 检查并使其一致
+- 4. 配置`@MapperScan`到具体的Mapper所在的包,如果存在多个mapper包可考虑使用通配符
+
+### 4. BaseMapper could not be found
+
+```java
+Field baseMapper in cn.cliveyuan.robin.base.BaseServiceImpl required a bean of type 'cn.cliveyuan.robin.base.BaseMapper' that could not be found.
+```
+
+原因: 只继承了BaseService没有继承BaseMapper
+
+解决:对应的Mapper需继承BaseMapper
+
+
+----
+
diff --git a/doc/fast-start.md b/doc/fast-start.md
new file mode 100644
index 0000000000000000000000000000000000000000..c76a1012401b08066f026046a1e47a41145cc985
--- /dev/null
+++ b/doc/fast-start.md
@@ -0,0 +1,219 @@
+## 快速开始
+
+这里以一个空的工程来示例
+
+#### 创建数据库和表
+
+> 以本地数据库为例,库名: robin_example
+
+```sql
+/*创建数据库*/
+CREATE DATABASE `robin_example` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
+/*创建用户表*/
+CREATE TABLE `t_user` (
+ `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
+ `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
+ `updated_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
+ `username` varchar(50) NOT NULL COMMENT '用户名',
+ `password` varchar(100) NOT NULL DEFAULT '' COMMENT '密码',
+ `name` varchar(50) NOT NULL COMMENT '姓名',
+ PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户';
+```
+
+#### 创建Maven项目并添加依赖
+
+引入 Spring Boot Starter 父工程
+
+```xml
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 2.3.4.RELEASE
+
+```
+
+引入相关依赖 最新版
+
+
+
+```xml
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+
+ org.mybatis.spring.boot
+ mybatis-spring-boot-starter
+ 2.1.2
+
+
+
+ mysql
+ mysql-connector-java
+ runtime
+
+
+
+ com.gitee.opensource4clive
+ robin-base
+ 1.2.0
+
+
+ com.gitee.opensource4clive
+ robin-generator
+ 1.2.0
+ test
+
+
+
+ org.projectlombok
+ lombok
+ 1.18.12
+
+
+
+ io.springfox
+ springfox-boot-starter
+ 3.0.0
+
+
+
+ org.hibernate.validator
+ hibernate-validator
+ 6.1.5.Final
+
+
+
+```
+
+#### 配置项目
+
+在`${项目根目录}/src/main/resources/application.yml`中配置基本信息
+
+> 对应数据库账号信息可改为自己的
+
+```yaml
+server:
+ port: 8080
+ servlet:
+ context-path: /
+ tomcat:
+ uri-encoding: UTF-8
+
+spring:
+ datasource:
+ driver-class-name: com.mysql.cj.jdbc.Driver
+ url: jdbc:mysql://localhost:3306/robin_example?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai&allowMultiQueries=true
+ username: root
+ password: 123456
+ jackson:
+ date-format: yyyy-MM-dd HH:mm:ss
+ time-zone: GMT+8
+
+mybatis:
+ mapper-locations: classpath:mapper/*Mapper.xml
+ configuration:
+ map-underscore-to-camel-case: true
+
+logging:
+ level:
+ cn:
+ cliveyuan:
+ robinexample:
+ mapper: debug
+
+```
+
+添加启动类`Application.java`
+
+```java
+@SpringBootApplication
+@MapperScan(basePackages = "cn.cliveyuan.robinexample.mapper")
+public class Application {
+ public static void main(String[] args) {
+ SpringApplication.run(Application.class, args);
+ }
+}
+```
+
+#### 编码
+
+编写实体类`User.java`
+
+```java
+@Data
+@TableName("t_user")
+public class User {
+ /**
+ * ID 主键
+ */
+ @TableId
+ private Long id;
+ /**
+ * 创建时间
+ */
+ @TableField(value = "created_at", ignoreSaving = true)
+ private Date createdAt;
+ /**
+ * 修改时间
+ */
+ @TableField(value = "updated_at", ignoreSaving = true)
+ private Date updatedAt;
+ /**
+ * 用户名
+ */
+ private String username;
+ /**
+ * 密码
+ */
+ private String password;
+ /**
+ * 姓名
+ */
+ private String name;
+}
+```
+
+编写Mapper类`UserMapper.java`
+
+```java
+public interface UserMapper extends BaseMapper {
+ // 如有其他方法直接书写其中即可
+ // User selectOne(Long id);
+}
+```
+
+同时也支持`@Mapper`注解
+
+#### 开始使用
+
+添加测试类
+
+```java
+@RunWith(SpringRunner.class)
+@SpringBootTest
+public class SampleTest {
+ @Resource
+ private UserMapper userMapper;
+ @Test
+ public void testList() {
+ Example example = new ConditionExample<>();
+ List list = userMapper.list(example);
+ Assert.assertTrue(list.size() > 0);
+ list.forEach(System.out::println);
+ }
+}
+```
+
+#### [示例项目源码](https://gitee.com/opensource4clive/robin-example)
+
diff --git a/doc/generator.md b/doc/generator.md
new file mode 100644
index 0000000000000000000000000000000000000000..9fa00879e3eb91d444b07c541e67663996c41f24
--- /dev/null
+++ b/doc/generator.md
@@ -0,0 +1,104 @@
+# 代码生成器
+
+## 简介
+快速生成 Entity、Mapper、Mapper XML、Service、Controller 等各个模块的代码,极大的提升了开发效率
+
+关于覆盖:
+ - Entity文件: Entity是与数据库表结构保持一致的, 尽量不要去修改, 如需扩展请添加Bean去继承它, 所以每次生成都会覆盖Entity
+ - 其他文件: 其他文件一次生成之后可以添加属性和方法, 所以每次生成不会覆盖
+
+## 快速开始
+在前面那个项目上添加代码生成器
+
+### 添加依赖
+
+引入代码生成器,`scope`设置为`test`
+```xml
+
+ com.gitee.opensource4clive
+ robin-generator
+ ${last.version}
+ test
+
+```
+
+### 配置
+添加生成配置文件`code-generator.xml`, 建议放到测试资源目录`resources/`
+```xml
+
+
+
+
+
+
+ true
+ true
+ true
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+[查看配置文档](xml-config.md)
+
+### 开始使用
+
+创建生成测试单元测试文件`CodeGeneratorTest.java`
+
+```java
+public class CodeGeneratorTest {
+ @Test
+ public void generate() {
+ MybatisGenerator.builder().configFilePath().build().generate();
+ // 若配置文件名非code-generator.xml, 或配置文件路径不在resources下,需要指定配置文件路径
+ // 如在resources/robin-cg.xml
+ // MybatisGenerator.builder().configFilePath("/robin-cg.xml").build().generate();
+ // 如在/Users/clive/cg-cofnig.xml
+ // MybatisGenerator.builder().configFilePath("/Users/clive/cg-cofnig.xml").build().generate();
+ }
+}
+```
+
+注:配置文件名为`code-generator.xml`时无需指定配置文件路径,否则需要指定`configFilePath`
+
diff --git a/doc/index.md b/doc/index.md
new file mode 100644
index 0000000000000000000000000000000000000000..0e51c22bc267b8b75478eda9cebce38abafeb0b5
--- /dev/null
+++ b/doc/index.md
@@ -0,0 +1,152 @@
+# 简介
+
+`code-generator`是一个简单的代码生成工具,在不侵入框架底层的前提下,达到简化开发、提高开发效率的目的。
+
+## 项目背景
+
+此项目分为两个部分:第一个部分为通用Mapper和Service提供CRUD基本操作的支持;第二个部分是代码生成功能,为表结构变动时提供高效快速生成对应的实体对象。
+此项目参考了[mybatis-generator](http://mybatis.org/generator/)和[mybatis-plus](https://mybatis.plus/), 取其精华并与grus框架融合。mybatis-generator会生成很多冗余代码,而mybatis-plus则不用生成冗余代码,功能也很强大,但是其对底层侵入太深,对mybatis的SqlSessionFactory进行了重写,不能直接集成到我司项目中使用;参考两者优秀之处code-generator诞生了,既不需要生成冗余代码,也不需要对底层侵入,使用方便集成快速,适合快速开发,将更多的时间用在业务逻辑上。
+
+## 特性
+- **无侵入**:只做增强不做改变,引入它不会对现有工程产生影响
+- **无损耗**:启动即会自动注入基本增删改查功能,性能无损耗,直接面向对象操作
+- **CRUD 操作**:内置通用 Mapper、通用 Service,仅仅通过少量配置即可实现单表大部分 CRUD 操作,更有强大的条件构造器,满足各类使用需求
+- **支持 Lambda 形式调用**:通过 Lambda 表达式,方便的编写各类查询条件,无需再担心字段写错
+- **代码生成器**:可快速生成 Entity、Mapper、Service、Controller 层代码,支持自定义模板
+- **分页**:基于 MyBatis 物理分页,直接返回grus框架封装的分页对象, 同时支持pagehelper分页插件
+
+## 快速开始
+
+这里以一个空的工程来示例
+
+#### 添加依赖
+
+引入 Grus Boot Starter 父工程:
+
+```xml
+
+ com.ciicgat.grus.boot
+ grus-boot-starter-parent
+ 2020.12.1.RELEASE
+
+```
+
+引入服务端应用常用的依赖
+
+```xml
+
+ grus-boot-starter-server-general
+ com.ciicgat.grus.boot
+
+```
+
+引入数据依赖
+
+```xml
+
+ com.ciicgat.grus.boot
+ grus-boot-starter-data
+
+```
+
+引入测试依赖
+
+```xml
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+```
+
+#### 配置
+
+在`application.properties`中配置基本信息
+
+```properties
+spring.application.name=ecappetc
+server.port=8088
+server.tomcat.uri-encoding=UTF-8
+logging.level.com.ciicgat.grusgenerator.codegenerator.example.mapper=debug
+spring.jackson.date-format=yyyy-MM-dd HH:mm:ss
+spring.jackson.time-zone=GMT+8
+grus.feign.log-req=true
+grus.feign.log-resp=true
+mybatis.mapper-locations=classpath*:mapper/*.xml
+
+```
+
+添加启动类`Application.java`
+
+```java
+@SpringBootApplication
+@MapperScan("com.ciicgat.grusgenerator.codegenerator.example.mapper")
+public class Application {
+ public static void main(String[] args) {
+ SpringApplication.run(Application.class, args);
+ }
+}
+```
+
+#### 编码
+
+编写实体类`ShopTip.java`
+
+```java
+@Data
+@TableName("ShopTip")
+public class ShopTip {
+ @TableId
+ private Long id;
+ @TableField(ignoreSaving = true)
+ private Date timeCreated;
+ @TableField(ignoreSaving = true)
+ private Date timeModified;
+ private Long ecappId;
+ private Integer type;
+ private String title;
+ private String content;
+ private Integer enable;
+}
+```
+
+编写Mapper类`ShopTipMapper.java`
+
+```java
+public interface ShopTipMapper extends BaseMapper {
+ // 如有其他方法直接书写其中即可
+ // ShopTip selectOne(Long id);
+}
+```
+
+同时也支持`@Mapper`注解
+
+#### 开始使用
+
+添加测试类
+
+```java
+@RunWith(SpringRunner.class)
+@SpringBootTest
+public class SampleTest {
+ @Resource
+ private ShopTipMapper shopTipMapper;
+ @Test
+ public void testList() {
+ Example example = new ConditionExample<>();
+ List list = shopTipMapper.list(example);
+ Assert.assertTrue(list.size() > 0);
+ list.forEach(System.out::println);
+ }
+}
+```
+
+## [CRUD 接口](doc/code-generator/crud-interface.md)
+
+## [条件构造器](doc/code-generator/conditional.md)
+
+## [代码生成器](doc/code-generator/generator.md)
+
+## [读写分离](doc/code-generator/read-write-separation.md)
+
+## [常见问题](doc/code-generator/faq.md)
diff --git a/doc/xml-config.md b/doc/xml-config.md
new file mode 100644
index 0000000000000000000000000000000000000000..81106506c302236e7e3fa23f06f72568a3973969
--- /dev/null
+++ b/doc/xml-config.md
@@ -0,0 +1,103 @@
+# 生成器配置文件 code-generator.xml
+
+## code-generator 根元素
+
+配置从此元素开始
+
+### baseConfig 基础配置
+
+#### property 属性
+
+- **enableSwagger** 启用Swagger,在生成的DTO和Controller中使用Swagger注解,需要添加对应的maven依赖
+- **enableValidation** 启用验证,在生成的DTO和Controller中使用验证注解,根据数据库表字段添加@NotNull,@Length注解,需要添加对应的maven依赖
+- **disableUpdatingMapperXml** 禁用更新`MapperXml`文件,每次生成会同步更新mapper中`id=BaseColumnList`和`id=BaseResultMap`内容,如果不需要更新此项设置为true禁用更新
+- **enableMapperAnnotation** 在生成的Mapper.java中添加@Mapper注解,默认不启用
+
+### jdbcConnection JDBC连接
+
+| 属性 | 名称 | 是否必填 | 描述 |
+| ------------- | ----------- | -------- | ------------------------------------------------------------ |
+| driverClass | 驱动类 | 是 | jdbc驱动类全路径 |
+| host | 主机地址 | 是 | 数据库主机地址,如非默认端口`3306`需带上端口号 |
+| database | 数据库 | 是 | 数据库名称 |
+| username | 用户名 | 是 | 数据库用户名 |
+| password | 密码 | 是 | 用户名密码 |
+| tinyInt1isBit | tinyint转换 | 否 | 默认为true, tinyint(1)类型转Boolean; 为false时,tinyint(1)类型转为Integer |
+
+### javaModelGenerator 实体对象生成器
+
+| 属性 | 名称 | 是否必填 | 描述 |
+| ------------- | -------------- | -------- | ------------------------------------------------------------ |
+| targetPackage | 包路径 | 是 | 文件所在的包全路径(小数点分隔的包名) |
+| codePath | 代码地址 | 是 | 文件所在相对项目根目录的路径 |
+| disabled | 是否禁用 | 否 | 禁用时,将跳过此模块生成 |
+| templatePath | 自定义模板路径 | 否 | 模板路径是相对路径,需放于resources下,同名即覆盖,不同名需指定路径 |
+| suffix | 自定义后缀 | 否 | 为生成的模块指定固定后缀,此属性对Entity不生效,Entity自定义后缀参考table标签 |
+
+注:如果需要自定义代码模板,需要从默认模板复制一份到本地项目进行修改,复制后选择**无格式粘贴**,否则格式会混乱
+
+默认模板文件路径
+
+- 实体类 **entity** templates/entity.java.ftl
+- xml映射 **mapperXml** templates/mapper.xml.ftl
+- Mapper **mapperJava** templates/mapper.java.ftl
+- 服务 **service** templates/service.java.ftl
+- 服务实现 **serviceImpl** templates/serviceimpl.java.ftl
+- 控制器 **controller** templates/controller.java.ftl
+- 转换类 **dto** templates/dto.java.ftl
+
+### sqlMapGenerator XMLMapper生成器
+
+同上
+
+默认后缀`Mapper`
+
+### javaClientGenerator JavaMapper生成器
+
+同上
+
+默认后缀`Mapper`
+
+### serviceGenerator Service生成器
+
+同上
+
+默认后缀`Service`
+
+### controllerGenerator Controller生成器
+
+同上
+
+默认后缀`Controller`
+
+### dtoGenerator Controoer生成器
+
+同上;用于对象转换DTO,依附于controllerGenerator,若生成controllerc才可以配置此项,否则不生效
+
+默认后缀`DTO`
+
+### tables 要生成的表集合
+
+| 属性 | 名称 | 是否必填 | 描述 |
+| ---------------- | ------------ | -------- | ------------------------------------------------------- |
+| all | 是否所有表 | 否 | 为true时,将读取数据库所有表, 将忽略其所有`table`子元素 |
+| ignoreColumns | 忽略的列 | 否 | 所有表需要忽略的列,多个以逗号分隔 |
+| createTimeColumn | 创建时间字段 | 否 | 默认为`created_at` |
+| updateTimeColumn | 更新时间字段 | 否 | 默认为`updated_at` |
+| entityObjectSuffix | 实体后缀 | 否 | 给生成的实体加上统一后缀, 如 `DO` -> UserDO |
+
+#### table 要生成的表
+
+| 属性 | 名称 | 是否必填 | 描述 |
+| ---------------- | ---------- | -------- | ---------------------------------------- |
+| tableName | 表名 | 是 | 表名 |
+| entityObjectName | 实体对象名 | 否 | 如果为空,则以表名大写驼峰作为实体对象名 |
+| ignoreColumns | 忽略的列 | 否 | 此表需要忽略的列,多个以逗号分隔 |
+
+注:
+
+- 忽略的列将不在生成的Entity中展示,一般为不需要操作的可空列,`table`的`ignoreColumns`属性会继承`tables`的
+- `entityObjectName`和`entityObjectSuffix`都存在时,生成的实体名为`${entityObjectName}${entityObjectSuffix}`
+
+
+
diff --git a/pom.xml b/pom.xml
index 2c7854866974a4313944ea9943c1ca3bf1986778..2c1c5091a7333c1b688b319f954db17d871706d5 100644
--- a/pom.xml
+++ b/pom.xml
@@ -5,7 +5,7 @@
com.gitee.opensource4clive
robin
pom
- 1.1.0
+ 1.2.0
robin
Robin is a lightweight framework based on MyBatis that provides adding, deleting, modifying and querying capabilities.
https://gitee.com/opensource4clive/robin
diff --git a/robin-base/pom.xml b/robin-base/pom.xml
index 79bc93be5d7095a58dfb2584a047ba10ef5073ec..fac9fa3580df799db549107215962998503f2da2 100644
--- a/robin-base/pom.xml
+++ b/robin-base/pom.xml
@@ -3,11 +3,11 @@
4.0.0
robin-base
jar
- 1.1.0
+ 1.2.0
com.gitee.opensource4clive
robin
- 1.1.0
+ 1.2.0
diff --git a/robin-base/src/main/java/cn/cliveyuan/robin/base/condition/PageQueryExample.java b/robin-base/src/main/java/cn/cliveyuan/robin/base/condition/PageQueryExample.java
index ce60037fc2842530aea01773e552111c6b45d5f3..76f0eae0a1f550927266e6c779194a14c976e066 100644
--- a/robin-base/src/main/java/cn/cliveyuan/robin/base/condition/PageQueryExample.java
+++ b/robin-base/src/main/java/cn/cliveyuan/robin/base/condition/PageQueryExample.java
@@ -4,6 +4,11 @@
package cn.cliveyuan.robin.base.condition;
+import cn.cliveyuan.robin.base.common.PageQueryRequest;
+import cn.cliveyuan.robin.base.util.BeanCopyUtils;
+
+import java.util.Objects;
+
/**
* 分页查询示例
*
@@ -31,6 +36,19 @@ public class PageQueryExample extends QueryExample {
*/
private Integer pageSize = DEFAULT_PAGE_SIZE;
+ public PageQueryExample() {
+ }
+
+ public PageQueryExample(PageQueryRequest> pageQueryRequest, Class tClass) {
+ if (Objects.nonNull(pageQueryRequest)) {
+ this.setPageNo(pageQueryRequest.getPageNo());
+ this.setPageSize(pageQueryRequest.getPageSize());
+ if (pageQueryRequest.getEntity() != null) {
+ this.setEntity(BeanCopyUtils.copy(pageQueryRequest.getEntity(), tClass));
+ }
+ }
+ }
+
public Integer getPageNo() {
return pageNo;
}
diff --git a/robin-base/src/main/java/cn/cliveyuan/robin/base/util/BeanCopyUtils.java b/robin-base/src/main/java/cn/cliveyuan/robin/base/util/BeanCopyUtils.java
index 77d988f0c01446da4303fb7836ba52097ff802e3..50d836dcd610e3a2a1693852a1ca8665a06209c0 100644
--- a/robin-base/src/main/java/cn/cliveyuan/robin/base/util/BeanCopyUtils.java
+++ b/robin-base/src/main/java/cn/cliveyuan/robin/base/util/BeanCopyUtils.java
@@ -27,7 +27,10 @@ public class BeanCopyUtils {
* @return
*/
public static T copy(Object source, Class targetClass) {
- AssertUtils.notNull(source, "source is required");
+ // AssertUtils.notNull(source, "source is required");
+ if (Objects.isNull(source)) {
+ return null;
+ }
AssertUtils.notNull(targetClass, "targetClass is required");
try {
T targetObject = targetClass.getDeclaredConstructor().newInstance();
diff --git a/robin-generator/pom.xml b/robin-generator/pom.xml
index ab1c007b6ebdf8c5ac7d8535546a5ea75583f7fb..64a1ebc1c1cc487752c28b75fcbd0c1d2305044d 100644
--- a/robin-generator/pom.xml
+++ b/robin-generator/pom.xml
@@ -2,13 +2,13 @@
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
4.0.0
robin-generator
- 1.1.0
+ 1.2.0
jar
com.gitee.opensource4clive
robin
- 1.1.0
+ 1.2.0
@@ -88,7 +88,6 @@
com.gitee.opensource4clive
robin-base
- test
diff --git a/robin-generator/src/main/java/cn/cliveyuan/robin/generator/core/CodeGeneratorXmlConfig.java b/robin-generator/src/main/java/cn/cliveyuan/robin/generator/core/CodeGeneratorXmlConfig.java
index 2fc27013864620e492d577ca0293104a9e2c4cfd..2e49b8abbc08b5f317ea32aed57669a668073f2a 100644
--- a/robin-generator/src/main/java/cn/cliveyuan/robin/generator/core/CodeGeneratorXmlConfig.java
+++ b/robin-generator/src/main/java/cn/cliveyuan/robin/generator/core/CodeGeneratorXmlConfig.java
@@ -31,11 +31,18 @@ public class CodeGeneratorXmlConfig implements Serializable {
@Data
@Builder
public static class BaseConfig {
+ // 启用Lombok
private boolean enableLombok;
+ // 启用swagger
private boolean enableSwagger;
+ // 启用验证
private boolean enableValidation;
+ // 启用读写分离
private boolean enableReadWriteSeparation;
+ // 禁用更新MapperXml字段
private boolean disableUpdatingMapperXml;
+ // 启用@Mapper注解
+ private boolean enableMapperAnnotation;
}
@Data
diff --git a/robin-generator/src/main/java/cn/cliveyuan/robin/generator/core/GeneratorContextResolver.java b/robin-generator/src/main/java/cn/cliveyuan/robin/generator/core/GeneratorContextResolver.java
index ff614bd951c3c27f6dc6bee7e076480ab674e829..ba51c211e2d66caf4c1614353315e10575e9ada5 100644
--- a/robin-generator/src/main/java/cn/cliveyuan/robin/generator/core/GeneratorContextResolver.java
+++ b/robin-generator/src/main/java/cn/cliveyuan/robin/generator/core/GeneratorContextResolver.java
@@ -211,6 +211,7 @@ public class GeneratorContextResolver {
case "enableValidation": baseConfig.setEnableValidation("true".equalsIgnoreCase(property.getStringValue())); break;
case "enableReadWriteSeparation": baseConfig.setEnableReadWriteSeparation("true".equalsIgnoreCase(property.getStringValue())); break;
case "disableUpdatingMapperXml": baseConfig.setDisableUpdatingMapperXml("true".equalsIgnoreCase(property.getStringValue())); break;
+ case "enableMapperAnnotation": baseConfig.setEnableMapperAnnotation("true".equalsIgnoreCase(property.getStringValue())); break;
}
}
}
diff --git a/robin-generator/src/main/resources/templates/controller.java.ftl b/robin-generator/src/main/resources/templates/controller.java.ftl
index c7d98740126b7cf6c7129558ffad0ea8de1f3f3f..4f61efe2915da7d8de83a7460f2370a5863cae2b 100644
--- a/robin-generator/src/main/resources/templates/controller.java.ftl
+++ b/robin-generator/src/main/resources/templates/controller.java.ftl
@@ -1,8 +1,3 @@
-/*
- * Copyright 2007-${.now?string('yyyy')}, CIIC Guanaitong, Co., Ltd.
- * All rights reserved.
- */
-
package ${controllerPackage};
import ${entityPackage}.${entity.entityName};
@@ -45,10 +40,8 @@ public class ${entity.fileName} {
[#if baseConfig.enableSwagger]
@ApiOperation("保存")
[/#if]
- public ApiResponse save([#if baseConfig.enableValidation]@Validated[/#if] ${entity.upperCamelName}${dtoSuffix} request) {
- ${entity.entityName} entity = BeanCopyUtils.copy(request, ${entity.entityName}.class);
- ${entity.lowerCamelName}${serviceSuffix}.save(entity);
- return ApiResponse.success(entity.getId());
+ public ApiResponse save([#if baseConfig.enableValidation]@Validated[/#if] ${entity.upperCamelName}${dtoSuffix} request) {
+ return ApiResponse.success(${entity.lowerCamelName}${serviceSuffix}.save(BeanCopyUtils.copy(request, ${entity.entityName}.class)) > 0);
}
@PostMapping("delete")
@@ -72,12 +65,6 @@ public class ${entity.fileName} {
@ApiOperation("分页查询")
[/#if]
public ApiResponse> page(@RequestBody PageQueryRequest<${entity.upperCamelName}${dtoSuffix}> request) {
- PageQueryExample<${entity.entityName}> query = new PageQueryExample<>();
- query.setPageNo(request.getPageNo());
- query.setPageSize(request.getPageSize());
- if (request.getEntity() != null) {
- query.setEntity(BeanCopyUtils.copy(request.getEntity(), ${entity.entityName}.class));
- }
- return ApiResponse.success(BeanCopyUtils.copyPagination(${entity.lowerCamelName}${serviceSuffix}.page(query), ${entity.upperCamelName}${dtoSuffix}.class));
+ return ApiResponse.success(BeanCopyUtils.copyPagination(${entity.lowerCamelName}${serviceSuffix}.page(new PageQueryExample<>(request, ${entity.entityName}.class)), ${entity.upperCamelName}${dtoSuffix}.class));
}
}
diff --git a/robin-generator/src/main/resources/templates/dto.java.ftl b/robin-generator/src/main/resources/templates/dto.java.ftl
index c1b174ff0271b51a0e2cf4ab5d2578aff1b2f6ae..724151fbd718a53dac36ac244b3ce176b53dc430 100644
--- a/robin-generator/src/main/resources/templates/dto.java.ftl
+++ b/robin-generator/src/main/resources/templates/dto.java.ftl
@@ -1,8 +1,3 @@
-/*
- * Copyright 2007-${.now?string('yyyy')}, CIIC Guanaitong, Co., Ltd.
- * All rights reserved.
- */
-
package ${dtoPackage};
[#if baseConfig.enableSwagger]
diff --git a/robin-generator/src/main/resources/templates/entity.java.ftl b/robin-generator/src/main/resources/templates/entity.java.ftl
index 5b2e612c6cfc0b189a362527d71cf782745ca360..8f942c4b00de21b66c1225a952f07443a9534df6 100644
--- a/robin-generator/src/main/resources/templates/entity.java.ftl
+++ b/robin-generator/src/main/resources/templates/entity.java.ftl
@@ -1,8 +1,3 @@
-/*
- * Copyright 2007-${.now?string('yyyy')}, CIIC Guanaitong, Co., Ltd.
- * All rights reserved.
- */
-
package ${entityPackage};
import cn.cliveyuan.robin.base.annotation.TableField;
diff --git a/robin-generator/src/main/resources/templates/mapper.java.ftl b/robin-generator/src/main/resources/templates/mapper.java.ftl
index 7b939c6083c6efd9a04df01d71236a88c70ff176..2596b604819b0bcffc55bd6e596ac92412135c93 100644
--- a/robin-generator/src/main/resources/templates/mapper.java.ftl
+++ b/robin-generator/src/main/resources/templates/mapper.java.ftl
@@ -1,16 +1,13 @@
-/*
- * Copyright 2007-${.now?string('yyyy')}, CIIC Guanaitong, Co., Ltd.
- * All rights reserved.
- */
-
package ${mapperPackage};
import ${entityPackage}.${entity.entityName};
-import cn.cliveyuan.robin.base.BaseMapper;
+import cn.cliveyuan.robin.base.BaseMapper;[#if baseConfig.enableMapperAnnotation]
+ import org.apache.ibatis.annotations.Mapper;[/#if]
/**
* ${entity.comment} Mapper
- */
+ */[#if baseConfig.enableMapperAnnotation]
+ @Mapper[/#if]
public interface ${entity.fileName} extends BaseMapper<${entity.entityName}> {
}
diff --git a/robin-generator/src/main/resources/templates/mapper.xml.ftl b/robin-generator/src/main/resources/templates/mapper.xml.ftl
index 323a6aabd49daf3c44a7ec423104641582a627fd..15c24b321776f347bdbac5ad3d878c35a947d3ac 100644
--- a/robin-generator/src/main/resources/templates/mapper.xml.ftl
+++ b/robin-generator/src/main/resources/templates/mapper.xml.ftl
@@ -1,8 +1,4 @@
-
diff --git a/robin-generator/src/main/resources/templates/service.java.ftl b/robin-generator/src/main/resources/templates/service.java.ftl
index dcf8af008b804eb69ec7bbfbbe7882d1d4a23a95..68e1bce425c458cd04a350945e375a4cc23db1ab 100644
--- a/robin-generator/src/main/resources/templates/service.java.ftl
+++ b/robin-generator/src/main/resources/templates/service.java.ftl
@@ -1,8 +1,3 @@
-/*
- * Copyright 2007-${.now?string('yyyy')}, CIIC Guanaitong, Co., Ltd.
- * All rights reserved.
- */
-
package ${servicePackage};
import cn.cliveyuan.robin.base.BaseService;
diff --git a/robin-generator/src/main/resources/templates/serviceimpl.java.ftl b/robin-generator/src/main/resources/templates/serviceimpl.java.ftl
index d5b086a04b9592e94f8eacffa29ec68c10220a68..b9eadf0268caa4c3999708015eb4ad8497db1f53 100644
--- a/robin-generator/src/main/resources/templates/serviceimpl.java.ftl
+++ b/robin-generator/src/main/resources/templates/serviceimpl.java.ftl
@@ -1,8 +1,3 @@
-/*
- * Copyright 2007-${.now?string('yyyy')}, CIIC Guanaitong, Co., Ltd.
- * All rights reserved.
- */
-
package ${serviceImplPackage};
import cn.cliveyuan.robin.base.BaseServiceImpl;
diff --git a/robin-generator/src/test/resources/code-generator.xml b/robin-generator/src/test/resources/code-generator.xml
index dfb414895e384c938b4b61aee35b7f6fff92b374..2b3bcfc2e10458b6d6972232361f8364888201e4 100755
--- a/robin-generator/src/test/resources/code-generator.xml
+++ b/robin-generator/src/test/resources/code-generator.xml
@@ -1,12 +1,13 @@
-
+
true
true
+ false
diff --git a/update_versions.sh b/update_versions.sh
index 61de130efd218465e2dc7f682915523293d7172c..9af421c73504fd5379580c38983ae306f675df3a 100755
--- a/update_versions.sh
+++ b/update_versions.sh
@@ -1,4 +1,3 @@
#!/bin/sh
-
-mvn versions:set -DnewVersion=1.1.0
+mvn versions:set -DnewVersion=1.2.0