我转载了CSDN一篇5万+访问量的文章
- 2019 年 10 月 4 日
- 筆記
逆向生成实体类等文件,是项目常用技能,单纯IDEA插件也可以实现将数据库表字段直接生成到指定文件夹下的实体类,Mybatis的逆向工程还可生成Controller,service,impl,mapper,mapper.xml等文件,Hibernate也可搭配MVC生成除此之外的前端页面,今天这篇文章,将介绍根据实体类生成建表SQL语句。
先介绍下idea生成实体类的方法。
1.绑定数据库

2.同步数据库后,选择要生成实体类的表

3.指定文件夹即可

接下来为转载正文
通过实体类生成对应的建表语句
最近的工作是把json解析后存入数据库,要求根据其结构创建对应的表去存放这些数据,然后就开始建起了实体类,花了整整一天时间,见了60多个类。。。想着要把这些类再创建成表简直是要疯掉。。还好我机智的想到了可以用反射解决这个问题。
我要做的很简单
1.根据类名称获取其字段名称;
2.根据其字段名称拼接成sql语句即可。
《注意文中目前写死了生成String与int类型,其他自行更改》
接着就在第二天花了半小时捣鼓出了以下代码:
import java.io.File; import java.io.FileOutputStream; import java.lang.reflect.Field; import java.util.ArrayList; import java.util.List; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * sql自动生成 * @author * @date 2018年4月11日 */ public class SqlGenerator { private static final Logger logger = LoggerFactory.getLogger(SqlGenerator.class); public static void main(String[] args) { //实体类所在的package在磁盘上的绝对路径 String packageName = "E:/report"; //生成sql的文件夹 String filePath = "E:/create/"; //项目中实体类的路径 String prefix = "com.example.entity."; String className = ""; StringBuffer sqls = new StringBuffer(); //获取包下的所有类名称 List<String> list = getAllClasses(packageName); for (String str : list) { className = prefix + str.substring(0, str.lastIndexOf(".")); String sql = generateSql(className, filePath); sqls.append(sql); } System.out.println(sqls.toString()); StringToSql(sqls.toString(), filePath + "report.sql"); } /** * 根据实体类生成建表语句 * @author * @date 2018年4月11日 * @param className 全类名 * @param filePath 磁盘路径 如 : d:/workspace/ */ public static String generateSql(String className,String filePath){ try { Class<?> clz = Class.forName(className); className = clz.getSimpleName(); Field[] fields = clz.getDeclaredFields(); StringBuffer column = new StringBuffer(); String varchar = " varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL,"; for (Field f : fields) { column.append(" n `"+f.getName()+"`").append(varchar); } StringBuffer sql = new StringBuffer(); sql.append("n DROP TABLE IF EXISTS `"+className+"`; ") .append(" n CREATE TABLE `"+className+"` (") .append(" n `id` int(11) NOT NULL AUTO_INCREMENT,") .append(" n "+column) .append(" n PRIMARY KEY (`id`) USING BTREE,") .append("n INDEX `id`(`id`) USING BTREE") .append(" n ) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_general_ci;"); return sql.toString(); } catch (ClassNotFoundException e) { logger.debug("该类未找到!"); return null; } } /** * 获取包下的所有类名称,获取的结果类似于 XXX.java * @author * @date 2018年4月11日 * @param packageName * @return */ public static List<String> getAllClasses(String packageName){ List<String> classList = new ArrayList<String>(); String className=""; File f = new File(packageName); if(f.exists() && f.isDirectory()){ File[] files = f.listFiles(); for (File file : files) { className = file.getName(); classList.add(className); } return classList; }else{ logger.debug("包路径未找到!"); return null; } } /** * 将string 写入sql文件 * @author * @date 2018年4月11日 * @param str * @param path */ public static void StringToSql(String str,String path){ byte[] sourceByte = str.getBytes(); if(null != sourceByte){ try { File file = new File(path); //文件路径(路径+文件名) if (!file.exists()) { //文件不存在则创建文件,先创建目录 File dir = new File(file.getParent()); dir.mkdirs(); file.createNewFile(); } FileOutputStream outStream = new FileOutputStream(file); //文件输出流用于将数据写入文件 outStream.write(sourceByte); outStream.flush(); outStream.close(); //关闭文件输出流 System.out.println("生成成功"); } catch (Exception e) { e.printStackTrace(); } } } }
写这段代码的时候还顺便做了个package下的类名扫描,这样就不用一个一个生成建表语句了。
注意事项:
//实体类所在的package在磁盘上的绝对路径 //绝对路径一定要书写到根目录否则读取不到String packageName = "F:\Subversion\main\java\com\project\system\dept\domain"; //生成sql的文件夹 String filePath = "F:\upload"; //项目中实体类的路径,以点结尾String prefix = "com.system.dept.domain."; String className = "Dept.java";
我自己测试结果:

————————————————

版权声明:本文为CSDN博主「lygogogo」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/ly690226302/article/details/79920319
还没完,仍然继续转载了一篇以前令我万分头疼的Thymleaf复选框回显问题,我当时因为复选框对齐回显样式问题折腾了不少时间,然后朋友圈的小伙子实现了他,并因此上过CSDN的首页推荐,2400+的访问量。
在Thymeleaf中执行Java方法,实现CheckBox的自选中
今天在开发中遇到了一个需求就是页面返回的时候让checkbox回显的,本来用JS来写并没有什么难度的。但是要使用Thymeleaf就变得有些复杂。thymeleaf有一个特性就是可以在标签中执行Java的方法。
<label class="checkbox-inline i-checks" th:each="data : ${list}"> <input th:attr="checked=${methodService.contains(data.id,proofsList)?true:false}" type="checkbox" name="proofs[]" th:value="${data.id}" id="inlineCheckbox1" /> </lable>
这里主要说明一下这个methodService.contains方法,它接受两个参数一个是id,一个是list
public class MethodService { public boolean contains(String id,List<Proof> proofs){ System.out.println(proofs); List<String> ids = new ArrayList<>(); for(Proof p: proofs){ ids.add(p.getId()); } return (ids.contains(id)); } }
这一步很重要 你要把这个调用的类放到Request域中,或者Session中,当然页面取值的时候也是不相同的。在Session中取值如下:session.proofsList
MethodService md = new MethodService(); mmap.put("methodService",md); mmap.put("proofsList",proofsList);
————————————————

版权声明:本文为CSDN博主「Crowno17」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:
https://blog.csdn.net/qq_24532581/article/details/85320870
近期素材较少,研究过关于逆向生成全套代码,包括CRUD的代码,一直在调试过程,也让朋友帮了忙,尽快写出来,下期见。
