spring cloud+vue在线视频网站 7.代码生成模块 part 1

news/2024/5/20 13:41:03/文章来源:https://blog.csdn.net/Mosiclone/article/details/109631574

这一章主要是完成代码生成的模块,用到的工具是 freemaker ,在完成代码生成模块的同时会完成小节部分的代码。

freemaker 的基本用法

一般来说一个 freemaker 的模版基本会包括下面四部分。
文本:直接输出的部分
注释:<#–2333–>格式部分,不会输出
插值:即${…}或#{…}格式的部分,将使用数据模型中的部分替代输出
FTL指令:FreeMarker指定,和HTML标记类似,名字前加#予以区分,不会输出

引入 freemaker

首先在 course 的依赖管理中添加 freemaker 依赖:

<dependency><groupId>org.freemarker</groupId><artifactId>freemarker</artifactId><version>2.3.29</version>
</dependency>

然后在 course 中新建 generator 包作为代码生成模块,pom 文件中添加 freemaker 依赖。

<dependency><groupId>org.freemarker</groupId><artifactId>freemarker</artifactId>
</dependency>

数据库持久层生成

mabatis generator 生成持久层

修改 server 中 resource 的 generatorConfig 最后的 tableName 和 domainObjectName 。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfigurationPUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN""http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd"><generatorConfiguration><context id="Mysql" targetRuntime="MyBatis3" defaultModelType="flat"><!-- 添加后sql语句中的关键字和表用``区分--><property name="beginningDelimiter" value="`"/><property name="endingDelimiter" value="`"/><!--  生成xml文件自动覆盖之前的文件  --><plugin type="org.mybatis.generator.plugins.UnmergeableXmlMappersPlugin"/><!--  生成实例类的tostring方法   --><plugin type="org.mybatis.generator.plugins.ToStringPlugin"/><!--  删除所有注释--><commentGenerator><property name="suppressAllComments" value="true"/></commentGenerator><!--连接数据库,修改自己的数据库名用户名密码--><jdbcConnection driverClass="com.mysql.jdbc.Driver"connectionURL="jdbc:mysql://localhost:3306/course"userId="root"password="czj666666"></jdbcConnection><!-- domain类的位置 --><javaModelGenerator targetProject="src/main/java"targetPackage="com.course.server.domain"/><!-- mapper xml的位置 --><sqlMapGenerator targetProject="src/main/resources"targetPackage="mapper"/><!-- mapper类的位置 --><javaClientGenerator targetProject="src/main/java"targetPackage="com.course.server.mapper"type="XMLMAPPER" /><!--        <table tableName="test" domainObjectName="Test"></table>-->
<!--        <table tableName="chapter" domainObjectName="Chapter"></table>--><table tableName="section" domainObjectName="Section"></table></context>
</generatorConfiguration>

运行 mybatis-generator 后生成持久层代码。

生成数据库表

这里用之前的 doc/db/all.sql 来生成数据库表,并添加数据。

drop table if exists `section`;
create table `section` (`id` char(8) not null default '' comment 'ID',`title` varchar(50) not null comment '标题',`course_id` char(8) comment '课程|course.id',`chapter_id` char(8) comment '大章|chapter.id',`video` char(200) comment '视频',`time` int comment '时长|单位秒',`charge` char(1) comment '收费|C 收费;F 免费',`sort` int comment '顺序',`created_at` DATETIME(3) comment '创建时间',`updated_at` datetime(3) comment '修改时间',primary key (`id`)
)engine=innodb default charset=utf8mb4 comment='小节';insert into `section` (id, title, course_id, chapter_id, video, time, charge, sort, created_at, updated_at)
values ('00000001','测试小节01','00000001','00000000','',500,'F',1,now(),now());

控制层服务层模版文件

freemaker 工具类

在 generator 模块中,创建如下结构的包。ftl 包存放 freemaker 模版文件,控制层和服务层代码都由这里的 ftl 模版生成;util 包存放 freemaker 工具类,server 中的 main 方法会调用抽离的工具类;server 中包含生成代码的 main 方法。

在这里插入图片描述

这里首先创建了一个 freemaker 的工具类。其中包含了 init 方法和 generator 方法。
其中 init 方法的作用是初始化 freemaker 设置,加载模版文件;generatro 方法的作用是生成文件并写入 map 对应的代码。

package com.course.generator.util;import freemarker.template.Configuration;
import freemarker.template.DefaultObjectWrapper;
import freemarker.template.Template;
import freemarker.template.TemplateException;import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Map;public class FreemarkerUtil {static Template temp;public static void initConfig(String ftlPath,String ftlName) throws IOException {Configuration cfg = new Configuration(Configuration.VERSION_2_3_29);cfg.setDirectoryForTemplateLoading(new File(ftlPath));cfg.setObjectWrapper(new DefaultObjectWrapper(Configuration.VERSION_2_3_29));temp = cfg.getTemplate(ftlName);}public static void generator(String fileName, Map<String, Object> map) throws IOException, TemplateException {FileWriter fw = new FileWriter(fileName);BufferedWriter bw = new BufferedWriter(fw);temp.process(map, bw);bw.flush();fw.close();}
}

控制层模板文件

模板文件有对应控制层和服务层的,这里用 ${domain} 代替 chapter ,用 ${Domain} 代替 Chapter ,在下面生成小节代码时分别用 section 和 Section 代替。

这里没有解决校验和文字的问题。
controller.ftl

package com.course.${module}.controller.admin;import com.course.server.dto.${Domain}Dto;
import com.course.server.dto.PageDto;
import com.course.server.dto.ResponseDto;
import com.course.server.service.${Domain}Service;
import com.course.server.util.ValidatorUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.*;import javax.annotation.Resource;@RestController
@RequestMapping("/admin/${domain}")
public class ${Domain}Controller {private static final Logger LOG = LoggerFactory.getLogger(${Domain}Controller.class);public static final String BUSINESS_NAME = "${tableNameCn}";@Resourceprivate ${Domain}Service ${domain}Service;@PostMapping("/list")public ResponseDto list(@RequestBody PageDto pageDto){${domain}Service.list(pageDto);ResponseDto responseDto = new ResponseDto();responseDto.setContent(pageDto);return responseDto;}@PostMapping("/save")public ResponseDto save(@RequestBody ${Domain}Dto ${domain}Dto){// 保存校验${domain}Service.save(${domain}Dto);ResponseDto responseDto = new ResponseDto();responseDto.setContent(${domain}Dto);return responseDto;}@DeleteMapping("/delete/{id}")public ResponseDto delete(@PathVariable String id){${domain}Service.delete(id);ResponseDto responseDto = new ResponseDto();return responseDto;}
}

服务层模板文件

service.ftl

package com.course.server.service;import com.course.server.domain.${Domain};
import com.course.server.domain.${Domain}Example;
import com.course.server.dto.${Domain}Dto;
import com.course.server.dto.PageDto;
import com.course.server.mapper.${Domain}Mapper;
import com.course.server.util.CopyUtil;
import com.course.server.util.UuidUtil;
import com.github.pagehelper.PageInfo;
import org.springframework.stereotype.Service;import javax.annotation.Resource;
import java.util.List;import com.github.pagehelper.PageHelper;
import org.springframework.util.StringUtils;@Service
public class ${Domain}Service {@Resourceprivate ${Domain}Mapper ${domain}Mapper;public void list(PageDto pageDto){PageHelper.startPage(pageDto.getPage(),pageDto.getSize());${Domain}Example ${domain}Example = new ${Domain}Example();List<${Domain}> ${domain}List = ${domain}Mapper.selectByExample(${domain}Example);PageInfo<${Domain}> pageInfo = new PageInfo<>(${domain}List);pageDto.setTotal(pageInfo.getTotal());List<${Domain}Dto> ${domain}DtosList;${domain}DtosList = CopyUtil.copyList(${domain}List,${Domain}Dto.class);pageDto.setList(${domain}DtosList);}public void save(${Domain}Dto ${domain}Dto){${Domain} ${domain} = CopyUtil.copy(${domain}Dto,${Domain}.class);if(StringUtils.isEmpty(${domain}.getId())){this.insert(${domain});}else{this.update(${domain});}}private void insert(${Domain} ${domain}){${domain}.setId(UuidUtil.getShortUuid());${domain}Mapper.insert(${domain});}private void update(${Domain} ${domain}){${domain}Mapper.updateByPrimaryKey(${domain});}public void delete(String id){${domain}Mapper.deleteByPrimaryKey(id);}
}

dto 层代码生成

要生成 dto 层的代码,首先要去数据库读取其中含有的字段等信息,然后将取得的信息进行处理,最后调用 generator 中的方法生成代码。

新建 field 类

其中,新建了 field 类来保存各个字段的信息:

package com.course.generator.util;public class Field {private String name; // 字段名:course_idprivate String nameHump; // 字段名小驼峰:courseIdprivate String nameBigHump; // 字段名大驼峰:CourseIdprivate String nameCn; // 中文名:课程private String type; // 字段类型:char(8)private String javaType; // java类型:Stringprivate String comment; // 注释:课程|IDpublic String getName() {return name;}public void setName(String name) {this.name = name;}public String getNameHump() {return nameHump;}public void setNameHump(String nameHump) {this.nameHump = nameHump;}public String getNameBigHump() {return nameBigHump;}public void setNameBigHump(String nameBigHump) {this.nameBigHump = nameBigHump;}public String getNameCn() {return nameCn;}public void setNameCn(String nameCn) {this.nameCn = nameCn;}public String getType() {return type;}public void setType(String type) {this.type = type;}public String getComment() {return comment;}public void setComment(String comment) {this.comment = comment;}public String getJavaType() {return javaType;}public void setJavaType(String javaType) {this.javaType = javaType;}@Overridepublic String toString() {final StringBuffer sb = new StringBuffer("Field{");sb.append("name='").append(name).append('\'');sb.append(", nameHump='").append(nameHump).append('\'');sb.append(", nameBigHump='").append(nameBigHump).append('\'');sb.append(", nameCn='").append(nameCn).append('\'');sb.append(", type='").append(type).append('\'');sb.append(", javaType='").append(javaType).append('\'');sb.append(", comment='").append(comment).append('\'');sb.append('}');return sb.toString();}
}

新建 DbUtil 类

接着新建了 DbUtil 类,来链接数据库,取到数据库表的各个字段并处理。

package com.course.generator.util;//import com.course.generator.enums.EnumGenerator;import java.sql.*;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;public class DbUtil {public static Connection getConnection() {Connection conn = null;try {Class.forName("com.mysql.jdbc.Driver");String url = "jdbc:mysql://localhost:3306/course?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai";String user = "root";String pass = "czj666666";conn = DriverManager.getConnection(url, user, pass);} catch (ClassNotFoundException e) {e.printStackTrace();} catch (SQLException e) {e.printStackTrace();}return conn;}/*** 获得表注释* @param tableName* @return* @throws Exception*/public static String getTableComment(String tableName) throws Exception {Connection conn = getConnection();Statement stmt = conn.createStatement();ResultSet rs = stmt.executeQuery("select table_comment from information_schema.tables Where table_name = '" + tableName + "'");String tableNameCH = "";if (rs != null) {while(rs.next()) {tableNameCH = rs.getString("table_comment");break;}}rs.close();stmt.close();conn.close();System.out.println("表名:" + tableNameCH);return tableNameCH;}/*** 获得所有列信息* @param tableName* @return* @throws Exception*/public static List<Field> getColumnByTableName(String tableName) throws Exception {List<Field> fieldList = new ArrayList<>();Connection conn = getConnection();Statement stmt = conn.createStatement();ResultSet rs = stmt.executeQuery("show full columns from `" + tableName + "`");if (rs != null) {while(rs.next()) {String columnName = rs.getString("Field");String type = rs.getString("Type");String comment = rs.getString("Comment");String nullAble = rs.getString("Null"); //YES NOField field = new Field();field.setName(columnName);field.setNameHump(lineToHump(columnName));field.setNameBigHump(lineToBigHump(columnName));field.setType(type);field.setJavaType(DbUtil.sqlTypeToJavaType(rs.getString("Type")));field.setComment(comment);if (comment.contains("|")) {field.setNameCn(comment.substring(0, comment.indexOf("|")));} else {field.setNameCn(comment);}fieldList.add(field);}}rs.close();stmt.close();conn.close();System.out.println("列信息:" + fieldList);return fieldList;}/*** 下划线转小驼峰*/public static String lineToHump(String str){Pattern linePattern = Pattern.compile("_(\\w)");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);return sb.toString();}/*** 下划线转大驼峰*/public static String lineToBigHump(String str){String s = lineToHump(str);return s.substring(0, 1).toUpperCase() + s.substring(1);}/*** 数据库类型转为Java类型*/public static String sqlTypeToJavaType(String sqlType) {if (sqlType.toUpperCase().contains("varchar".toUpperCase())|| sqlType.toUpperCase().contains("char".toUpperCase())|| sqlType.toUpperCase().contains("text".toUpperCase())) {return "String";} else if (sqlType.toUpperCase().contains("datetime".toUpperCase())) {return "Date";} else if (sqlType.toUpperCase().contains("int".toUpperCase())) {return "Integer";} else if (sqlType.toUpperCase().contains("long".toUpperCase())) {return "Long";} else if (sqlType.toUpperCase().contains("decimal".toUpperCase())) {return "BigDecimal";} else {return "String";}}
}

新建 dto 模板

最后新建了 dto 的模板文件。

package com.course.server.dto;<#list typeSet as type>
<#if type=='Date'>
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
</#if>
<#if type=='BigDecimal'>
import java.math.BigDecimal;
</#if>
</#list>public class ${Domain}Dto {<#list fieldList as field>/*** ${field.comment}*/<#if field.javaType=='Date'>@JsonFormat(pattern="yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")</#if>private ${field.javaType} ${field.nameHump};</#list><#list fieldList as field>public ${field.javaType} get${field.nameBigHump}() {return ${field.nameHump};}public void set${field.nameBigHump}(${field.javaType} ${field.nameHump}) {this.${field.nameHump} = ${field.nameHump};}</#list>@Overridepublic String toString() {StringBuilder sb = new StringBuilder();sb.append(getClass().getSimpleName());sb.append(" [");sb.append("Hash = ").append(hashCode());<#list fieldList as field>sb.append(", ${field.nameHump}=").append(${field.nameHump});</#list>sb.append("]");return sb.toString();}}

生成方法

这里首先去读取 generatorConfig.xml 中修改的 tableName 和 domainObjectName ,接着调用 DbUtil 中的方法读取处理各个字段,最后分别生成各个模块的代码。

package com.course.generator.server;import com.course.generator.util.DbUtil;
import com.course.generator.util.Field;
import com.course.generator.util.FreemarkerUtil;
import freemarker.template.TemplateException;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;import java.io.File;
import java.io.IOException;
import java.util.*;public class ServerGenerator {static String MODULE = "business";static String ftlPath = "/Users/chenzhijie/Documents/course/generator/src/main/java/com/course/generator/ftl/";static String toDtoPath = "/Users/chenzhijie/Documents/course/server/src/main/java/com/course/server/dto/";static String toServicePath = "/Users/chenzhijie/Documents/course/server/src/main/java/com/course/server/service/";static String toControllerPath = "/Users/chenzhijie/Documents/course/" + MODULE +"/src/main/java/com/course/" + MODULE + "/controller/admin/";static String generatorConfigPath = "/Users/chenzhijie/Documents/course/server/src/main/resources/generator/generatorConfig.xml";public static void main(String[] args) throws Exception {String module = MODULE;// 只生成配置文件中的第一个table节点File file = new File(generatorConfigPath);SAXReader reader=new SAXReader();//读取xml文件到Document中Document doc=reader.read(file);//获取xml文件的根节点Element rootElement=doc.getRootElement();//读取context节点Element contextElement = rootElement.element("context");//定义一个Element用于遍历Element tableElement;//取第一个“table”的节点tableElement=contextElement.elementIterator("table").next();String Domain = tableElement.attributeValue("domainObjectName");String tableName = tableElement.attributeValue("tableName");String tableNameCn = DbUtil.getTableComment(tableName);String domain = Domain.substring(0, 1).toLowerCase() + Domain.substring(1);System.out.println("表:"+tableElement.attributeValue("tableName"));System.out.println("Domain:"+tableElement.attributeValue("domainObjectName"));List<Field> fieldList = DbUtil.getColumnByTableName(domain);Set<String> typeSet = getJavaTypes(fieldList);Map<String, Object> map = new HashMap<>();map.put("Domain", Domain);map.put("domain", domain);map.put("tableNameCn", tableNameCn);map.put("module", module);map.put("fieldList", fieldList);map.put("typeSet", typeSet);//service层代码生成FreemarkerUtil.initConfig(ftlPath, "service.ftl");FreemarkerUtil.generator(toServicePath + Domain + "Service.java", map);//controller层代码生成FreemarkerUtil.initConfig(ftlPath, "controller.ftl");FreemarkerUtil.generator(toControllerPath + Domain + "Controller.java", map);//dto层代码生成FreemarkerUtil.initConfig(ftlPath,"dto.ftl");FreemarkerUtil.generator(toDtoPath + Domain + "Dto.java", map);}/*** 获取所有的Java类型,使用Set去重*/private static Set<String> getJavaTypes(List<Field> fieldList) {Set<String> set = new HashSet<>();for (int i = 0; i < fieldList.size(); i++) {Field field = fieldList.get(i);set.add(field.getJavaType());}return set;}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_894727.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

网站检测方式个人总结

这几天看架构看的头晕&#xff0c;觉得有点看不下去了 换个心情&#xff0c;等状态调整过来再继续看 趁这个时间休息一些&#xff0c;也正好把之前学过的知识做一个总结。 首先表明立场 这只是一个总结 并不是教大家什么 我的水平没有那么高 这是一个提醒自己的备忘 但是如果有…

用了2周时间,终于把Python网站开发库大全整理完了

用了 2 周的时间整理了 Python 中所有的网站开发库&#xff08;下文简称&#xff1a;Web 框架&#xff09;&#xff0c;供大家学习参考。 相关文件 小伙伴们可以关注小编的Python源码、问题解答&学习交流群&#xff1a;733089476 有很多的资源可以白嫖的哈&#xff0c;需…

今天给大家介绍一下~我学习 Python 的 三个神级网站

今天来给大家介绍三个我在学习 Python 路上帮助比较大的堪称神级的网站&#xff0c;尤其是对于刚刚入门的同学来说&#xff0c;绝对不容错过~ 相关文件 小伙伴们可以关注小编的Python源码、问题解答&学习交流群&#xff1a;733089476 有很多的资源可以白嫖的哈&#xff0…

WEB网站加速CND加速工作原理

转自&#xff1a;https://blog.csdn.net/5hongbing/article/details/78025349 通过传统的未加缓存服务的访问过程与加缓存服务的访问过程对比&#xff0c;了解CDN缓存访问方式与未加缓存访问方式的差别。 1.传统访问过程(未加速缓存服务) 访问未使用CDN缓存后的网站的过程&…

逛Github网站显示中文教程

打开Github对于看不懂英文的孩子来说刚打开官网就尬住了&#xff0c;后来逛了很多网站才发现一个方法可以将网站的部分内容转换为中文&#xff0c;虽然说是部分的&#xff0c;但是也够用了差不多。下面放教程。 1.找到自己浏览器安装扩展插件的地方&#xff0c;我测试的360浏览…

三日娱乐活动之——建立自己的网站

目录 云服务器搭建SSH登陆LNMP环境的搭建Nginx的设置小节总结 网页的编写CSS的调用php文件上传小节总结 云服务器搭建 我用的是阿里云的学生机&#xff0c;自己娱乐娱乐够用了&#xff0c;稍微懂点Linux的知识&#xff0c;选择Centos7的系统就可以耍了。 SSH登陆 我直接用密…

Vs2010创建网站

1.打开VS2010&#xff0c;新建——网站——ASP.Net空网站。 2.创建网站后你会发现你的项目并没有.sln结尾的文件&#xff0c;像这样。 事实上项目的.sln文件保存到了C:\Users\zjs\Documents\Visual Studio 2010\Projects 我一般会把这个.sln文件拷贝到项目所对应的文件夹目录。…

公安内网部署网站出现500.19-Internal Server Error

今天去桂林叠彩分局&#xff0c;帮他们部署一个内网平台的网站。去了机房&#xff0c;windowserver2012系统已装好。我本想我的工作会很快弄完。无非就是在这个系统上安装一个oracle数据库&#xff0c;然后在iis部署一个网站&#xff0c;网站能呈现数据就ok了。Oracle数据库安装…

我的网站收入

建站有好几个月了&#xff0c;但申请google adsense和阿里妈妈并且成功通过却是上个月的事情。到目前为止&#xff0c;google adsense帐户的估算总收入为1.79美元&#xff0c;阿里妈妈的收入为2.52元&#xff0c;看到这里&#xff0c;或者很多读者都会嗤之以鼻&#xff0c;甚至…

没有网站也能网赚

如果你能持之以恒&#xff0c;而且文档质量高的话&#xff0c;那么月入过万也不是没有可能的。 2009年5月&#xff0c;我在建站的过程中为了找点资料&#xff0c;通过搜索引擎搜索到了豆丁&#xff0c;还记得当时是为了搜索关于google map的资料&#xff0c;很多地方都没有找到…

前端常见SEO注意事项

前端开发工程师不仅需要要跟视觉设计师、交互式设计师配合&#xff0c;完美还原设计图稿&#xff0c;编写兼容各大浏览器、加载速度快、用户体验好的页面。现在还需要跟SEO人员配合&#xff0c;调整页面的代码结构和标签。 一些成熟的平台&#xff0c;在开发初期并没有考虑优化…

精通Web Analytics 2.0 (3) 第一章:网站分析的新奇世界

精通Web Analytics 2.0 &#xff08;3&#xff09; 第一章&#xff1a;网站分析的新奇世界 精通Web Analytics 2.0 : 用户中心科学与在线统计艺术 第一章&#xff1a;Web Analytics 2.0的新奇世界 多年以来&#xff0c;我们很清楚的知道&#xff0c;网站分析能够真正的改革网络…

精通Web Analytics 2.0 (12) 第十章:针对潜在的网站分析陷阱的最佳解决方案

精通Web Analytics 2.0 &#xff08;12&#xff09; 第十章&#xff1a;针对潜在的网站分析陷阱的最佳解决方案 精通Web Analytics 2.0 : 用户中心科学与在线统计艺术 第十章&#xff1a;针对潜在的网站分析陷阱的最佳解决方案 是时候去处理网站分析中最棘手的一些问题了&…

学习Python一定要知道的八个网站,看看你知道几个

导语 最近很多人问我有没有可以跟着学习的网站&#xff0c;一个人学没方向&#xff0c;老是不知道该怎么学习&#xff0c;我今天就把自己知道的几个网站分享给大家&#xff0c;那些问我的小伙伴可以根据这个去找自己喜欢的网站哦! python是一个编程语言&#xff0c;相比其他的…

阿里云ECS建站全流程(Debian)

1. 购买域名和ECS服务器 2. 环境配置 2.1 官方教程位置 这里是按照官网上的教程进行的&#xff0c;入口如下图所示&#xff1a; 官网的教程就不抄下来了&#xff0c;看官网就行。本文章只记载官网内容之外需要补充的操作。 2.2 安装yum 因为购买服务器时选择的Debian&…

sqlmap如何用dirsearch.py协助--os -shell拿到目标网站shell

本文为博主原创文章首发于FreeBuf→https://www.freebuf.com/sectool/256588.html SQLMAP sqlmap是一个开源渗透测试工具&#xff0c; 它可以自动检测和利用SQL注入漏洞并接管数据库服务器。它具有强大的检测引擎&#xff0c;同时有众多功能&#xff0c;包括数据库指纹识别、从…

超棒的五个在线学习web编程的网站

超棒的五个在线学习web编程的网站 http://www.gbtags.com/gb/share/2523.htm# 如果你需要给自己冲冲电而又没有时间的话&#xff0c;使用一些在线学习编程的网站&#xff0c;利用一些碎片时间来学习提高自己的话&#xff0c;今天这篇文章肯定能够帮你大忙&#xff0c;本文里我…

【全源码及文档】基于JAVA的宠物网站设计与实现

摘 要 本系统是采用Java技术来构建的一个基于Web技术的B/S结构的宠物网站&#xff0c;该网站建立在Spring和Struts2框架之上&#xff0c;前台使用JSP作为开发语言&#xff0c;后台使用MySQL数据库管理系统对数据进行管理&#xff0c;开发环境选用MyEclipse&#xff0c;应用服务…

【全源码及文档】基于JSP和MySql的资讯网站的设计与开发

摘 要 互联网时代是一个资讯爆发的时代&#xff0c;人们每天都能接收到各种平台推送的各式各样的资讯&#xff0c;这些资讯有可能是用户感兴趣的&#xff0c;也有可能是用户所厌恶的&#xff0c;如何在各种各样的资讯中最高效的获取自己需要的内容成为一个普遍的问题。本课题研…