每次建立ssm項目的時候都需要自己去創建一堆文件,這里介紹兩個方法來節省我們的時間
一、用文件流的方式來根據pojo來自動生成dao層、service層的代碼
模板中都是最常用的增刪改查的方法,不是固定的格式的用[名字]替換,比如[className]為類名,[idao]為接口名;
dao層接口:
package com.dao; import com.pojo.[className]; import java.util.List; public interface [idao] { List<[className]> list([className] [objectName]); int add([className] [objectName]); [className] getById(Integer id); int update([className] [objectName]); int del(int id); int batchdel(Integer[] ids); }
service接口:
package com.service; import com.pojo.[className]; import java.util.List; public interface [iservice] { List<[className]> list([className] [objectName]); int add([className] [objectName]); Timi getById(Integer id); int update([className] [objectName]); int del(int id); int batchdel(Integer[] ids); }
service實現類:
package com.service.impl; import com.dao.[idao]; import com.pojo.[className]; import com.service.[iservice]; import org.springframework.stereotype.Service; import javax.annotation.Resource; import java.util.List; @Service public class [serviceimpl] implements [iservice] { @Resource [idao] [objectName]Dao; @Override public List<[className]> list([className] [objectName]) { return [objectName]Dao.list([objectName]); } @Override public int add([className] [objectName]) { return [objectName]Dao.add([objectName]); } @Override public [className] getById(Integer id) { return [objectName]Dao.getById(id); } @Override public int update([className] [objectName]) { return [objectName]Dao.update([objectName]); } @Override public int del(int id) { return [objectName]Dao.del(id); } @Override public int batchdel(Integer[] ids) { return [objectName]Dao.batchdel(ids); } }
mapper:
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.dao.[idao]"> <sql id="basequery"> select [select] from [tablename] </sql> <select id="list" resultType="[className]" parameterType="[className]"> <include refid="basequery"></include> <where> </where> </select> <insert id="add" parameterType="[className]" > insert into [tablename]([insertlist]) values([insertpro]) </insert> <select id="getById" resultType="[className]" parameterType="java.lang.Integer"> <include refid="basequery"></include> where id = #{id} </select> <update id="update" parameterType="[className]"> update [tablename] set [setlist] where id = #{id} </update> <delete id="del" parameterType="java.lang.Integer"> delete from [tablename] where id=#{id} </delete> <delete id="batchdel" > delete from [tablename] where id in <foreach collection="array" item="item" separator="," open="(" close=")"> #{item} </foreach> </delete> </mapper>
1、首先搭建出基本的ssm框架(見之前的博客)
2、寫一個測試類,用來生成文件,代碼如下
public class MyTest { //根據pojo和目錄生成相關名字 //分別是基礎路徑、類的名字、對象名、dao接口完全限定名等,user.dir是項目路徑 static String basepath=System.getProperty("user.dir")+"/src/main/java/com/"; static String className = "Timi"; static String objectName =className.substring(0,1).toLowerCase()+className.substring(1); static String idao=className+"Dao"; static String iservice =className+"Service"; static String serviceimpl=iservice+"Impl"; static String mapperpath=System.getProperty("user.dir")+"/src/main/resources/"; //通過主函數來創建四個文件 public static void main(String[] args) throws IOException, ClassNotFoundException { createidao(); createiservice(); createserviceimpl(); createmapper(); } //創建dao接口 public static void createidao() throws IOException { File file=new File(basepath+"dao/"+idao+".java"); if(file.exists()){ System.out.println("dao接口文件已存在"); } else{ file.createNewFile(); System.out.println("dao接口創建完成"); //讀取模板轉字符串 File temp =new File(basepath+"/template/daotemplate.tmp"); String str= FileUtils.readFileToString(temp); //替換關鍵字並寫入正確的路徑 String code=str.replaceAll("\\[className]",className) .replaceAll("\\[objectName]",objectName) .replaceAll("\\[idao]",idao); FileUtils.writeStringToFile(file,code); } } //創建service接口,原理和idao一樣 public static void createiservice() throws IOException { File file=new File(basepath+"service/"+iservice+".java"); if(file.exists()){ System.out.println("service接口文件已存在"); } else{ file.createNewFile(); System.out.println("service接口創建完成"); File temp =new File(basepath+"/template/servicetemplate.tmp"); String str= FileUtils.readFileToString(temp); String code=str.replaceAll("\\[className]",className) .replaceAll("\\[objectName]",objectName) .replaceAll("\\[iservice]",iservice); FileUtils.writeStringToFile(file,code); } } public static void createserviceimpl() throws IOException { File file=new File(basepath+"service/impl/"+serviceimpl+".java"); if(file.exists()){ System.out.println("service實現類文件已存在"); } else{ file.createNewFile(); System.out.println("service實現類創建完成"); File temp =new File(basepath+"/template/serviceimpltemplate.tmp"); String str= FileUtils.readFileToString(temp); String code=str.replaceAll("\\[className]",className) .replaceAll("\\[objectName]",objectName) .replaceAll("\\[iservice]",iservice) .replaceAll("\\[serviceimpl]",serviceimpl) .replaceAll("\\[idao]",idao); FileUtils.writeStringToFile(file,code); } } //邏輯比較復雜就是mapper文件的自動生成 public static void createmapper() throws IOException, ClassNotFoundException { File file=new File(mapperpath+"com/dao/"+idao+".xml"); if(file.exists()){ System.out.println("mapper文件已存在"); } else{ file.createNewFile(); System.out.println("mapper文件創建完成"); File temp =new File(basepath+"/template/mapper.tmp"); String str= FileUtils.readFileToString(temp); Class clz=null; String tablename=""; //創建四個list分別存放查、增加的數據庫字段、增加的屬性字段和修改的字段 List<String> select=new ArrayList<String>(); List<String> insertlist=new ArrayList<String>(); List<String> insertpro=new ArrayList<String>(); List<String> setlist=new ArrayList<String>(); try{ //通過反射獲取類的對象 clz=Class.forName("com.pojo."+className); //先判斷對象是否有注解,來防止數據庫名和對象名不一致 if(clz.isAnnotationPresent(tab.class)){ tablename= ((tab) clz.getAnnotation(tab.class)).value(); } else{ tablename=objectName; } Field[] field=clz.getDeclaredFields(); //遍歷屬性名防止字段和屬性不一致,如果不一直就用別名,比如數據庫為user_id,屬性為userId for(Field fe:field){ String in=""; String se=""; if(fe.isAnnotationPresent(colume.class)){ colume clu=fe.getAnnotation(colume.class); se=clu.value()+" as "+fe.getName(); in=clu.value(); } else{ se=fe.getName(); in=fe.getName(); } select.add(se); if(!fe.isAnnotationPresent(id.class)){ insertlist.add(in); insertpro.add("#{"+fe.getName()+"}"); setlist.add(in+"=#{"+fe.getName()+"}"); } } }catch(ClassNotFoundException e){ e.printStackTrace(); } //sql語句和關鍵詞替換 String code=str.replaceAll("\\[idao]",idao) .replaceAll("\\[select]",select.toString().replaceAll("\\[","").replaceAll("\\]","")) .replaceAll("\\[tablename]",tablename) .replaceAll("\\[insertlist]",insertlist.toString().replaceAll("\\[","").replaceAll("\\]","")) .replaceAll("\\[insertpro]",insertpro.toString().replaceAll("\\[","").replaceAll("\\]","")) .replaceAll("\\[setlist]",setlist.toString().replaceAll("\\[","").replaceAll("\\]","")) .replaceAll("\\[className]",className); FileUtils.writeStringToFile(file,code); } } }
生成后的文件代碼如圖:
創建完就可以在controller中直接用了。
二、web代碼生成器
mybatis-plus
1、首先導入必要的包
<dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.2.0</version> </dependency> <!-- 代碼生成器--> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-generator</artifactId> <version>3.2.0</version> </dependency> <!-- freemarker 模板引擎 代碼生成器依賴--> <dependency> <groupId>org.freemarker</groupId> <artifactId>freemarker</artifactId> <version>2.3.30</version> </dependency>
2、然后創建測試類,導入必要的包,使用代碼生成器模板執行即可
public class AutoCodeplus { public static void main(String[] args) { // 代碼生成器 AutoGenerator mpg = new AutoGenerator(); // 全局配置 GlobalConfig gc = new GlobalConfig(); String projectPath = System.getProperty("user.dir") ; // 子項目名稱,分布式才會用 // String projectName = "modelName"; gc.setOutputDir(projectPath + "/src/main/java"); gc.setAuthor("jshand"); gc.setOpen(false); // gc.setSwagger2(true); 實體屬性 Swagger2 注解 mpg.setGlobalConfig(gc); // 數據源配置 DataSourceConfig dsc = new DataSourceConfig();
//修改成自己的 dsc.setUrl("jdbc:mysql://**********?useUnicode=true&useSSL=false&characterEncoding=utf8"); // dsc.setSchemaName("public"); dsc.setDriverName("com.mysql.jdbc.Driver"); dsc.setUsername("root"); dsc.setPassword("123456"); mpg.setDataSource(dsc); // 包配置 PackageConfig pc = new PackageConfig(); pc.setParent("包名"); pc.setEntity("pojo"); pc.setService("service"); pc.setMapper("mapper"); pc.setServiceImpl("service.impl"); pc.setController("controller");
// 分布式用下面的配置,還要設置一個pojo的名字 /* Map<String, String> pathInfo = new HashMap<>(); pathInfo.put("entity_path", projectPath + projectName + "/src/main/java/com/neucourse/pojo"); pathInfo.put("mapper_path", projectPath + projectName + "/src/main/java/com/neucourse/mapper"); pathInfo.put("service_path", projectPath + projectName + "/src/main/java/com/neucourse/service"); pathInfo.put("service_impl_path", projectPath + projectName + "/src/main/java/com/neucourse/service/impl"); pathInfo.put("controller_path", projectPath + projectName + "/src/main/java/com/neucourse/controller"); pc.setPathInfo(pathInfo); */ mpg.setPackageInfo(pc); // 自定義配置 InjectionConfig cfg = new InjectionConfig() { @Override public void initMap() { } }; // 如果模板引擎是 freemarker String templatePath = "/templates/mapper.xml.ftl"; // 如果模板引擎是 velocity // String templatePath = "/templates/mapper.xml.vm"; // 自定義輸出配置 List<FileOutConfig> focList = new ArrayList<>(); // 自定義配置會被優先輸出 focList.add(new FileOutConfig(templatePath) { @Override public String outputFile(TableInfo tableInfo) { // 自定義輸出文件名 , 如果你 Entity 設置了前后綴、此處注意 xml 的名稱會跟着發生變化!! return projectPath + "/src/main/resources/com/neuedu/mapper" + "/" + tableInfo.getEntityName() + "Mapper" + StringPool.DOT_XML; } }); /* cfg.setFileCreate(new IFileCreate() { @Override public boolean isCreate(ConfigBuilder configBuilder, FileType fileType, String filePath) { // 判斷自定義文件夾是否需要創建 checkDir("調用默認方法創建的目錄"); return false; } }); */ cfg.setFileOutConfigList(focList); mpg.setCfg(cfg); // 配置模板 TemplateConfig templateConfig = new TemplateConfig(); // 配置自定義輸出模板 //指定自定義模板路徑,注意不要帶上.ftl/.vm, 會根據使用的模板引擎自動識別 // templateConfig.setEntity("templates/entity2.java"); // templateConfig.setService(); // templateConfig.setController(); templateConfig.setXml(null); mpg.setTemplate(templateConfig); // 策略配置 StrategyConfig strategy = new StrategyConfig(); strategy.setNaming(NamingStrategy.underline_to_camel); strategy.setColumnNaming(NamingStrategy.underline_to_camel); strategy.setSuperEntityClass("com.neuedu.util.BasePojo"); strategy.setEntityLombokModel(true); strategy.setRestControllerStyle(true); // 公共父類 //strategy.setSuperControllerClass("你自己的父類控制器,沒有就不用設置!"); // 寫於父類中的公共字段 strategy.setSuperEntityColumns("id");
//是否生成單個表,不填默認所有表 strategy.setInclude("表名,可以不填"); strategy.setControllerMappingHyphenStyle(true); strategy.setTablePrefix(pc.getModuleName() + "_"); mpg.setStrategy(strategy); mpg.setTemplateEngine(new FreemarkerTemplateEngine()); mpg.execute(); } }
3、還可以用第一種方法直接生成基本的增刪改查批量刪除的controller,這就要自己稍微改進一下。