电脑知识|欧美黑人一区二区三区|软件|欧美黑人一级爽快片淫片高清|系统|欧美黑人狂野猛交老妇|数据库|服务器|编程开发|网络运营|知识问答|技术教程文章 - 好吧啦网

您的位置:首頁技術文章
文章詳情頁

springboot整合freemarker代碼自動生成器

瀏覽:3日期:2023-03-09 10:45:01
目錄手擼一個代碼自動生成器!!技術架構開發步驟:一、創建工程二、數據庫連接操作三、加載數據表信息創建配置接口Controller四、代碼生成五、測試手擼一個代碼自動生成器!!

實現功能:MyBatis 逆向工程

技術架構

頁面是用 Vue ,element-ui開發;網絡請求是 Axios。服務端是 Spring Boot頁面模版是 Freemarker:

springboot整合freemarker代碼自動生成器

開發步驟:一、創建工程

springboot整合freemarker代碼自動生成器

二、數據庫連接操作

1.所需包結構

springboot整合freemarker代碼自動生成器

2.在model包中創建Db類

作用:用于接受前端傳來數據庫連接相關的值(username,password,url)

package com.example.generate_code.model;/** * @author: 王澤 */public class Db { private String username; private String password; private String url; public String getUsername() {return username; } public void setUsername(String username) {this.username = username; } public String getPassword() {return password; } public void setPassword(String password) {this.password = password; } public String getUrl() {return url; } public void setUrl(String url) {this.url = url; }}

3.在model中創建RespBean類

自定義響應類,返回數據更方便

package com.example.generate_code.model;/** * @author: 王澤 */public class RespBean { private Integer status; private String msg; private Object obj; public static RespBean ok(String msg,Object obj) {return new RespBean(200, msg, obj); } public static RespBean ok(String msg) {return new RespBean(200, msg, null); } public static RespBean error(String msg,Object obj) {return new RespBean(500, msg, obj); } public static RespBean error(String msg) {return new RespBean(500, msg, null); } private RespBean() { } private RespBean(Integer status, String msg, Object obj) {this.status = status;this.msg = msg;this.obj = obj; } public Integer getStatus() {return status; } public void setStatus(Integer status) {this.status = status; } public String getMsg() {return msg; } public void setMsg(String msg) {this.msg = msg; } public Object getObj() {return obj; } public void setObj(Object obj) {this.obj = obj; }}

4.在Utils中創建DBUtils

JDBC連接工具類

public class DbUtils { private static Connection connection; public static Connection getConnection() {return connection; } public static Connection initDb(Db db) {if (connection == null) { try {Class.forName('com.mysql.cj.jdbc.Driver');connection = DriverManager.getConnection(db.getUrl(), db.getUsername(), db.getPassword()); } catch (ClassNotFoundException | SQLException e) {e.printStackTrace(); }}return connection; }}

5.寫一個連接接口DbController

連接數據庫

@RestControllerpublic class DbController { @PostMapping('/connect') public RespBean connect(@RequestBody Db db) {Connection con = DBUtils.initDb(db);if (con != null) { return RespBean.ok('數據庫連接成功');}return RespBean.error('數據庫連接失敗'); }}

6.創建index頁面

<!DOCTYPE html><html lang='en'><head> <meta charset='UTF-8'> <title>代碼生成工具</title> <script src='https://cdn.jsdelivr.net/npm/vue/dist/vue.js'></script> <!-- 引入樣式 --> <link rel='stylesheet' > <!-- 引入組件庫 --> <script src='https://unpkg.com/element-ui/lib/index.js'></script> <script src='https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js'></script></head><body><div id='app'> <table><tr> <td><el-tag size='mini'>數據庫用戶名:</el-tag> </td> <td><el-input size='mini' v-model='db.username'></el-input> </td></tr><tr> <td><el-tag size='mini'>數據庫密碼:</el-tag> </td> <td><el-input size='mini' v-model='db.password'></el-input> </td></tr><tr> <td><el-tag size='mini'>數據庫連接地址:</el-tag> </td> <td><el-input size='mini' v-model='db.url'> <template slot='prepend'>jdbc:mysql://</template> <template slot='append'>?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai </template></el-input> </td></tr> </table> <div style='display: flex'><el-button type='primary' size='mini' @click='connect' :disabled='!connectBtnEnabled'>連接數據庫</el-button><div style='color: #ff018d;font-weight: bold'>[{{msg}}]</div><el-input v-model='packageName' size='mini' style='width: 300px'></el-input><el-button type='primary' size='mini' @click='config'>配置</el-button> </div></div><script> new Vue({el: '#app',data: function () { return {packageName: ’’,msg: ’數據庫未連接’,connectBtnEnabled: true,db: { username: 'root', password: '123456', url: 'localhost:3306/'} }},methods: { connect() {let _this = this;this.db.url = 'jdbc:mysql://' + this.db.url + '?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai';axios.post(’/connect’, this.db) .then(function (response) {_this.msg = response.data.msg;_this.db = { username: 'root', password: '123456', url: 'localhost:3306/'}_this.connectBtnEnabled = false; }) .catch(function (error) {console.log(error); }); }} })</script></body></html>

springboot整合freemarker代碼自動生成器

三、加載數據表信息

1.服務器端編寫

ColumnClass 用來描述表中的每一列

package com.example.generate_code.model;/** * @author: 王澤 */public class ColumnClass { private String propertyName; //對應java屬性的名字 private String columnName; //數據庫中的名字 private String type;//字段類型 private String remark; //備注 private Boolean isPrimary; //字段是不是一個主鍵 @Override public String toString() {return 'ColumnClass{' +'propertyName=’' + propertyName + ’’’ +', columnName=’' + columnName + ’’’ +', type=’' + type + ’’’ +', remark=’' + remark + ’’’ +', isPrimary=' + isPrimary +’}’; } public String getPropertyName() {return propertyName; } public void setPropertyName(String propertyName) {this.propertyName = propertyName; } public String getColumnName() {return columnName; } public void setColumnName(String columnName) {this.columnName = columnName; } public String getType() {return type; } public void setType(String type) {this.type = type; } public String getRemark() {return remark; } public void setRemark(String remark) {this.remark = remark; } public Boolean getPrimary() {return isPrimary; } public void setPrimary(Boolean primary) {isPrimary = primary; }}

描述一個具體的表的信息 TableClass

package com.example.generate_code.model;import java.util.List;/** * @author: 王澤 */public class TableClass { private String tableName; //表名 ,以下是生成的名字 private String modelName; private String serviceName; private String mapperName; private String controllerName; private String packageName; private List<ColumnClass> columns; // 字段 @Override public String toString() {return 'TableClass{' +'tableName=’' + tableName + ’’’ +', modelName=’' + modelName + ’’’ +', serviceName=’' + serviceName + ’’’ +', mapperName=’' + mapperName + ’’’ +', controllerName=’' + controllerName + ’’’ +', packageName=’' + packageName + ’’’ +', columns=' + columns +’}’; } public String getTableName() {return tableName; } public void setTableName(String tableName) {this.tableName = tableName; } public String getModelName() {return modelName; } public void setModelName(String modelName) {this.modelName = modelName; } public String getServiceName() {return serviceName; } public void setServiceName(String serviceName) {this.serviceName = serviceName; } public String getMapperName() {return mapperName; } public void setMapperName(String mapperName) {this.mapperName = mapperName; } public String getControllerName() {return controllerName; } public void setControllerName(String controllerName) {this.controllerName = controllerName; } public String getPackageName() {return packageName; } public void setPackageName(String packageName) {this.packageName = packageName; } public List<ColumnClass> getColumns() {return columns; } public void setColumns(List<ColumnClass> columns) {this.columns = columns; }}創建配置接口Controller

用map來接受前端傳來的數據

用到了谷歌提供的工具包guava,需要導入依賴

@PostMapping('/config') public RespBean config(@RequestBody Map<String, String> map) {String packageName = map.get('packageName');try { Connection connection = DBUtils.getConnection(); DatabaseMetaData metaData = connection.getMetaData(); ResultSet tables = metaData.getTables(connection.getCatalog(), null, null, null); List<TableClass> tableClassList = new ArrayList<>(); while (tables.next()) {TableClass tableClass = new TableClass();tableClass.setPackageName(packageName);String table_name = tables.getString('TABLE_NAME');String modelName = CaseFormat.LOWER_UNDERSCORE.to(CaseFormat.UPPER_CAMEL, table_name);tableClass.setTableName(table_name);tableClass.setModelName(modelName);tableClass.setControllerName(modelName + 'Controller');tableClass.setMapperName(modelName + 'Mapper');tableClass.setServiceName(modelName+'Service');tableClassList.add(tableClass); } return RespBean.ok('數據庫信息讀取成功', tableClassList);} catch (Exception e) { e.printStackTrace();}return RespBean.error('數據庫信息讀取失敗'); }

<dependency> <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> <version>30.1-jre</version></dependency>

2.完善index頁面

<!DOCTYPE html><html lang='en'><head> <meta charset='UTF-8'> <title>代碼生成工具</title> <script src='https://cdn.jsdelivr.net/npm/vue/dist/vue.js'></script> <!-- 引入樣式 --> <link rel='stylesheet' > <!-- 引入組件庫 --> <script src='https://unpkg.com/element-ui/lib/index.js'></script> <script src='https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js'></script></head><body><div id='app'> <table><tr> <td><el-tag size='mini'>數據庫用戶名:</el-tag> </td> <td><el-input size='mini' v-model='db.username'></el-input> </td></tr><tr> <td><el-tag size='mini'>數據庫密碼:</el-tag> </td> <td><el-input size='mini' v-model='db.password'></el-input> </td></tr><tr> <td><el-tag size='mini'>數據庫連接地址:</el-tag> </td> <td><el-input size='mini' v-model='db.url'> <template slot='prepend'>jdbc:mysql://</template> <template slot='append'>?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai </template></el-input> </td></tr> </table> <div style='display: flex'><el-button type='primary' size='mini' @click='connect' :disabled='!connectBtnEnabled'>連接數據庫</el-button><div style='color: #ff018d;font-weight: bold'>[{{msg}}]</div><el-input v-model='packageName' size='mini' style='width: 300px'></el-input><el-button type='primary' size='mini' @click='config'>配置</el-button> </div> <el-table :data='tableData' stripe border style='width: 100%'><el-table-columnprop='tableName'label='表名稱'width='180'></el-table-column><el-table-columnlabel='實體類名稱'width='180'> <template slot-scope='scope'><el-input v-model='scope.row.modelName'></el-input> </template></el-table-column><el-table-columnlabel='Mapper名稱'> <template slot-scope='scope'><el-input v-model='scope.row.mapperName'></el-input> </template></el-table-column><el-table-columnlabel='Service名稱'> <template slot-scope='scope'><el-input v-model='scope.row.serviceName'></el-input> </template></el-table-column><el-table-columnlabel='Controller名稱'> <template slot-scope='scope'><el-input v-model='scope.row.controllerName'></el-input> </template></el-table-column> </el-table> <div><el-button @click='generateCode' type='success'>生成代碼</el-button><div style='color: #ff0114;font-weight: bold'>*{{result}}*</div><div>{{codePath}}</div> </div></div><script> new Vue({el: '#app',data: function () { return {tableData: [],packageName: ’com.wangze.test’,msg: ’數據庫未連接’,connectBtnEnabled: true,db: { username: 'root', password: '123456', url: 'localhost:3306/'} }},methods: { generateCode() {let _this = this;axios.post(’/generateCode’, this.tableData) .then(function (response) {_this.result = response.data.msg;_this.codePath = response.data.obj; }) .catch(function (error) { }); }, config() {let _this = this;axios.post(’/config’, {packageName: this.packageName}) .then(function (response) {_this.msg = response.data.msg;_this.tableData = response.data.obj; }) .catch(function (error) {console.log(error); }); }, connect() {let _this = this;this.db.url = 'jdbc:mysql://' + this.db.url + '?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai';axios.post(’/connect’, this.db) .then(function (response) {_this.msg = response.data.msg;_this.db = { username: 'root', password: '123456', url: 'localhost:3306/'}_this.connectBtnEnabled = false; }) .catch(function (error) {console.log(error); }); }} })</script></body></html>

springboot整合freemarker代碼自動生成器

四、代碼生成

1.創建模板 Model.java.ftl

package ${packageName}.model;import java.util.Date;public class ${modelName}{ <#if columns??><#list columns as column> <#if column.type=’VARCHAR’||column.type=’TEXT’||column.type=’CHAR’>/*** ${column.remark}*/private String ${column.propertyName?uncap_first}; </#if> <#if column.type=’INT’>/*** ${column.remark}*/private Integer ${column.propertyName?uncap_first}; </#if> <#if column.type=’DATETIME’>/*** ${column.remark}*/private Date ${column.propertyName?uncap_first}; </#if> <#if column.type=’BIGINT’>/*** ${column.remark}*/private Long ${column.propertyName?uncap_first}; </#if> <#if column.type=’DOUBLE’>/*** ${column.remark}*/private Double ${column.propertyName?uncap_first}; </#if> <#if column.type=’BIT’>/*** ${column.remark}*/private Boolean ${column.propertyName?uncap_first}; </#if></#list> </#if> <#if columns??><#list columns as column> <#if column.type=’VARCHAR’||column.type=’TEXT’||column.type=’CHAR’>public String get${column.propertyName}(){ return ${column.propertyName?uncap_first};}public void set${column.propertyName}(String ${column.propertyName?uncap_first}){ this.${column.propertyName?uncap_first}=${column.propertyName?uncap_first};} </#if> <#if column.type=’INT’>public Integer get${column.propertyName}(){return ${column.propertyName?uncap_first};}public void set${column.propertyName}(Integer ${column.propertyName?uncap_first}){this.${column.propertyName?uncap_first}=${column.propertyName?uncap_first};} </#if> <#if column.type=’DATETIME’>public Date get${column.propertyName}(){return ${column.propertyName?uncap_first};}public void set${column.propertyName}(Date ${column.propertyName?uncap_first}){this.${column.propertyName?uncap_first}=${column.propertyName?uncap_first};} </#if> <#if column.type=’BIGINT’>public Long get${column.propertyName}(){return ${column.propertyName?uncap_first};}public void set${column.propertyName}(Long ${column.propertyName?uncap_first}){this.${column.propertyName?uncap_first}=${column.propertyName?uncap_first};} </#if> <#if column.type=’DOUBLE’>public Double get${column.propertyName}(){return ${column.propertyName?uncap_first};}public void set${column.propertyName}(Double ${column.propertyName?uncap_first}){this.${column.propertyName?uncap_first}=${column.propertyName?uncap_first};} </#if> <#if column.type=’BIT’>public Boolean get${column.propertyName}(){return ${column.propertyName?uncap_first};}public void set${column.propertyName}(Boolean ${column.propertyName?uncap_first}){this.${column.propertyName?uncap_first}=${column.propertyName?uncap_first};} </#if></#list> </#if>}

Service.java.ftl

package ${packageName}.service;import ${packageName}.model.${modelName};import ${packageName}.mapper.${mapperName};import org.springframework.stereotype.Service;import org.springframework.beans.factory.annotation.Autowired;import java.util.List;@Servicepublic class ${serviceName}{ @Autowired ${mapperName} ${mapperName?uncap_first}; public List<${modelName}> getAll${modelName}s(){return ${mapperName?uncap_first}.getAll${modelName}s(); }}

Controller.java.ftl

package ${packageName}.controller;import ${packageName}.model.${modelName};import ${packageName}.service.${serviceName};import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.bind.annotation.RestController;import org.springframework.web.bind.annotation.GetMapping;import java.util.List;@RestControllerpublic class ${controllerName}{ @Autowired ${serviceName} ${serviceName?uncap_first}; @GetMapping('/${modelName?lower_case}s') public List<${modelName}> getAll${modelName}s(){return ${serviceName?uncap_first}.getAll${modelName}s(); }}

Mapper.java.ftl

package ${packageName}.mapper;import ${packageName}.model.${modelName};import org.apache.ibatis.annotations.Mapper;import java.util.List;@Mapperpublic interface ${mapperName}{ List<${modelName}> getAll${modelName}s();}

Mapper.xml.ftl

<!DOCTYPE mapperPUBLIC '-//mybatis.org//DTD Mapper 3.0//EN''http://mybatis.org/dtd/mybatis-3-mapper.dtd'><mapper namespace='${packageName}.mapper.${mapperName}'> <resultMap type='${packageName}.model.${modelName}'><#list columns as column> <<#if column.primary??>id<#else>result</#if> column='${column.columnName}' property='${column.propertyName?uncap_first}' jdbcType='<#if column.type=’INT’>INTEGER<#elseif column.type=’DATETIME’>TIMESTAMP<#elseif column.type=’TEXT’>VARCHAR<#else>${column.type}</#if>' /></#list> </resultMap> <select resultMap='BaseResultMap'>select * from ${tableName}; </select></mapper>

2.代碼生成Controller

package com.example.generate_code.controller;import com.example.generate_code.model.RespBean;import com.example.generate_code.model.TableClass;import com.example.generate_code.service.GenerateCodeService;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.bind.annotation.PostMapping;import org.springframework.web.bind.annotation.RequestBody;import org.springframework.web.bind.annotation.RestController;import javax.servlet.http.HttpServletRequest;import java.util.List;@RestControllerpublic class GenerateCodeController { @Autowired GenerateCodeService generateCodeService; @PostMapping('/generateCode') public RespBean generateCode(@RequestBody List<TableClass> tableClassList, HttpServletRequest req) {return generateCodeService.generateCode(tableClassList, req.getServletContext().getRealPath('/')); }}

3.編寫service

package com.example.generate_code.service;import com.example.generate_code.model.ColumnClass;import com.example.generate_code.model.RespBean;import com.example.generate_code.model.TableClass;import com.example.generate_code.utils.DBUtils;import com.google.common.base.CaseFormat;import freemarker.cache.ClassTemplateLoader;import freemarker.template.Configuration;import freemarker.template.Template;import freemarker.template.TemplateException;import org.springframework.stereotype.Service;import java.io.File;import java.io.FileOutputStream;import java.io.IOException;import java.io.OutputStreamWriter;import java.sql.Connection;import java.sql.DatabaseMetaData;import java.sql.ResultSet;import java.util.ArrayList;import java.util.List;@Servicepublic class GenerateCodeService { Configuration cfg = null; {cfg = new Configuration(Configuration.VERSION_2_3_30);cfg.setTemplateLoader(new ClassTemplateLoader(GenerateCodeService.class, '/templates'));cfg.setDefaultEncoding('UTF-8'); } public RespBean generateCode(List<TableClass> tableClassList, String realPath) {try { Template modelTemplate = cfg.getTemplate('Model.java.ftl'); Template mapperJavaTemplate = cfg.getTemplate('Mapper.java.ftl'); Template mapperXmlTemplate = cfg.getTemplate('Mapper.xml.ftl'); Template serviceTemplate = cfg.getTemplate('Service.java.ftl'); Template controllerTemplate = cfg.getTemplate('Controller.java.ftl'); Connection connection = DBUtils.getConnection(); DatabaseMetaData metaData = connection.getMetaData(); for (TableClass tableClass : tableClassList) {ResultSet columns = metaData.getColumns(connection.getCatalog(), null, tableClass.getTableName(), null);ResultSet primaryKeys = metaData.getPrimaryKeys(connection.getCatalog(), null, tableClass.getTableName());List<ColumnClass> columnClassList = new ArrayList<>();while (columns.next()) { String column_name = columns.getString('COLUMN_NAME'); String type_name = columns.getString('TYPE_NAME'); String remarks = columns.getString('REMARKS'); ColumnClass columnClass = new ColumnClass(); columnClass.setRemark(remarks); columnClass.setColumnName(column_name); columnClass.setType(type_name); columnClass.setPropertyName(CaseFormat.LOWER_UNDERSCORE.to(CaseFormat.UPPER_CAMEL, column_name)); primaryKeys.first(); while (primaryKeys.next()) {String pkName = primaryKeys.getString('COLUMN_NAME');if (column_name.equals(pkName)) { columnClass.setPrimary(true);} } columnClassList.add(columnClass);}tableClass.setColumns(columnClassList);String path = realPath + '/' + tableClass.getPackageName().replace('.', '/');generate(modelTemplate, tableClass, path + '/model/');generate(mapperJavaTemplate, tableClass, path + '/mapper/');generate(mapperXmlTemplate, tableClass, path + '/mapper/');generate(serviceTemplate, tableClass, path + '/service/');generate(controllerTemplate, tableClass, path + '/controller/'); } return RespBean.ok('代碼已生成', realPath);} catch (Exception e) { e.printStackTrace();}return RespBean.error('代碼生成失敗'); } private void generate(Template template, TableClass tableClass, String path) throws IOException, TemplateException {File folder = new File(path);if (!folder.exists()) { folder.mkdirs();}String fileName = path + '/' + tableClass.getModelName() + template.getName().replace('.ftl', '').replace('Model', '');FileOutputStream fos = new FileOutputStream(fileName);OutputStreamWriter out = new OutputStreamWriter(fos);template.process(tableClass,out);fos.close();out.close(); }}五、測試

springboot整合freemarker代碼自動生成器

springboot整合freemarker代碼自動生成器

這時候已經找到了,我們來驗證一下效果!

springboot整合freemarker代碼自動生成器

修改寫配置

spring.datasource.name=rootspring.datasource.password=123456spring.datasource.url=jdbc:mysql://localhost:3306/boot_crm?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai

pom.xml

<resources> <resource><directory>src/main/java</directory><includes> <include>**/*.xml</include></includes> </resource> <resource><directory>src/main/resources</directory> </resource></resources>

導入生成的代碼

springboot整合freemarker代碼自動生成器

運行測試

一個基本的mybatis逆向工程就完成了!

最后附上項目源代碼:Gitee

到此這篇關于springboot整合freemarker代碼自動生成器的文章就介紹到這了,更多相關springboot 代碼自動生成器內容請搜索好吧啦網以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持好吧啦網!

標簽: Spring
相關文章:
主站蜘蛛池模板: 扬尘在线监测系统_工地噪声扬尘检测仪_扬尘监测系统_贝塔射线扬尘监测设备「风途物联网科技」 | 不干胶标签-不干胶贴纸-不干胶标签定制-不干胶标签印刷厂-弗雷曼纸业(苏州)有限公司 | 亿立分板机_曲线_锯片式_走刀_在线式全自动_铣刀_在线V槽分板机-杭州亿协智能装备有限公司 | 北京网络营销推广_百度SEO搜索引擎优化公司_网站排名优化_谷歌SEO - 北京卓立海创信息技术有限公司 | 香港新时代国际美容美发化妆美甲培训学校-26年培训经验,值得信赖! | 华禹护栏|锌钢护栏_阳台护栏_护栏厂家-华禹专注阳台护栏、楼梯栏杆、百叶窗、空调架、基坑护栏、道路护栏等锌钢护栏产品的生产销售。 | 四川成都干燥设备_回转筒干燥机_脉冲除尘器_输送设备_热风炉_成都川工星科机电设备有限公司 | 天津市能谱科技有限公司-专业的红外光谱仪_红外测油仪_紫外测油仪_红外制样附件_傅里叶红外光谱技术生产服务厂商 | 上海平衡机-单面卧式动平衡机-万向节动平衡机-圈带动平衡机厂家-上海申岢动平衡机制造有限公司 | 安徽成考网-安徽成人高考网| 首页-瓜尔胶系列-化工单体系列-油田压裂助剂-瓜尔胶厂家-山东广浦生物科技有限公司 | 流水线电子称-钰恒-上下限报警电子秤-上海宿衡实业有限公司 | 云杂志网-学术期刊-首页| 微型驱动系统解决方案-深圳市兆威机电股份有限公司 | 船用烟火信号弹-CCS防汛救生圈-船用救生抛绳器(海威救生设备) | 空压机商城|空气压缩机|空压机配件-压缩机网旗下商城 | 东风体检车厂家_公共卫生体检车_医院体检车_移动体检车-锦沅科贸 | 沈阳真空机_沈阳真空包装机_沈阳大米真空包装机-沈阳海鹞真空包装机械有限公司 | 砂石生产线_石料生产线设备_制砂生产线设备价格_生产厂家-河南中誉鼎力智能装备有限公司 | 雷冲击高压发生器-水内冷直流高压发生器-串联谐振分压器-武汉特高压电力科技有限公司 | 企业VI设计_LOGO设计公司_品牌商标设计_【北京美研】 | 土壤养分检测仪_肥料养分检测仪_土壤水分检测仪-山东莱恩德仪器 大型多片锯,圆木多片锯,方木多片锯,板材多片锯-祥富机械有限公司 | 中国产业发展研究网 - 提供行业研究报告 可行性研究报告 投资咨询 市场调研服务 | 浙江华锤电器有限公司_地磅称重设备_防作弊地磅_浙江地磅售后维修_无人值守扫码过磅系统_浙江源头地磅厂家_浙江工厂直营地磅 | 东莞压铸厂_精密压铸_锌合金压铸_铝合金压铸_压铸件加工_东莞祥宇金属制品 | SF6环境监测系统-接地环流在线监测装置-瑟恩实业 | 整车VOC采样环境舱-甲醛VOC预处理舱-多舱法VOC检测环境仓-上海科绿特科技仪器有限公司 | 金联宇电缆|广东金联宇电缆厂家_广东金联宇电缆实业有限公司 | 打孔器,打孔钳厂家【温州新星德牌五金工具】 | 玻璃钢型材-玻璃钢风管-玻璃钢管道,生产厂家-[江苏欧升玻璃钢制造有限公司] | 橡胶粉碎机_橡胶磨粉机_轮胎粉碎机_轮胎磨粉机-河南鼎聚重工机械制造有限公司 | 哲力实业_专注汽车涂料汽车漆研发生产_汽车漆|修补油漆品牌厂家 长沙一级消防工程公司_智能化弱电_机电安装_亮化工程专业施工承包_湖南公共安全工程有限公司 | 盘式曝气器-微孔曝气器-管式曝气器-曝气盘-斜管填料 | 郑州市前程水处理有限公司 | 滚筒烘干机_转筒烘干机_滚筒干燥机_转筒干燥机_回转烘干机_回转干燥机-设备生产厂家 | 智能家居全屋智能系统多少钱一套-小米全套价格、装修方案 | 电磁辐射仪-电磁辐射检测仪-pm2.5检测仪-多功能射线检测仪-上海何亦仪器仪表有限公司 | 佛山市钱丰金属不锈钢蜂窝板定制厂家|不锈钢装饰线条|不锈钢屏风| 电梯装饰板|不锈钢蜂窝板不锈钢工艺板材厂家佛山市钱丰金属制品有限公司 | 环讯传媒,永康网络公司,永康网站建设,永康小程序开发制作,永康网站制作,武义网页设计,金华地区网站SEO优化推广 - 永康市环讯电子商务有限公司 | 青岛侦探调查_青岛侦探事务所_青岛调查事务所_青岛婚外情取证-青岛狄仁杰国际侦探公司 | 渗透仪-直剪仪-三轴仪|苏州昱创百科 | 吉林污水处理公司,长春工业污水处理设备,净水设备-长春易洁环保科技有限公司 |