获取依赖
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| <repositories> <repository> <id>github-maven-repo</id> <url>https://raw.github.com/fanlychie/maven-repo/releases</url> </repository> </repositories> <dependencies> <dependency> <groupId>org.fanlychie</groupId> <artifactId>mybatis-template-generator</artifactId> <version>2.0</version> <scope>test</scope> </dependency> </dependencies>
|
环境要求
JDK1.7 或以上版本
项目地址
https://github.com/fanlychie/mybatis-template-generator
配置
配置文件
在项目类路径下新建一个文件 mybatis-template-generator.xml (右键链接另存为下载), 内容如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
| <?xml version="1.0" encoding="UTF-8"?> <configuration> <properties> <include location="jdbc.properties"/> <property name="basePackage" value="com.domain"/> </properties> <datasource> <property name="url" value="${jdbc.url}"/> <property name="username" value="${jdbc.username}"/> <property name="password" value="${jdbc.password}"/> <property name="driverClass" value="${jdbc.driver}"/> </datasource> <table> <property name="separator" value="_"/> <property name="ignores"> <value>temp*</value> </property> <property name="escapes"> <value>none</value> </property> <property name="prefixs"> <value>tb_</value> </property> </table> <column> <property name="separator" value="_"/> <property name="ignores"> <value>temp*</value> </property> <property name="escapes"> <value>none</value> </property> <property name="prefixs"> <value>none</value> </property> </column> <output> <property name="entity" folder="${basedir}/src/main/java" package="${basePackage}.entity"/> <property name="mapperXml" folder="${basedir}/src/main/resources" package="${basePackage}.mapper"/> <property name="dao" folder="${basedir}/src/main/java" package="${basePackage}.dao"/> <property name="daoImpl" folder="${basedir}/src/main/java" package="${basePackage}.dao.impl"/> <property name="service" folder="${basedir}/src/main/java" package="${basePackage}.service"/> <property name="serviceImpl" folder="${basedir}/src/main/java" package="${basePackage}.service.impl"/> <property name="overwrite"> <value>none</value> </property> </output> </configuration>
|
properties
配置模板文件上下文参数键值对, 上下文环境可以通过 ${} 语法来引用自定义的键值对。
通过类路径下的属性文件引入:
1
| <include location="jdbc.properties"/>
|
直接声明键值对:
1
| <property name="basePackage" value="com.domain"/>
|
datasource
配置数据源信息:
1 2 3 4 5 6 7 8 9 10
| <property name="url" value="${jdbc.url}"/> <property name="username" value="${jdbc.username}"/> <property name="password" value="${jdbc.password}"/> <property name="driverClass" value="${jdbc.driver}"/> <property name="metadataClass" value="org.fanlychie.mybatis.template.db.MySQLMetadata"/>
|
metadataClass 默认使用 MySQL 数据库实现。
其它数据库生成模板代码需实现抽象类 org.fanlychie.mybatis.template.db.DatabaseMetadata。
table
数据库表配置信息:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| <property name="separator" value="_"/> <property name="ignores"> <value>temp*</value> </property> <property name="escapes"> <value>none</value> </property> <property name="prefixs"> <value>tb_</value> </property>
|
参数 |
描述 |
separator |
表名分隔符, 用于驼峰拼写, 例: user_info -> UserInfo |
ignores |
忽略表, 匹配的表将被忽略不处理 |
escapes |
逃逸表, 它无视 ignores 配置的规则, 匹配的表总是会输出文件 |
prefixs |
表前缀, 输出的类文件忽略此名称, 例: tb_user_info -> UserInfo |
column
数据库列配置信息:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| <property name="separator" value="_"/> <property name="ignores"> <value>temp*</value> </property> <property name="escapes"> <value>none</value> </property> <property name="prefixs"> <value>none</value> </property> <property name="typeMapping"> <value jdbcType="varchar" javaType="String" /> </property>
|
参数 |
描述 |
separator |
列名分隔符, 用于驼峰拼写, 例: user_id -> userId |
ignores |
忽略列, 匹配的表将被忽略不处理 |
escapes |
逃逸列, 它无视 ignores 配置的规则, 匹配的列总是输出到对象属性或文件 |
prefixs |
列前缀, 输出的属性忽略此前缀名 |
typeMapping |
数据库类型和 JAVA 数据类型的映射表 |
output
模板文件输出配置信息:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| <property name="entity" folder="${basedir}/src/main/java" package="${basePackage}.entity"/> <property name="mapperXml" folder="${basedir}/src/main/resources" package="${basePackage}.mapper"/> <property name="dao" folder="${basedir}/src/main/java" package="${basePackage}.dao"/> <property name="daoImpl" folder="${basedir}/src/main/java" package="${basePackage}.dao.impl"/> <property name="service" folder="${basedir}/src/main/java" package="${basePackage}.service"/> <property name="serviceImpl" folder="${basedir}/src/main/java" package="${basePackage}.service.impl"/> <property name="overwrite"> <value>none</value> </property>
|
${basedir} 表示当前项目的路径。
参数 |
描述 |
folder |
模板文件输出到的目录路径 |
package |
模板文件使用的包名 |
overwrite |
可以指定哪些模板文件强制重新生成输出。 例: 只重新生成 user_info 表相关的文件 UserInfo* 例: 只重新生成 user_info 表 XML 文件 UserInfo*.xml |
生成模板文件
maven 命令
1
| mvn exec:java -Dexec.mainClass=MyBatisTemplateGenerator -Dexec.classpathScope=test
|
Java 方法调用
1 2 3
| public static void main(String[] args) { org.fanlychie.mybatis.template.Generator.generate(); }
|
使用
引入测试依赖包:
1 2 3 4 5 6 7 8 9 10
| <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>4.2.5.RELEASE</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> </dependency>
|
以 user 用户表为例:
模板文件
除常规文件生成外代码生成器还会为每一个表生成对应的 Criteria 类,用于 SQL 条件操作,例: user 表 -> UserCriteria。
Criteria 类拥有和实体类一致的 set 方法,不同的是 Criteria 类的 set 方法的参数接收的是 Criterion 对象,Criterion 对象通过 Value 静态方法来构建,见下文。
日志
设置输出 SQL 语句 ( com.domain 替换成你自己的包名 ) :
1
| log4j.logger.com.domain.dao = DEBUG
|
保存数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| import com.domain.entity.User; import com.domain.service.UserService; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import java.util.Date; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration("/spring-context.xml") public class UserTest { @Autowired private UserService userService; @Test public void testSave() { User user = new User(); user.setName("张三"); user.setAge(23); user.setSalary(8600F); user.setProvince("广东"); user.setCity("广州"); user.setArea("天河区"); user.setCreateTime(new Date()); Integer id = userService.save(user); } }
|
单元测试:
1 2 3
| DEBUG [save:145] - ==> Preparing: INSERT INTO USER ( ID, NAME, AGE, SALARY, PROVINCE, CITY, AREA, CREATE_TIME ) VALUES ( ?, ?, ?, ?, ?, ?, ?, ? ) DEBUG [save:145] - ==> Parameters: null, 张三(String), 23(Integer), 8600.0(Float), 广东(String), 广州(String), 天河区(String), 2017-02-04 17:33:09.373(Timestamp) DEBUG [save:145] - <== Updates: 1
|
更新数据
根据主键更新
1 2 3 4 5 6 7 8
| @Test public void testUpdate() { User user = new User(); user.setId(21); user.setName("张三丰"); boolean result = userService.update(user); }
|
单元测试:
1 2 3
| DEBUG [update:145] - ==> Preparing: UPDATE USER SET NAME = ? WHERE id = ? DEBUG [update:145] - ==> Parameters: 张三丰(String), 21(Integer) DEBUG [update:145] - <== Updates: 1
|
根据条件更新
1 2 3 4 5 6 7 8 9 10 11 12
| @Test public void testUpdate() { User user = new User(); user.setSalary(9000F); UserCriteria criteria = new UserCriteria(); criteria.setName(Value.eq("张三丰")); int result = userService.update(user, criteria); }
|
单元测试:
1 2 3
| DEBUG [update:145] - ==> Preparing: UPDATE USER SET SALARY = ? WHERE name = ? DEBUG [update:145] - ==> Parameters: 9000.0(Float), 张三丰(String) DEBUG [update:145] - <== Updates: 1
|
删除数据
根据主键删除
1 2 3 4 5
| @Test public void testDelete() { boolean result = userService.delete(21); }
|
单元测试:
1 2 3
| DEBUG [delete:145] - ==> Preparing: DELETE FROM USER WHERE id = ? DEBUG [delete:145] - ==> Parameters: 21(Integer) DEBUG [delete:145] - <== Updates: 1
|
根据条件删除
1 2 3 4 5 6 7 8 9
| @Test public void testDelete() { UserCriteria criteria = new UserCriteria(); criteria.setAge(Value.gt(30)); int result = userService.delete(criteria); }
|
单元测试:
1 2 3
| DEBUG [delete:145] - ==> Preparing: DELETE FROM USER WHERE age > ? DEBUG [delete:145] - ==> Parameters: 30(Integer) DEBUG [delete:145] - <== Updates: 2
|
查询数据
查询全部
1 2 3 4 5 6 7
| @Test public void testSelect() { List<User> user = userService.selectAll(); for (User u : user) { System.out.println(u.getName()); } }
|
单元测试:
1 2 3
| DEBUG [selectList:145] - ==> Preparing: SELECT * FROM USER DEBUG [selectList:145] - ==> Parameters: DEBUG [selectList:145] - <== Total: 18
|
主键查询
1 2 3 4
| @Test public void testSelect() { User user = userService.selectOne(8); }
|
单元测试:
1 2 3
| DEBUG [selectList:145] - ==> Preparing: SELECT * FROM USER WHERE id = ? DEBUG [selectList:145] - ==> Parameters: 8(Integer) DEBUG [selectList:145] - <== Total: 1
|
条件查询唯一记录
1 2 3 4 5 6 7 8 9 10
| @Test public void testSelect() { UserCriteria criteria = new UserCriteria(); criteria.setAge(Value.gt(20)); criteria.setName(Value.eq("用户08")); User user = userService.selectOne(criteria); }
|
单元测试:
1 2 3
| DEBUG [selectList:145] - ==> Preparing: SELECT * FROM USER WHERE age > ? AND name = ? DEBUG [selectList:145] - ==> Parameters: 20(Integer), 用户08(String) DEBUG [selectList:145] - <== Total: 1
|
列表查询
1 2 3 4 5 6 7 8 9
| @Test public void testSelect() { UserCriteria criteria = new UserCriteria(); criteria.setAge(Value.lt(25)); List<User> users = userService.selectList(criteria); }
|
单元测试:
1 2 3
| DEBUG [selectList:145] - ==> Preparing: SELECT * FROM USER WHERE age < ? DEBUG [selectList:145] - ==> Parameters: 25(Integer) DEBUG [selectList:145] - <== Total: 7
|
查询条数
1 2 3 4 5 6 7 8 9
| @Test public void testSelect() { UserCriteria criteria = new UserCriteria(); criteria.setAge(Value.lt(25)); long counts = userService.selectCount(criteria); }
|
单元测试:
1 2 3
| DEBUG [selectCount:145] - ==> Preparing: SELECT COUNT(1) FROM USER WHERE age < ? DEBUG [selectCount:145] - ==> Parameters: 25(Integer) DEBUG [selectCount:145] - <== Total: 1
|
分页查询
bootstrap 插件分页
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| @Test public void testSelect() { Pagination pagination = new Pagination(); UserCriteria criteria = new UserCriteria(); pagination = userService.selectPage(criteria, pagination); System.out.println(pagination.getTotal()); for (Object row : pagination.getRows()) { User user = (User) row; System.out.println(user.getName() + " - ¥" + user.getSalary()); } }
|
单元测试:
1 2 3 4 5 6 7
| DEBUG [selectCount:145] - ==> Preparing: SELECT COUNT(1) FROM USER DEBUG [selectCount:145] - ==> Parameters: DEBUG [selectCount:145] - <== Total: 1 DEBUG [selectList:145] - ==> Preparing: SELECT * FROM USER LIMIT ?, ? DEBUG [selectList:145] - ==> Parameters: 0(Integer), 10(Integer) DEBUG [selectList:145] - <== Total: 10
|
bootstrap 插件分页 Pagination 参数说明表:
参数 |
是否必须 |
描述 |
rows |
否 |
分页结果集合, 返回字段, 无需设值 |
total |
否 |
查询结果总条数, 返回字段, 无需设值 |
limit |
否 |
每页显示的条数, 默认 10 |
offset |
否 |
查询的起始索引值, 默认 0 |
sort |
否 |
排序字段的名称 |
order |
否 |
排序的关键字 |
search |
否 |
搜索的关键字 |
field |
否 |
搜索字段名称, bootstrap 分页插件不发送此参数, 如果有需要, 需手工设置, 建议不使用此参数 |
普通分页
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| @Test public void testSelect() { Pagination pagination = new Pagination(); pagination.setPage(1); UserCriteria criteria = new UserCriteria(); criteria.setSalary(Value.orderBy(OrderBy.ASC)); criteria.setAge(Value.orderBy(OrderBy.ASC)); pagination = userService.selectPage(criteria, pagination); System.out.println("查询结果总条数: " + pagination.getTotal()); System.out.println("查询结果总页数: " + pagination.getPages()); System.out.println("上一页的页码: " + pagination.getPrev()); System.out.println("下一页的页码: " + pagination.getNext()); for (Object row : pagination.getRows()) { User user = (User) row; System.out.println(user.getName() + " " + user.getAge() + " - ¥" + user.getSalary()); } }
|
单元测试:
1 2 3 4 5 6 7
| DEBUG [selectCount:145] - ==> Preparing: SELECT COUNT(1) FROM USER DEBUG [selectCount:145] - ==> Parameters: DEBUG [selectCount:145] - <== Total: 1 DEBUG [selectList:145] - ==> Preparing: SELECT * FROM USER ORDER BY salary ASC , age ASC LIMIT ?, ? DEBUG [selectList:145] - ==> Parameters: 0(Integer), 10(Integer) DEBUG [selectList:145] - <== Total: 10
|
bootstrap 插件分页 Pagination 参数说明表:
参数 |
是否必须 |
描述 |
rows |
否 |
分页结果集合, 返回字段, 无需设值 |
total |
否 |
查询结果总条数, 返回字段, 无需设值 |
limit |
否 |
每页显示的条数, 默认 10 |
offset |
否 |
查询的起始索引值, 默认 0 |
sort |
否 |
排序字段的名称 |
order |
否 |
排序的关键字 |
search |
否 |
搜索的关键字 |
field |
否 |
搜索字段名称 |
page |
是 |
当前请求的页码, 页码从 1 开始 |
prev |
否 |
上一页的页码, 返回字段, 无需设值 |
next |
否 |
下一页的页码, 返回字段, 无需设值 |
pages |
否 |
查询结果总页数, 返回字段, 无需设值 |
逻辑操作
多个 Criterion 条件默认是 AND 逻辑:
1 2 3 4 5 6 7 8 9 10 11
| @Test public void testSelect() { UserCriteria criteria = new UserCriteria(); criteria.setAge(Value.lt(28)); criteria.setSalary(Value.gt(8000)); List<User> users = userService.selectList(criteria); }
|
单元测试:
1 2 3
| DEBUG [selectList:145] - ==> Preparing: SELECT * FROM USER WHERE age < ? AND salary > ? DEBUG [selectList:145] - ==> Parameters: 28(Integer), 8000(Integer) DEBUG [selectList:145] - <== Total: 4
|
支持简单的 OR 逻辑:
1 2 3 4 5 6 7 8 9
| @Test public void testSelect() { UserCriteria criteria = new UserCriteria(); criteria.setAge(Value.lt(28)).or(criteria.setSalary(Value.gt(12000))); List<User> users = userService.selectList(criteria); }
|
单元测试:
1 2 3
| DEBUG [selectList:145] - ==> Preparing: SELECT * FROM USER WHERE age < ? OR salary > ? DEBUG [selectList:145] - ==> Parameters: 28(Integer), 12000(Integer) DEBUG [selectList:145] - <== Total: 15
|