新课程C++实用编程以上线!!!
大家好,我是小笨笨的世界,今天呢,我们会给大家带来出NOIP-C++大神培养计划之外的另一个专辑课程,这门课程主要是在于C++语言编程,实用模板、函数分享,大佬代码,游戏编程等运用广泛的内容,希望大家在学有余力时放松一下。 我们的专辑叫:C++实用编程。 请大家敬请期待,我们一周更新一次,更行时间在周末,我会准时发出我们的课程!
本文介绍如何用Java编写高度自定义的代码生成器
MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息。
上面这一段话来自Mybatis官网的介绍, 初用Mybatis时感觉这个框架相比于JDBC优雅多了, 用起来也如官网说的非常简单。但是用了一段时间之后, 弊端就慢慢凸显出来了
使用Mybatis时不得不为每个表创建一个Entity.java、Mapper.xml(Mapper可以融合入Dao中)、Dao.java,Service.java 层次很清晰, 但是太多重复性的工作了, 费时间且易于出错
并且当数据库发生一点改动的时候... 苦不堪言
后来出现了自动生成代码的插件, 但是总是不尽人意, 不能随心所欲地控制, 毕竟每个人的需求都不一样
本文就来介绍如何简单的编写一个自己的代码生成器
实现的思路很简单, 首先查询数据库的表结构, 得到列名, 列类型...等信息
创建文件模版, 将这些信息插入模版中, 最后打包模版进压缩包导出
代码实现 一共五个Java类
首先来看两个实体类
TableDO 存放表名, 对于的类名, 以及列信息
完整类代码 TableDO.java
public class TableDO {
private String tableName;
private List<ColumnDO> columns;
private String className;
private String suffix;
// get()... set()...
}
ColumnDO 存放列名, 数据库字段类型, 以及对应Java中的属性名和类型
完整类代码 ColumnDO.java
public class ColumnDO {
private String columnName;
private String dataType;
private String attrName;
private String attrLowerName;
private String attrType;
// get()... set()...
}
在GeneratorMapper 中, 我们通过表名查询表自动的信息
完整类代码 GeneratorMapper.java
@Mapper
public interface GeneratorMapper {
@Select("select column_name columnName, data_type dataType from information_schema.columns where table_name = #{tableName} and table_schema = (select database()) order by ordinal_position")
List<ColumnDO> listColumns(String tableName);
}
在GeneratorUtils 中进行类信息与模版之间的转换
完整类代码 GeneratorUtils.java
将表信息放入Velocity模版的上下文中
Map<String, Object> map = new HashMap<>();
map.put("tableName", table.getTableName());
map.put("className", table.getClassName());
map.put("pathName", getPackageName().substring(getPackageName().lastIndexOf(".") + 1));
map.put("columns", table.getColumns());
map.put("package", getPackageName());
map.put("suffix", table.getSuffix());
Properties prop = new Properties();
prop.put("file.resource.loader.class", "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");
Velocity.init(prop);
VelocityContext context = new VelocityContext(map);
添加模版
List<String> templates = new ArrayList<>();
templates.add("mybatis/Model.java.vm");
templates.add("mybatis/Query.java.vm");
templates.add("mybatis/Dao.java.vm");
templates.add("mybatis/Mapper.xml.vm");
templates.add("mybatis/Service.java.vm");
编译模版
StringWriter sw = new StringWriter();
Template tpl = Velocity.getTemplate(template, "UTF-8");
tpl.merge(context, sw);
Utils类完成了生成代码的主要工作, 但是代码也是比较简单的
在Service 中注入Mapper 查询列信息, 并用Utils生成代码, 然后导出压缩包
完整类代码 GeneratorService.java
@Service
public class GeneratorService {
@Resource
private GeneratorMapper generatorMapper;
@Resource
private Environment environment;
public void generateZip(String[] tableNames, String zipPath) throws IOException {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
ZipOutputStream zip = new ZipOutputStream(outputStream);
for (String tableName : tableNames) {
TableDO table = new TableDO();
table.setTableName(tableName);
table.setColumns(generatorMapper.listColumns(tableName));
GeneratorUtils.generatorCode(table, zip,getConfig());
}
IOUtils.closeQuietly(zip);
FileOutputStream file = new FileOutputStream(zipPath);
file.write(outputStream.toByteArray());
file.close();
}
// getConfig ...
}
自己写代码生成器的好处就是, 可以根据需求定制自己的模版, 下面是我的几个模版可以供参考
生成的代码是在commons-mybatis架构下使用的
package ${package}.database.dao;
import ${package}.database.model.${className}${suffix};
import org.apache.ibatis.annotations.Mapper;
import org.laziji.commons.mybatis.dao.${suffix}Dao;
@Mapper
public interface ${className}Dao extends ${suffix}Dao<${className}${suffix}> {
}
在resources下创建application-${name}.yml文件, ${name}随意, 例如: application-example.yml, 可创建多个
配置文件内容如下, 填入数据库配置, 以及生成代码的包名, 源文件路径
spring:
datasource:
url: jdbc:mysql://xxx.xxx.xxx.xxx:3306/xxxx?characterEncoding=utf-8
username: xxxxxx
password: xxxxxx
generator:
package: com.xxx.xxx
resources: mapper
在test文件下创建测试类
@ActiveProfiles("example")中填入刚才配置文件名的name tableNames需要生成的表, 可以多个zipPath 代码导出路径package pg.laziji.generator;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.junit4.SpringRunner;
import pg.laziji.generator.mybatis.GeneratorService;
import javax.annotation.Resource;
import java.io.IOException;
@ActiveProfiles("example")
@RunWith(SpringRunner.class)
@SpringBootTest
public class ExampleTest {
@Resource
private GeneratorService generatorService;
@Test
public void test() throws IOException {
String[] tableNames = new String[]{"example_table1", "example_table2"};
String zipPath = "/home/code.zip";
generatorService.generateZip(tableNames,zipPath);
}
}
微信关注我们
转载内容版权归作者及来源网站所有!
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
近一个月的开发和优化,本站点的第一个app全新上线。该app采用极致压缩,本体才4.36MB。系统里面做了大量数据访问、缓存优化。方便用户在手机上查看文章。后续会推出HarmonyOS的适配版本。
为解决软件依赖安装时官方源访问速度慢的问题,腾讯云为一些软件搭建了缓存服务。您可以通过使用腾讯云软件源站来提升依赖包的安装速度。为了方便用户自由搭建服务架构,目前腾讯云软件源站支持公网访问和内网访问。
Rocky Linux(中文名:洛基)是由Gregory Kurtzer于2020年12月发起的企业级Linux发行版,作为CentOS稳定版停止维护后与RHEL(Red Hat Enterprise Linux)完全兼容的开源替代方案,由社区拥有并管理,支持x86_64、aarch64等架构。其通过重新编译RHEL源代码提供长期稳定性,采用模块化包装和SELinux安全架构,默认包含GNOME桌面环境及XFS文件系统,支持十年生命周期更新。
Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。还可自定义键绑定,菜单和工具栏。Sublime Text 的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。Sublime Text 是一个跨平台的编辑器,同时支持Windows、Linux、Mac OS X等操作系统。