java mybatisGenerator with velocity
mybatisGenerator + velocity 模板生成dao+ mapper,并将mysql命名规范的table name + column -> java命名规范的 Class name + fieldname,并支持生成,感谢https://github.com/shuzheng/zheng的开源内容。
pom依赖
<dependency>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-core</artifactId>
<version>${mybatis-generator.version}</version>
</dependency> <!-- velocity模板引擎 -->
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity</artifactId>
<version>1.7</version>
</dependency> <!-- mysql -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.34</version>
<scope>runtime</scope>
</dependency> <!-- 常用工具包 -->
<dependency>
<groupId>commons-beanutils</groupId>
<artifactId>commons-beanutils</artifactId>
<version>1.9.3</version>
</dependency>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.6</version>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.10</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-compress</artifactId>
<version>1.12</version>
</dependency>
相关源码:
AES工具:
package cn.jsfund.ase.util; import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder; import javax.crypto.*;
import javax.crypto.spec.SecretKeySpec;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom; /**
* @author ppgeneve
* @Description: AES加密工具类
* @Date 2018/8/20 15:14
*/
public class AESUtil {
private static final String ENCODE_RULES = "zheng"; /**
* 加密
* 1.构造密钥生成器
* 2.根据ecnodeRules规则初始化密钥生成器
* 3.产生密钥
* 4.创建和初始化密码器
* 5.内容加密
* 6.返回字符串
*/
public static String aesEncode(String content) {
try {
//1.构造密钥生成器,指定为AES算法,不区分大小写
KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
//2.根据ecnodeRules规则初始化密钥生成器
//生成一个128位的随机源,根据传入的字节数组
SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
random.setSeed(ENCODE_RULES.getBytes());
keyGenerator.init(128, random);
//3.产生原始对称密钥
SecretKey originalKey = keyGenerator.generateKey();
//4.获得原始对称密钥的字节数组
byte[] raw = originalKey.getEncoded();
//5.根据字节数组生成AES密钥
SecretKey key = new SecretKeySpec(raw, "AES");
//6.根据指定算法AES自成密码器
Cipher cipher = Cipher.getInstance("AES");
//7.初始化密码器,第一个参数为加密(Encrypt_mode)或者解密解密(Decrypt_mode)操作,第二个参数为使用的KEY
cipher.init(Cipher.ENCRYPT_MODE, key);
//8.获取加密内容的字节数组(这里要设置为utf-8)不然内容中如果有中文和英文混合中文就会解密为乱码
byte[] byteEncode = content.getBytes(StandardCharsets.UTF_8);
//9.根据密码器的初始化方式--加密:将数据加密
byte[] byteAES = cipher.doFinal(byteEncode);
//10.将加密后的数据转换为字符串
//这里用Base64Encoder中会找不到包
//解决办法:
//在项目的Build path中先移除JRE System Library,再添加库JRE System Library,重新编译后就一切正常了。
return new BASE64Encoder().encode(byteAES);
} catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | IllegalBlockSizeException | BadPaddingException e) {
e.printStackTrace();
}
//如果有错就返加null
return null;
} /**
* 解密
* 解密过程:
* 1.同加密1-4步
* 2.将加密后的字符串反纺成byte[]数组
* 3.将加密内容解密
*/
public static String aesDecode(String content) {
try {
//1.构造密钥生成器,指定为AES算法,不区分大小写
KeyGenerator keygen = KeyGenerator.getInstance("AES");
//2.根据ecnodeRules规则初始化密钥生成器
//生成一个128位的随机源,根据传入的字节数组
SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
random.setSeed(ENCODE_RULES.getBytes());
keygen.init(128, random);
//3.产生原始对称密钥
SecretKey originalKey = keygen.generateKey();
//4.获得原始对称密钥的字节数组
byte[] raw = originalKey.getEncoded();
//5.根据字节数组生成AES密钥
SecretKey key = new SecretKeySpec(raw, "AES");
//6.根据指定算法AES自成密码器
Cipher cipher = Cipher.getInstance("AES");
//7.初始化密码器,第一个参数为加密(Encrypt_mode)或者解密(Decrypt_mode)操作,第二个参数为使用的KEY
cipher.init(Cipher.DECRYPT_MODE, key);
//8.将加密并编码后的内容解码成字节数组
byte[] byteContent = new BASE64Decoder().decodeBuffer(content);
/*
* 解密
*/
byte[] byteDecode = cipher.doFinal(byteContent);
return new String(byteDecode, StandardCharsets.UTF_8);
} catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | IOException | BadPaddingException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
throw new RuntimeException("配置文件中的密码需要使用AES加密");
}
//如果有错就返加null
return null;
} public static void main(String[] args) throws Exception{
String encoding = "UTF-8";
File file = new File("api_extension.py");
Long fileLength = file.length();
byte[] fileContent = new byte[fileLength.intValue()];
try {
FileInputStream in = new FileInputStream(file);
in.read(fileContent);
in.close();
} catch (FileNotFoundException e) {
System.out.println("File not found.");
} catch (IOException e) {
System.out.println("xx");
} String content = new String(fileContent, encoding);
System.out.println("-------key | AESEncode | AESDecode--------"); String encrypt = aesEncode(content); System.out.println(encrypt);
String decrypt = aesDecode(encrypt); System.out.println(decrypt); }
}
JdbcUtil
package cn.jsfund.ase.util; import java.sql.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map; /**
* @author ppgeneve
* @Description: Jdbc工具类
* @Date 2018/8/20 15:14
*/
public class JdbcUtil { /**
* 定义数据库的链接
*/
private Connection conn; /**
* 定义sql语句的执行对象
*/
private PreparedStatement pstmt; /**
* 定义查询返回的结果集合
*/
private ResultSet rs; // 初始化
public JdbcUtil(String driver, String url, String username, String password) {
try {
Class.forName(driver);
conn = DriverManager.getConnection(url, username, password);
System.out.println("数据库连接成功");
} catch (Exception e) {
e.printStackTrace();
}
} // 更新数据
public boolean updateByParams(String sql, List params) throws SQLException {
// 影响行数
int result = -1;
pstmt = conn.prepareStatement(sql);
int index = 1;
// 填充sql语句中的占位符
if (null != params && !params.isEmpty()) {
for (int i = 0; i < params.size(); i++) {
pstmt.setObject(index++, params.get(i));
}
}
result = pstmt.executeUpdate();
return result > 0;
} // 查询多条记录
public List<Map> selectByParams(String sql, List params) throws SQLException {
List<Map> list = new ArrayList<>();
int index = 1;
pstmt = conn.prepareStatement(sql);
if (null != params && !params.isEmpty()) {
for (int i = 0; i < params.size(); i++) {
pstmt.setObject(index++, params.get(i));
}
}
rs = pstmt.executeQuery();
ResultSetMetaData metaData = rs.getMetaData();
int colsLen = metaData.getColumnCount();
while (rs.next()) {
Map map = new HashMap(colsLen);
for (int i = 0; i < colsLen; i++) {
String columnName = metaData.getColumnName(i + 1);
Object columnValue = rs.getObject(columnName);
if (null == columnValue) {
columnValue = "";
}
map.put(columnName, columnValue);
}
list.add(map);
}
return list;
} // 释放连接
public void release() {
try {
if (null != rs) {
rs.close();
}
if (null != pstmt) {
pstmt.close();
}
if (null != conn) {
conn.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
System.out.println("释放数据库连接");
} }
资源文件读取工具
package cn.jsfund.ase.util; import java.util.Date;
import java.util.HashMap;
import java.util.MissingResourceException;
import java.util.ResourceBundle; /**
* @author ppgeneve
* @Description: 资源文件读取工具
* @Date 2018/8/20 15:14
*/
public class PropertiesFileUtil { // 当打开多个资源文件时,缓存资源文件
private static HashMap<String, PropertiesFileUtil> configMap = new HashMap<String, PropertiesFileUtil>();
// 打开文件时间,判断超时使用
private Date loadTime = null;
// 资源文件
private ResourceBundle resourceBundle = null;
// 默认资源文件名称
private static final String NAME = "config";
// 缓存时间
private static final Integer TIME_OUT = 60 * 1000; // 私有构造方法,创建单例
private PropertiesFileUtil(String name) {
this.loadTime = new Date();
this.resourceBundle = ResourceBundle.getBundle(name);
} public static synchronized PropertiesFileUtil getInstance() {
return getInstance(NAME);
} public static synchronized PropertiesFileUtil getInstance(String name) {
PropertiesFileUtil conf = configMap.get(name);
if (null == conf) {
conf = new PropertiesFileUtil(name);
configMap.put(name, conf);
}
// 判断是否打开的资源文件是否超时1分钟
if ((System.currentTimeMillis() - conf.getLoadTime().getTime()) > TIME_OUT) {
conf = new PropertiesFileUtil(name);
configMap.put(name, conf);
}
return conf;
} // 根据key读取value
public String get(String key) {
try {
String value = resourceBundle.getString(key);
return value;
} catch (MissingResourceException e) {
return "";
}
} // 根据key读取value(整形)
public Integer getInt(String key) {
try {
String value = resourceBundle.getString(key);
return Integer.parseInt(value);
} catch (MissingResourceException e) {
return null;
}
} // 根据key读取value(布尔)
public boolean getBool(String key) {
try {
String value = resourceBundle.getString(key);
if ("true".equals(value)) {
return true;
}
return false;
} catch (MissingResourceException e) {
return false;
}
} public Date getLoadTime() {
return loadTime;
} }
string工具类:
package cn.jsfund.ase.util; import org.apache.commons.lang.StringUtils; import java.util.regex.Matcher;
import java.util.regex.Pattern; /**
* @author ppgeneve
* @Description: String 工具类
* @Date 2018/8/20 15:14
*/
public class StringUtil { private static Pattern linePattern = Pattern.compile("_(\\w)");
private static Pattern humpPattern = Pattern.compile("[A-Z]"); /**
* 下划线转驼峰
* @param str
* @return
*/
public static String lineToHump(String str) {
if (null == str || "".equals(str)) {
return str;
}
str = str.toLowerCase();
Matcher matcher = linePattern.matcher(str);
StringBuffer sb = new StringBuffer();
while (matcher.find()) {
matcher.appendReplacement(sb, matcher.group(1).toUpperCase());
}
matcher.appendTail(sb); str = sb.toString();
str = str.substring(0, 1).toUpperCase() + str.substring(1); return str;
} /**
* 驼峰转下划线,效率比上面高
* @param str
* @return
*/
public static String humpToLine(String str) {
Matcher matcher = humpPattern.matcher(str);
StringBuffer sb = new StringBuffer();
while (matcher.find()) {
matcher.appendReplacement(sb, "_" + matcher.group(0).toLowerCase());
}
matcher.appendTail(sb);
return sb.toString();
} /**
* 驼峰转下划线(简单写法,效率低于{@link #humpToLine(String)})
* @param str
* @return
*/
public static String humpToLine2(String str) {
return str.replaceAll("[A-Z]", "_$0").toLowerCase();
} /**
* 首字母转小写
* @param s
* @return
*/
public static String toLowerCaseFirstOne(String s) {
if (StringUtils.isBlank(s)) {
return s;
}
if (Character.isLowerCase(s.charAt(0))) {
return s;
} else {
return (new StringBuilder()).append(Character.toLowerCase(s.charAt(0))).append(s.substring(1)).toString();
}
} /**
* 首字母转大写
* @param s
* @return
*/
public static String toUpperCaseFirstOne(String s) {
if (StringUtils.isBlank(s)) {
return s;
}
if (Character.isUpperCase(s.charAt(0))) {
return s;
} else {
return (new StringBuffer()).append(Character.toUpperCase(s.charAt(0))).append(s.substring(1)).toString();
}
} /**
* object转String
* @param object
* @return
*/
public static String getString(Object object) {
return getString(object, "");
} public static String getString(Object object, String defaultValue) {
if (null == object) {
return defaultValue;
}
try {
return object.toString();
} catch (Exception e) {
return defaultValue;
}
} /**
* object转Integer
* @param object
* @return
*/
public static int getInt(Object object) {
return getInt(object, -1);
} public static int getInt(Object object, Integer defaultValue) {
if (null == object) {
return defaultValue;
}
try {
return Integer.parseInt(object.toString());
} catch (Exception e) {
return defaultValue;
}
} /**
* object转Boolean
* @param object
* @return
*/
public static boolean getBoolean(Object object) {
return getBoolean(object, false);
} public static boolean getBoolean(Object object, Boolean defaultValue) {
if (null == object) {
return defaultValue;
}
try {
return Boolean.parseBoolean(object.toString());
} catch (Exception e) {
return defaultValue;
}
} }
velocity工具:
package cn.jsfund.ase.util; import org.apache.commons.io.output.FileWriterWithEncoding;
import org.apache.commons.lang.StringUtils;
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.Velocity;
import org.apache.velocity.app.VelocityEngine; import java.io.File;
import java.util.Properties; /**
* @author ppgeneve
* @Description: 模板工具类
* @Date 2018/8/20 15:14
*/
public class VelocityUtil { /**
* 根据模板生成文件
* @param inputVmFilePath 模板路径
* @param outputFilePath 输出文件路径
* @param context
* @throws Exception
*/
public static void generate(String inputVmFilePath, String outputFilePath, VelocityContext context) throws Exception {
try {
Properties properties = new Properties();
properties.setProperty(VelocityEngine.FILE_RESOURCE_LOADER_PATH, getPath(inputVmFilePath));
Velocity.init(properties);
//VelocityEngine engine = new VelocityEngine();
Template template = Velocity.getTemplate(getFile(inputVmFilePath), "utf-8");
File outputFile = new File(outputFilePath);
FileWriterWithEncoding writer = new FileWriterWithEncoding(outputFile, "utf-8");
template.merge(context, writer);
writer.close();
} catch (Exception ex) {
throw ex;
}
} /**
* 根据文件绝对路径获取目录
* @param filePath
* @return
*/
public static String getPath(String filePath) {
String path = "";
if (StringUtils.isNotBlank(filePath)) {
path = filePath.substring(0, filePath.lastIndexOf("/") + 1);
}
return path;
} /**
* 根据文件绝对路径获取文件
* @param filePath
* @return
*/
public static String getFile(String filePath) {
String file = "";
if (StringUtils.isNotBlank(filePath)) {
file = filePath.substring(filePath.lastIndexOf("/") + 1);
}
return file;
} }
mybatisGenerator工具:这里可以根据模板直接生成service,serviceImpl,serviceMock等,本文这里省略
package cn.jsfund.ase.util; import org.apache.commons.lang.ObjectUtils;
import org.apache.velocity.VelocityContext;
import org.mybatis.generator.api.MyBatisGenerator;
import org.mybatis.generator.config.Configuration;
import org.mybatis.generator.config.xml.ConfigurationParser;
import org.mybatis.generator.internal.DefaultShellCallback; import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map; import static cn.jsfund.ase.util.StringUtil.lineToHump; /**
* @author ppgeneve
* @Description: 代码生成类
* @Date 2018/8/20 15:14
*/
public class MybatisGeneratorUtil { // generatorConfig模板路径
private static String generatorConfig_vm = "/template/generatorConfig.vm";
// Service模板路径
private static String service_vm = "/template/Service.vm";
// ServiceMock模板路径
private static String serviceMock_vm = "/template/ServiceMock.vm";
// ServiceImpl模板路径
private static String serviceImpl_vm = "/template/ServiceImpl.vm"; /**
* 根据模板生成generatorConfig.xml文件
*
* @param jdbcDriver 驱动路径
* @param jdbcUrl 链接
* @param jdbcUsername 帐号
* @param jdbcPassword 密码
* @param module 项目模块
* @param database 数据库
* @param tablePrefix 表前缀
* @param packageName 包名
*/
public static void generator(
String jdbcDriver,
String jdbcUrl,
String jdbcUsername,
String jdbcPassword,
String module,
String database,
String tablePrefix,
String packageName,
Map<String, String> lastInsertIdTables) throws Exception { String os = System.getProperty("os.name");
String targetProject = module;
String basePath = MybatisGeneratorUtil.class.getResource("/").getPath().replace("/target/classes/", "").replace(targetProject, "");
if (os.toLowerCase().startsWith("win")) {
generatorConfig_vm = MybatisGeneratorUtil.class.getResource(generatorConfig_vm).getPath().replaceFirst("/", "");
// service_vm = MybatisGeneratorUtil.class.getResource(service_vm).getPath().replaceFirst("/", "");
// serviceMock_vm = MybatisGeneratorUtil.class.getResource(serviceMock_vm).getPath().replaceFirst("/", "");
// serviceImpl_vm = MybatisGeneratorUtil.class.getResource(serviceImpl_vm).getPath().replaceFirst("/", "");
basePath = basePath.replaceFirst("/", "");
} else {
generatorConfig_vm = MybatisGeneratorUtil.class.getResource(generatorConfig_vm).getPath();
// service_vm = MybatisGeneratorUtil.class.getResource(service_vm).getPath();
// serviceMock_vm = MybatisGeneratorUtil.class.getResource(serviceMock_vm).getPath();
// serviceImpl_vm = MybatisGeneratorUtil.class.getResource(serviceImpl_vm).getPath();
} String generatorConfigXml = MybatisGeneratorUtil.class.getResource("/").getPath().replace("/target/classes/", "") + "/src/main/resources/generatorConfig.xml";
targetProject = basePath + targetProject;
String sql = "SELECT table_name FROM INFORMATION_SCHEMA.TABLES WHERE table_schema = '" + database + "' AND table_name LIKE '" + tablePrefix + "_%';"; System.out.println("========== 开始生成generatorConfig.xml文件 ==========");
List<Map<String, Object>> tables = new ArrayList<>();
try {
VelocityContext context = new VelocityContext();
Map<String, Object> table; // 查询定制前缀项目的所有表,这里支持jdbcpassword ase解密, 配置中的password是密文,jdbcPassword -> AESUtil.aseDecode(jdbcPassword)
JdbcUtil jdbcUtil = new JdbcUtil(jdbcDriver, jdbcUrl, jdbcUsername, jdbcPassword);
List<Map> result = jdbcUtil.selectByParams(sql, null);
for (Map map : result) {
System.out.println(map.get("TABLE_NAME"));
table = new HashMap<>(2);
table.put("table_name", map.get("TABLE_NAME"));
table.put("model_name", lineToHump(ObjectUtils.toString(map.get("TABLE_NAME"))));
tables.add(table);
}
jdbcUtil.release();
//xmlMapper写到resources/mappers下面
String targetProjectSqlMap = "/Users/xxx/.../resources/mappers";
context.put("tables", tables);
context.put("generator_javaModelGenerator_targetPackage", packageName + ".dao.model");
context.put("generator_sqlMapGenerator_targetPackage", packageName + ".dao.mapper");
context.put("generator_javaClientGenerator_targetPackage", packageName + ".dao.mapper");
context.put("targetProject", targetProject);
context.put("targetProject_sqlMap", targetProjectSqlMap);
context.put("generator_jdbc_password", jdbcPassword);
context.put("last_insert_id_tables", lastInsertIdTables);
VelocityUtil.generate(generatorConfig_vm, generatorConfigXml, context);
// 删除旧代码
deleteDir(new File(targetProject + "/src/main/java/" + packageName.replaceAll("\\.", "/") + "/dao/model"));
deleteDir(new File(targetProject + "/src/main/java/" + packageName.replaceAll("\\.", "/") + "/dao/mapper"));
// deleteDir(new File(targetProjectSqlMap + "/src/main/java/" + packageName.replaceAll("\\.", "/") + "/dao/mapper"));
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("========== 结束生成generatorConfig.xml文件 =========="); System.out.println("========== 开始运行MybatisGenerator ==========");
List<String> warnings = new ArrayList<>();
File configFile = new File(generatorConfigXml);
ConfigurationParser cp = new ConfigurationParser(warnings);
Configuration config = cp.parseConfiguration(configFile);
DefaultShellCallback callback = new DefaultShellCallback(true);
MyBatisGenerator myBatisGenerator = new MyBatisGenerator(config, callback, warnings);
myBatisGenerator.generate(null);
for (String warning : warnings) {
System.out.println(warning);
}
System.out.println("========== 结束运行MybatisGenerator =========="); // System.out.println("========== 开始生成Service ==========");
// String ctime = new SimpleDateFormat("yyyy/M/d").format(new Date());
// String servicePath = basePath + module + "/" + module + "-rpc-api" + "/src/main/java/" + packageName.replaceAll("\\.", "/") + "/rpc/api";
// String serviceImplPath = basePath + module + "/" + module + "-rpc-service" + "/src/main/java/" + packageName.replaceAll("\\.", "/") + "/rpc/service/impl";
// for (int i = 0; i < tables.size(); i++) {
// String model = StringUtil.lineToHump(ObjectUtils.toString(tables.get(i).get("table_name")));
// String service = servicePath + "/" + model + "Service.java";
// String serviceMock = servicePath + "/" + model + "ServiceMock.java";
// String serviceImpl = serviceImplPath + "/" + model + "ServiceImpl.java";
// 生成service
// File serviceFile = new File(service);
// if (!serviceFile.exists()) {
// VelocityContext context = new VelocityContext();
// context.put("package_name", packageName);
// context.put("model", model);
// context.put("ctime", ctime);
// VelocityUtil.generate(service_vm, service, context);
// System.out.println(service);
// }
// 生成serviceMock
// File serviceMockFile = new File(serviceMock);
// if (!serviceMockFile.exists()) {
// VelocityContext context = new VelocityContext();
// context.put("package_name", packageName);
// context.put("model", model);
// context.put("ctime", ctime);
// VelocityUtil.generate(serviceMock_vm, serviceMock, context);
// System.out.println(serviceMock);
// }
// 生成serviceImpl
// File serviceImplFile = new File(serviceImpl);
// if (!serviceImplFile.exists()) {
// VelocityContext context = new VelocityContext();
// context.put("package_name", packageName);
// context.put("model", model);
// context.put("mapper", StringUtil.toLowerCaseFirstOne(model));
// context.put("ctime", ctime);
// VelocityUtil.generate(serviceImpl_vm, serviceImpl, context);
// System.out.println(serviceImpl);
// }
// }
// System.out.println("========== 结束生成Service ==========");
} // 递归删除非空文件夹
public static void deleteDir(File dir) {
if (dir.isDirectory()) {
File[] files = dir.listFiles();
for (int i = 0; i < files.length; i++) {
deleteDir(files[i]);
}
}
dir.delete();
} }
GeneratorMain:
package cn.jsfund.ase; import cn.jsfund.ase.util.MybatisGeneratorUtil;
import cn.jsfund.ase.util.PropertiesFileUtil; import java.util.HashMap;
import java.util.Map; /**
* @author ppgeneve
* @Description: Generator
* @Date 2018/8/20 15:14
*/
public class Generator { // 根据命名规范,只修改此常量值即可
private static String MODULE = "aes";
private static String DATABASE = "jstest";
private static String TABLE_PREFIX = "";
private static String PACKAGE_NAME = "cn.jsfund";
private static String JDBC_DRIVER = PropertiesFileUtil.getInstance("generator").get("generator.jdbc.driver");
private static String JDBC_URL = PropertiesFileUtil.getInstance("generator").get("generator.jdbc.url");
private static String JDBC_USERNAME = PropertiesFileUtil.getInstance("generator").get("generator.jdbc.username");
private static String JDBC_PASSWORD = PropertiesFileUtil.getInstance("generator").get("generator.jdbc.password");
// 需要insert后返回主键的表配置,key:表名,value:主键名
private static Map<String, String> LAST_INSERT_ID_TABLES = new HashMap<>();
static { } /**
* 自动代码生成
* @param args
*/
public static void main(String[] args) throws Exception {
MybatisGeneratorUtil.generator(JDBC_DRIVER, JDBC_URL, JDBC_USERNAME, JDBC_PASSWORD, MODULE, DATABASE, TABLE_PREFIX, PACKAGE_NAME, LAST_INSERT_ID_TABLES);
} }
generatorConfig.vm
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE generatorConfiguration PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN" "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd" >
<generatorConfiguration> <!-- 配置文件 -->
<properties resource="generator.properties"></properties> <context id="MysqlContext" targetRuntime="MyBatis3" defaultModelType="flat"> <property name="javaFileEncoding" value="UTF-8"/>
<!-- 由于beginningDelimiter和endingDelimiter的默认值为双引号("),在Mysql中不能这么写,所以还要将这两个默认值改为` -->
<property name="beginningDelimiter" value="`"/>
<property name="endingDelimiter" value="`"/> <!-- 为生成的Java模型创建一个toString方法 -->
<plugin type="org.mybatis.generator.plugins.ToStringPlugin"></plugin> <!-- 为生成的Java模型类添加序列化接口,并生成serialVersionUID字段 -->
<plugin type="cn.jsfund.ase.plugin.SerializablePlugin">
<property name="suppressJavaInterface" value="false"/>
</plugin> <!-- 生成一个新的selectByExample方法,这个方法可以接收offset和limit参数,主要用来实现分页,只支持mysql(已使用pagehelper代替) -->
<!--<plugin type="com.zheng.common.plugin.PaginationPlugin"></plugin>--> <!-- 生成在XML中的<cache>元素 -->
<plugin type="org.mybatis.generator.plugins.CachePlugin">
<!-- 使用ehcache -->
<property name="cache_type" value="org.mybatis.caches.ehcache.LoggingEhcache" />
<!-- 内置cache配置 -->
<!--
<property name="cache_eviction" value="LRU" />
<property name="cache_flushInterval" value="60000" />
<property name="cache_readOnly" value="true" />
<property name="cache_size" value="1024" />
-->
</plugin> <!-- Java模型生成equals和hashcode方法 -->
<plugin type="org.mybatis.generator.plugins.EqualsHashCodePlugin"></plugin> <!-- 生成的代码去掉注释 -->
<commentGenerator type="cn.jsfund.ase.plugin.CommentGenerator">
<property name="suppressAllComments" value="true" />
<property name="suppressDate" value="true"/>
</commentGenerator> <!-- 数据库连接 -->
<jdbcConnection driverClass="${generator.jdbc.driver}"
connectionURL="${generator.jdbc.url}"
userId="${generator.jdbc.username}"
password="${generator_jdbc_password}" /> <!-- model生成 -->
<javaModelGenerator targetPackage="${generator_javaModelGenerator_targetPackage}" targetProject="${targetProject}/src/main/java" /> <!-- MapperXML生成 -->
<sqlMapGenerator targetPackage="${generator_sqlMapGenerator_targetPackage}" targetProject="${targetProject_sqlMap}" /> <!-- Mapper接口生成 -->
<javaClientGenerator targetPackage="${generator_javaClientGenerator_targetPackage}" targetProject="${targetProject}/src/main/java" type="XMLMAPPER" /> <!-- 需要映射的表 -->
#foreach($table in $tables)
#if($last_insert_id_tables.containsKey($!table.table_name) == true)
<table tableName="$!table.table_name" domainObjectName="$!table.model_name">
<generatedKey column="$!last_insert_id_tables.get($!table.table_name)" sqlStatement="MySql" identity="true"/>
</table>
#else
<table tableName="$!table.table_name" domainObjectName="$!table.model_name"></table>
#end
#end
</context>
</generatorConfiguration>
java mybatisGenerator with velocity的更多相关文章
- Caused by: java.io.FileNotFoundException: velocity.log (No such file or directory)
Caused by: org.apache.velocity.exception.VelocityException: Error initializing log: Failed to initia ...
- Java安全之Velocity模版注入
Java安全之Velocity模版注入 Apache Velocity Apache Velocity是一个基于Java的模板引擎,它提供了一个模板语言去引用由Java代码定义的对象.它允许web 页 ...
- [Java] 模板引擎 Velocity 随笔
Velocity 是一个基于 Java 的模板引擎. 本博文演示 Velocity 的 HelloWord 以及分支条件. HelloWord.vm,模板文件. templateDemo.java, ...
- OSCHina技术导向:Java模板引擎velocity
OSChina 采用 velocity 作为页面模板 Velocity是一个基于java的模板引擎(template engine).它允许任何人仅仅简单的使用模板语言(template langua ...
- velocity模板引擎 -- java.io.FileNotFoundException: velocity.log (Permission denied)
问题原因是velocity的日志框架导致(velocity是使用自己封装的日志框架记录日志的),velocity在初始化Logger时,如果没有读取到配置文件,则会使用默认的velocity.log做 ...
- 《Velocity java开发指南》中文版(下)转载
文章出自:http://sakyone.iteye.com/blog/524292 8.Application Attributes Application Attributes (应用程序属性)是和 ...
- 《Velocity java开发指南》中文版(上)转载
文章引自:http://sakyone.iteye.com/blog/524289 1.开始入门 Velocity是一基于java语言的模板引擎,使用这个简单.功能强大的开发工具,可以很容易的将数据对 ...
- 使用 Velocity 模板引擎快速生成代码(zhuan)
http://www.ibm.com/developerworks/cn/java/j-lo-velocity1/ ****************************************** ...
- 使用Velocity 模板引擎快速生成代码
Velocity 模板引擎介绍 在现今的软件开发过程中,软件开发人员将更多的精力投入在了重复的相似劳动中.特别是在如今特别流行的MVC架构模式中,软件各个层次的功能更加独立,同时代码的相似度也更加高. ...
随机推荐
- jQuery 选择器效率
http://blog.csdn.net/cxl444905143/article/details/48808809 ID > Tag > Class ID 选择器是速度最快的,这主要是因 ...
- CUDA Samples: Dot Product
以下CUDA sample是分别用C++和CUDA实现的两个非常大的向量实现点积操作,并对其中使用到的CUDA函数进行了解说,各个文件内容如下: common.hpp: #ifndef FBC_CUD ...
- 【Keras学习】常见问题与解答
Keras FAQ:常见问题 如何引用Keras? 如果Keras对你的研究有帮助的话,请在你的文章中引用Keras.这里是一个使用BibTex的例子 @misc{chollet2015keras, ...
- 错误:XMLHttpRequest cannot load
原因:Chrome浏览器不支持本地ajax访问,具体就是ajax不能访问file 有3种解决办法:http://frabbit2013.blog.51cto.com/1067958/1254285 其 ...
- 创建你的第一个Flutter应用程序
前言 Flutter,Google推出的跨平台开发框架.就在前几天,Flutter的首个发布预览版(Release Preview 1)正式发布! 即将迎来Flutter 正式版(1.0).本篇将带你 ...
- [转载][QT][SQL]sql学习记录2_sqlite数据类型
转载自:sqlite学习网站: http://www.runoob.com/sqlite/sqlite-tutorial.html SQLite 语法 SQLite 是遵循一套独特的称为语法的规则和 ...
- MySQL中的锁理解
1.目的:解决客户端并发访问的冲突问题 2.锁的分类 1.锁类型 1.读锁(共享锁) 查询(select):加读锁之后,别人不能更改表记录,但是可以进行查询. 2.写锁(互斥锁,排他锁) 更新(upd ...
- fedora22 安装fcitx 输入法
<h4>安装fcitx:</h4><blockquote>sudo yum install fcitx fcitx-pinyin fcitx-configtools ...
- 每天一个linux命令(文件操作):【转载】find 命令概览
Linux下find命令在目录结构中搜索文件,并执行指定的操作.Linux下find命令提供了相当多的查找条件,功能很强大.由于find具有强大的功能,所以它的选项也很多,其中大部分选项都值得我们花时 ...
- 51nod 1600 Simple KMP【后缀自动机+LCT】【思维好题】*
Description 对于一个字符串|S|,我们定义fail[i],表示最大的x使得S[1..x]=S[i-x+1..i],满足(x<i) 显然对于一个字符串,如果我们将每个0<=i&l ...