真棒!
真棒!
要是eladmin-mp能添加数据权限功能,一定会是非常好用的一个框架
eladmin-mp缺少仅本人数据权限,还有怎样自动处理数据权限
不能装centos8吗
谢谢分享
感谢分享,试试看
大佬,互换个友链, 已添加您了
{ "title": "SerMs", "screenshot": "https://bu.dusays.com/2023/10/11/65264d86ddebb.png", "url": "https://blog.serms.top/", "avatar": "https://bu.dusays.com/2023/10/11/65269ea6226c8.png", "description": "代码如诗,细节成就极致,逻辑成就完美。", "keywords": "SerMs" }
感谢大佬
博主已经添加了
名称: Fostmar博客地址: https://fostmar.online图标:https://fostmar.online/usr/uploads/2023/12/2354092855.webp简介:kali渗透、建站、数码,以博客为核心,打造生态圈
首页
统计
微语
留言
邻居
壁纸
推荐
我的开源
Search
1
快速解决 npm 安装 node-sass 速度慢/错误的问题
24,311 阅读
2
升级 element-ui 2.15.7 后遇到 el-date-picker 警告问题
10,289 阅读
3
Centos 7 彻底卸载清除 Docker 环境
8,633 阅读
4
vue 更新 sass 版本出现大量警告的坑
8,517 阅读
5
前端 axios 中 qs 介绍与使用
8,437 阅读
推荐分享
文章推荐
资源分享
软件开发
异常记录
Linux学习
日常杂记
开源
登录
Search
标签搜索
Java记录
Linux系统
eladmin开源
Web前端
Spring教程
Docker容器
其他
Git教程
Google插件
jpa
好文分享
Nginx配置
异常记录
持续集成工具
数据库
线程池
Typecho博客
Azure管理
Lambda表达式
PowerDesigner
知了小站
不怕学问浅,就怕志气短。
累计撰写
74
篇文章
累计收到
397
条评论
首页
栏目
推荐分享
文章推荐
资源分享
软件开发
异常记录
Linux学习
日常杂记
开源
页面
统计
微语
留言
邻居
壁纸
推荐
我的开源
用户登录
登录
搜索到
20
篇与
的结果
2020-08-24
Typecho 迁移到 Docker 的过程记录
前言之前博客搭建在阿里云的机器上,现在快过期了,加上原机器带宽太小,就不打算续费了,现在就需要将 Typecho 博客迁移到新机器上。以前使用的是宝塔面板搭建的,现在不想把机器环境搞得乱七八糟,因此选择使用 Docker 来搭建 Typecho。安装Docker使用一键脚本安装Dockercurl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun && systemctl start docker && systemctl enable docker如果提示 curl 命令不存在,就需要先安装 curl# Centos yum -y install curl # Ubuntu、Debian apt -y install curl配置镜像加速如果你机器是国内的机器,那么需要配置镜像加速阿里云镜像获取地址:https://cr.console.aliyun.com/cn-hangzhou/instances/mirrors修改 /etc/docker/daemon.json,文件不存在就创建一个{ "registry-mirrors": [ "你的加速地址" ] }安装数据库这里选择的是 Mariadb,可自行选择数据库镜像,这里配置参数就不做解释了,懂的都懂docker run -d -v /home/mysql:/var/lib/mysql \ -p 3306:3306 -e MYSQL_ROOT_PASSWORD=密码 \ --privileged=true --restart=always --name mariadb mariadb安装 PHP安装官方的 php:7.2-fpm 镜像后,还需要进入容器安装 mysql pdo 才能使用 Mysql 数据库,比较麻烦,这里我自己在 php:7.2-fpm 的基础上构建了个带 mysql pdo 的镜像,可以选择性使用。docker run -d -v /home/nginx/html:/var/www/html \ -p 8080:8080 --link mariadb:mariadb --name php dqjdda/php安装 Nginxdocker run -d \ --link php:php \ --name nginx --restart always \ -p 80:80 -p 443:443 \ -e "TZ=Asia/Shanghai" \ -v /home/nginx/nginx.conf:/etc/nginx/nginx.conf \ -v /home/nginx/conf.d:/etc/nginx/conf.d \ -v /home/nginx/logs:/var/log/nginx \ -v /home/nginx/cert:/etc/nginx/cert \ -v /home/nginx/html:/var/www/html \ nginx配置 Nginx/home/nginx/conf.d 用于放配置文件/home/nginx/logs 存放日志/home/nginx/cert 存放证书/home/nginx/html 存放网页在 /home/nginx/conf.d 目录创建文件 blog.confserver { listen 443 ssl http2; server_name izlzl.com; gzip on; # 缓存SSL ssl_session_cache shared:SSL:10m; ssl_session_timeout 1d; # 证书配置 ssl_certificate /etc/nginx/cert/ydyno.com/ydyno.com_chain.crt; ssl_certificate_key /etc/nginx/cert/ydyno.com/ydyno.com_key.key; root /var/www/html/ydyno; index index.php; # 伪静态 if (!-e $request_filename) { rewrite ^(.*)$ /index.php$1 last; } location ~ .*\.php(\/.*)*$ { include fastcgi_params; fastcgi_param PATH_INFO $fastcgi_path_info; fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info; fastcgi_param SCRIPT_NAME $fastcgi_script_name; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_index index.php; fastcgi_pass php:9000; } location ~* \.(jpg|jpeg|gif|png|css|js|ico|xml)$ { expires 5d; } # deny access to . files, for security location ~ /\. { log_not_found off; deny all; } } server { listen 80; server_name izlzl.com ydyno.com; return 301 https://izlzl.com$request_uri; }迁移博客直接将老服务器的博客目录移动到 /var/www/html/ydyno ,然后将数据库导出,然后导入到新库即可
2020年08月24日
2,746 阅读
7 评论
2 点赞
2020-02-20
快速解决 npm 安装 node-sass 速度慢/错误的问题
可通过配置淘宝的镜像源解决,首先配置淘宝的镜像源npm config set registry https://registry.npm.taobao.org然后在 ~/.npmrc 加入下面内容sass_binary_site=https://npm.taobao.org/mirrors/node-sass/.npmrc 文件位于win:C:\Users\[你的账户名称]\.npmrc linux:直接使用 vi ~/.npmrc完整配置如图
2020年02月20日
24,311 阅读
4 评论
19 点赞
2019-12-30
前端 axios 中 qs 介绍与使用
首先 qs 是一个 npm 仓库所管理的包,可通过 npm install qs 命令进行安装地址: https://www.npmjs.com/package/qsqs.parse()qs.parse() 将URL解析成对象的形式const Qs = require('qs'); let url = 'method=query_sql_dataset_data&projectId=85&appToken=7d22e38e-5717-11e7-907b-a6006ad3dba0'; Qs.parse(url); console.log(Qs.parse(url));qs.stringify()qs.stringify() 将对象序列化成URL的形式,以&进行拼接const Qs = require('qs'); let obj= { method: "query_sql_dataset_data", projectId: "85", appToken: "7d22e38e-5717-11e7-907b-a6006ad3dba0", datasetId: " 12564701" }; Qs.stringify(obj); console.log(Qs.stringify(obj));那么当我们需要传递数组的时候,我们就可以通过下面方式进行处理:默认情况下,它们给出明确的索引,如下代码:qs.stringify({ a: ['b', 'c', 'd'] }); // 'a[0]=b&a[1]=c&a[2]=d'也可以进行重写这种默认方式为falseqs.stringify({ a: ['b', 'c', 'd'] }, { indices: false }); // 'a=b&a=c&a=d'当然,也可以通过arrayFormat 选项进行格式化输出,如下代码所示:qs.stringify({ a: ['b', 'c'] }, { arrayFormat: 'indices' }) // 'a[0]=b&a[1]=c' qs.stringify({ a: ['b', 'c'] }, { arrayFormat: 'brackets' }) // 'a[]=b&a[]=c' qs.stringify({ a: ['b', 'c'] }, { arrayFormat: 'repeat' }) // 'a=b&a=c'在这里需要注意的是,JSON中同样存在stringify方法,但是两者之间的区别是很明显的,如下所示:{"uid":"cs11","pwd":"000000als","username":"cs11","password":"000000als"} uid=cs11&pwd=000000als&username=cs11&password=000000als如上所示,前者是采用 JSON.stringify(param) 进行处理,后者是采用 Qs.stringify(param) 进行处理的。对于JSON.stringify和JSON的使用可参见https://blog.csdn.net/suwu150/article/details/76100120原文地址:https://www.jianshu.com/p/67223e177aa6
2019年12月30日
8,437 阅读
2 评论
7 点赞
2019-12-27
解决 Vue 在 History 模式部署在 Nginx 上刷新报 404 的问题
教程适用于history模式,假设域名假设为:auauz.net原配置server { listen 80; server_name auauz.net; root /www/wwwroot/eladmin-web/dist; index index.html; error_page 404 /index.html; }修改如下server { listen 80; server_name auauz.net; location / { root /www/wwwroot/eladmin-web/dist; try_files $uri $uri/ @router; index index.html; } location @router { rewrite ^.*$ /index.html last; } }
2019年12月27日
3,899 阅读
6 评论
0 点赞
2019-12-19
ES6 语法大全 export,import,for.of循环,promise等等
变量let 局部变量 const 常量 var 全局变量字符串的拓展let str = "123" str.includes("1")//true includes方法 是否包含 str.startsWith("2")//false 是否以2开头 str.endsWith("2")//false 是否以2结尾解构表达式//数组解构 let arr = [1,2,3] const [x,y,z] = arr;// x,y,z对应 1,2,3 //对象解构 const person = { name:"jack", age:21, language:['java','php'], } let {name,age,language} = person //自定义命名 let {name:n,age:a,language} = person 函数的优化//参数上面的优化=1,指当b没有值时默认为1 function test(a,b=1){ console.log(a+b) }箭头函数//Demo1 单个参数 var demo1= fucntion demo1(obj){ console.log(obj) } 箭头函数简化为: var demo1= obj =>console.log(obj); //Demo2 两个参数 var sum =function(a,b){ console.log(a+n) } 箭头函数简化为: var sum = (a,b)=>console.log(obj); //Demo3 没有参数 let sayHello = ()=>console.log("hello!"); //Demo4 代码不止一行 使用 {} var sum = (a,b)=>{ console.log(a+n); console.log(a+n) } //Demo5 对象的函数简写 let person ={ name:“jeck”; //原来 eat:function(food){ console.log(this.name +food) } //箭头函数 eat2:food=>console.log(this.name +food) //简写版 eat3(food){ console.log(this.name +food) } } //Demo6:箭头函数配合解构表达式 let person ={ name:“jeck”; eat2:food=>console.log(this.name +food) } function test1(person){ console.log(person.name); } //简化调用函数 使用{}传参数,传入对象 var test1=({name})=>console.log(name); test1(person );map和reduce函数map 让原来的集合经过 map 中的函数 进行处理回调let arr = ['1','2','3']; arr.map(s=>parseInt(s))//字符串转化为内证书 //reduce() 接收一个函数和一个初始值 第一个参数时上一次reduce的处理结果 第二个参数是数组中要处理的下一个元素 const arr = [1,20,30,40] arr.reduce((a,b)=>a+b)拓展运算符(三个点…)将一个数组转为用逗号分隔的参数序列function add(a,b){ return a+b; } var number = [1,2]; //数组合并 var arrs=[...[1,2,3],...[4,5,6]];//[1,2,3,4,5,6] //将字符串转为数组 console.log([...'hello'])//['h','e','l','l','o']promise// 函数格式 const promise = new promise(function(resolve,reject){ //操作 //if(success){ resolve(value);//成功 }else{ reject(error)//失败 } }) //执行完了在执行一些东西的话 promise.then(function(value){ //异步回调 }).catch(function(error){ //异常回调 })set和mapset 只能保存不同元素,相同的元素会被忽略let set = new set(); let set = new set([2,3,4,5]); //map接受一个数组,数组中的元素时键值对 let map = new map([ ['key','value'], ['key1','value1'], ])for.of循环for(let obj of h){ console.log(obj) }模块化export import// export 导出命令 calss Util{ sum=(a,b)=>a+b; } export default Util // import加载 import Util from './Util'原文链接:https://blog.csdn.net/qq_35349982/article/details/103581101
2019年12月19日
2,542 阅读
3 评论
1 点赞
2019-11-06
Spring Boot 自定义异步线程池的两种方式
SpringBoot 使用异步线程池方式如下第一种创建自定义线程池配置类,AsyncTaskExecutePool@EnableAsync @Configuration public class AsyncTaskExecutePool { //核心线程池大小 private final int corePoolSize = 10; //最大线程数 private final int maxPoolSize = 15; //队列容量 private final int queueCapacity = 50; //活跃时间/秒 private final int keepAliveSeconds = 60; @Bean public Executor myAsyncTaskPool() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); //核心线程池大小 executor.setCorePoolSize(corePoolSize); //最大线程数 executor.setMaxPoolSize(maxPoolSize); //队列容量 executor.setQueueCapacity(queueCapacity); //活跃时间 executor.setKeepAliveSeconds(keepAliveSeconds); //设置线程池关闭的时候等待所有任务都完成再继续销毁其他的Bean executor.setWaitForTasksToCompleteOnShutdown(true); //线程名字前缀 executor.setThreadNamePrefix("my-async1--"); // setRejectedExecutionHandler:当pool已经达到max size的时候,如何处理新任务 // CallerRunsPolicy:不在新线程中执行任务,而是由调用者所在的线程来执行 executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); executor.initialize(); return executor; } }创建任务处理类AsyncTask@Component @Slf4j public class AsyncTask { /** * myAsyncTaskPool 线程池的方法名,此处如果不写,会使用Spring默认的线程池 * @param i */ @Async("myAsyncTaskPool") public void run(int i){ log.info("我是:" + i); } }测试线程池AppTests@SpringBootTest class AppTests { @Autowired private AsyncTask asyncTask; @Test void test(){ for (int i = 0; i < 100; i++) { asyncTask.run(i); } } } 运行查看效果第二种第二种方式是重写 spring 默认线程池,使用这种方式的好处是可以直接使用 @Async 注解创建配置类AsyncTaskExecutePool1 并且实现AsyncConfigurer 类@Slf4j @EnableAsync @Configuration public class AsyncTaskExecutePool1 implements AsyncConfigurer { //核心线程池大小 private final int corePoolSize = 10; //最大线程数 private final int maxPoolSize = 15; //队列容量 private final int queueCapacity = 50; //活跃时间/秒 private final int keepAliveSeconds = 60; @Override public Executor getAsyncExecutor() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); //核心线程池大小 executor.setCorePoolSize(corePoolSize); //最大线程数 executor.setMaxPoolSize(maxPoolSize); //队列容量 executor.setQueueCapacity(queueCapacity); //活跃时间 executor.setKeepAliveSeconds(keepAliveSeconds); //设置线程池关闭的时候等待所有任务都完成再继续销毁其他的Bean executor.setWaitForTasksToCompleteOnShutdown(true); //线程名字前缀 executor.setThreadNamePrefix("my-async-"); // setRejectedExecutionHandler:当pool已经达到max size的时候,如何处理新任务 // CallerRunsPolicy:不在新线程中执行任务,而是由调用者所在的线程来执行 executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); executor.initialize(); return executor; } /** * 异步任务异常处理 * @return */ @Override public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() { return (throwable, method, objects) -> { log.error("===="+throwable.getMessage()+"====", throwable); log.error("exception method:"+method.getName()); }; } }修改AsyncTask 类,在类中加入方法run1@Async public void run1(int i){ log.info("我是:" + i); }测试,在AppTests 中加入方法test1@Test void test1(){ for (int i = 0; i < 100; i++) { asyncTask.run1(i); } }运行查看效果注意同类中调用带有@Async 的方法是不生效的例子中的参数根据具体的需求修改源码本文源码:https://github.com/elunez/spring-boot-learn
2019年11月06日
4,148 阅读
0 评论
2 点赞
2019-10-17
Spring boot 整合 FreeMarker 实现代码生成功能
在我们开发一个新的功能的时候,会根据表创建Entity,Controller,Service,Repository等代码,其中很多步骤都是重复的,并且特别繁琐。这个时候就需要一个代码生成器帮助我们解决这个问题从而提高工作效率,让我们更致力于业务逻辑。设计原理在我们安装数据库后会有几个默认的数据库,其中information_schema这个数据库中保存了MySQL服务器所有数据库的信息,如:数据库名、数据库表、表的数据信息与访问权限等。information_schema的表tables记录了所有数据库的表的信息 information_schema的表columns记录了所有数据库的表字段详细的信息我们代码中可以可以通过Sql语句查询出当前数据库中所有表的信息,这里已 eladmin 为例。# 显示部分数据:表名称、数据库引擎、编码、表备注、创建时间 select table_name ,create_time , engine, table_collation, table_comment from information_schema.tables where table_schema = (select database());知道表的数据后,可以查询出表字段的详细数据,这里用 job 表为例sql语句如下:# 显示部分数据:字段名称、字段类型、字段注释、字段键类型等 select column_name, is_nullable, data_type, column_comment, column_key, extra from information_schema.columns where table_schema = (select database()) and table_name = "job";有了表字段信息的数据后,通过程序将数据库表字段类型转换成Java语言的字段类型,再通过FreeMarker创建模板,将数据写入到模板,输出成文件即可实现代码生成功能。代码实现这里只贴出核心代码,源码可查询文末地址,首先创建一个新的spring boot 项目,选择如下依赖Maven完整依赖如下<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-freemarker</artifactId> </dependency> <!-- 配置管理工具 --> <dependency> <groupId>commons-configuration</groupId> <artifactId>commons-configuration</artifactId> <version>1.9</version> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> <exclusions> <exclusion> <groupId>org.junit.vintage</groupId> <artifactId>junit-vintage-engine</artifactId> </exclusion> </exclusions> </dependency> </dependencies>项目结构如下教程开始修改Spring boot 配置文件 application.yml,如下service: port: 8080 spring: datasource: url: jdbc:mysql://localhost:3306/eladmin?serverTimezone=Asia/Shanghai username: root password: 123456 driver-class-name: com.mysql.jdbc.Driver jpa: show-sql: true在 resources 目录下创建 Mysql 字段与 Java字段对应关系的配置文件 generator.properties,生成代码时字段转换时使用tinyint=Integer smallint=Integer mediumint=Integer int=Integer integer=Integer bigint=Long float=Float double=Double decimal=BigDecimal bit=Boolean char=String varchar=String tinytext=String text=String mediumtext=String longtext=String date=Timestamp datetime=Timestamp timestamp=Timestamp在 vo 包下创建临时 Vo 类 ColumnInfo,该类的功能用于接收Mysql字段详细信息import lombok.AllArgsConstructor; import lombok.Data; @Data @AllArgsConstructor public class ColumnInfo { /** 数据库字段名称 **/ private Object columnName; /** 允许空值 **/ private Object isNullable; /** 数据库字段类型 **/ private Object columnType; /** 数据库字段注释 **/ private Object columnComment; /** 数据库字段键类型 **/ private Object columnKey; /** 额外的参数 **/ private Object extra; }在 util 包下创建字段工具类 ColumnUtil,该类的功能用于转换mysql类型为Java字段类型,同时添加驼峰转换方法,将表名转换成类名import org.apache.commons.configuration.Configuration; import org.apache.commons.configuration.ConfigurationException; import org.apache.commons.configuration.PropertiesConfiguration; /** * sql字段转java * * @author jie * @date 2019-01-03 */ public class ColumnUtil { private static final char SEPARATOR = '_'; /** * 获取配置信息 */ public static PropertiesConfiguration getConfig() { try { return new PropertiesConfiguration("generator.properties"); } catch (ConfigurationException e) { e.printStackTrace(); } return null; } /** * 转换mysql数据类型为java数据类型 * @param type * @return */ public static String cloToJava(String type){ Configuration config = getConfig(); return config.getString(type,null); } /** * 驼峰命名法工具 * * @return toCamelCase(" hello_world ") == "helloWorld" * toCapitalizeCamelCase("hello_world") == "HelloWorld" * toUnderScoreCase("helloWorld") = "hello_world" */ public static String toCamelCase(String s) { if (s == null) { return null; } s = s.toLowerCase(); StringBuilder sb = new StringBuilder(s.length()); boolean upperCase = false; for (int i = 0; i < s.length(); i++) { char c = s.charAt(i); if (c == SEPARATOR) { upperCase = true; } else if (upperCase) { sb.append(Character.toUpperCase(c)); upperCase = false; } else { sb.append(c); } } return sb.toString(); } /** * 驼峰命名法工具 * * @return toCamelCase(" hello_world ") == "helloWorld" * toCapitalizeCamelCase("hello_world") == "HelloWorld" * toUnderScoreCase("helloWorld") = "hello_world" */ public static String toCapitalizeCamelCase(String s) { if (s == null) { return null; } s = toCamelCase(s); return s.substring(0, 1).toUpperCase() + s.substring(1); } }在 util 包下创建代码生成工具类 GeneratorUtil,该类用于将获取到的Mysql字段信息转出Java字段类型,并且获取代码生成的路径,读取 Template,并且输出成文件,代码如下:import freemarker.template.Configuration; import freemarker.template.Template; import freemarker.template.TemplateException; import lombok.extern.slf4j.Slf4j; import org.springframework.util.ObjectUtils; import java.io.*; import java.time.LocalDate; import java.util.*; /** * 代码生成 * * @author jie * @date 2019-01-02 */ @Slf4j public class GeneratorUtil { private static final String TIMESTAMP = "Timestamp"; private static final String BIGDECIMAL = "BigDecimal"; private static final String PK = "PRI"; private static final String EXTRA = "auto_increment"; /** * 生成代码 * @param columnInfos * @param pack * @param author * @param tableName * @throws IOException */ public static void generatorCode(List<ColumnInfo> columnInfos, String pack, String author, String tableName) throws IOException { Map<String, Object> map = new HashMap<>(); map.put("package", pack); map.put("author", author); map.put("date", LocalDate.now().toString()); map.put("tableName", tableName); // 转换为小写开头的的类名, hello_world == helloWorld String className = ColumnUtil.toCapitalizeCamelCase(tableName); // 转换为大写开头的类名, hello_world == HelloWorld String changeClassName = ColumnUtil.toCamelCase(tableName); map.put("className", className); map.put("changeClassName", changeClassName); // 是否包含 Timestamp 类型 map.put("hasTimestamp", false); // 是否包含 BigDecimal 类型 map.put("hasBigDecimal", false); // 是否为自增主键 map.put("auto", false); List<Map<String, Object>> columns = new ArrayList<>(); for (ColumnInfo column : columnInfos) { Map<String, Object> listMap = new HashMap<>(); listMap.put("columnComment", column.getColumnComment()); listMap.put("columnKey", column.getColumnKey()); String colType = ColumnUtil.cloToJava(column.getColumnType().toString()); String changeColumnName = ColumnUtil.toCamelCase(column.getColumnName().toString()); if (PK.equals(column.getColumnKey())) { map.put("pkColumnType", colType); map.put("pkChangeColName", changeColumnName); } if (TIMESTAMP.equals(colType)) { map.put("hasTimestamp", true); } if (BIGDECIMAL.equals(colType)) { map.put("hasBigDecimal", true); } if (EXTRA.equals(column.getExtra())) { map.put("auto", true); } listMap.put("columnType", colType); listMap.put("columnName", column.getColumnName()); listMap.put("isNullable", column.getIsNullable()); listMap.put("changeColumnName", changeColumnName); columns.add(listMap); } map.put("columns", columns); Configuration configuration = new Configuration(Configuration.VERSION_2_3_23); configuration.setClassForTemplateLoading(GeneratorUtil.class, "/template"); Template template = configuration.getTemplate("Entity.ftl"); // 获取文件路径 String filePath = getAdminFilePath(pack, className); File file = new File(filePath); // 生成代码 genFile(file, template, map); } /** * 定义文件路径以及名称 */ private static String getAdminFilePath(String pack, String className) { String ProjectPath = System.getProperty("user.dir") + File.separator; String packagePath = ProjectPath + File.separator + "src" + File.separator + "main" + File.separator + "java" + File.separator; if (!ObjectUtils.isEmpty(pack)) { packagePath += pack.replace(".", File.separator) + File.separator; } return packagePath + "entity" + File.separator + className + ".java"; } private static void genFile(File file, Template template, Map<String, Object> params) throws IOException { File parentFile = file.getParentFile(); // 创建目录 if (null != parentFile && !parentFile.exists()) { parentFile.mkdirs(); } //创建输出流 Writer writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), "UTF-8")); //输出模板和数据模型都对应的文件 try { template.process(params, writer); } catch (TemplateException e) { e.printStackTrace(); } } }在 resources 的 template 目录下创建 framework 模板 Entity.ftl,代码如下:package ${package}.entity; import lombok.Data; import javax.persistence.*; <#if hasTimestamp> import java.sql.Timestamp; </#if> <#if hasBigDecimal> import java.math.BigDecimal; </#if> import java.io.Serializable; /** * @author ${author} * @date ${date} */ @Entity @Data @Table(name="${tableName}") public class ${className} implements Serializable { <#if columns??> <#list columns as column> <#if column.columnComment != ''> // ${column.columnComment} </#if> <#if column.columnKey = 'PRI'> @Id <#if auto> @GeneratedValue(strategy = GenerationType.IDENTITY) </#if> </#if> @Column(name = "${column.columnName}"<#if column.columnKey = 'UNI'>,unique = true</#if><#if column.isNullable = 'NO' && column.columnKey != 'PRI'>,nullable = false</#if>) private ${column.columnType} ${column.changeColumnName}; </#list> </#if> }创建服务类 GeneratorService,该类用于获取数据库表的源数据import org.springframework.stereotype.Service; import org.springframework.util.ObjectUtils; import javax.persistence.EntityManager; import javax.persistence.PersistenceContext; import javax.persistence.Query; import java.io.IOException; import java.util.ArrayList; import java.util.List; /** * 代码生成服务 */ @Service public class GeneratorService { @PersistenceContext private EntityManager em; public List<ColumnInfo> getColumns(String tableName) { StringBuilder sql = new StringBuilder("select column_name, is_nullable, data_type, column_comment, column_key, extra from information_schema.columns where "); if(!ObjectUtils.isEmpty(tableName)){ sql.append("table_name = '").append(tableName).append("' "); } sql.append("and table_schema = (select database()) order by ordinal_position"); Query query = em.createNativeQuery(sql.toString()); List result = query.getResultList(); List<ColumnInfo> columnInfos = new ArrayList<>(); for (Object o : result) { Object[] obj = (Object[])o; columnInfos.add(new ColumnInfo(obj[0],obj[1],obj[2],obj[3],obj[4],obj[5])); } return columnInfos; } }由于没有前端页面,所以只能在测试类中演示代码生成功能,GeneratorDomeApplicationTests 修改如下import com.ydyno.util.GeneratorUtil; import com.ydyno.vo.ColumnInfo; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import java.io.IOException; import java.util.List; @SpringBootTest class GeneratorDomeApplicationTests { @Autowired private GeneratorService generatorService; @Test void genTest() throws IOException { String tableName = "job"; String pack = "com.ydyno"; String author = "Zheng Jie"; List<ColumnInfo> columnInfos = generatorService.getColumns(tableName); GeneratorUtil.generatorCode(columnInfos,pack,author,tableName); } }执行后,查看创建好的Entity
2019年10月17日
7,608 阅读
1 评论
1 点赞
2019-07-09
持续集成工具 Jenkins 介绍与安装
我们在项目开发过程中,需要将已开发完的功能提交到 Git 上,然后构建与发布。如果更新很频繁,这将变得非常繁琐,并且会浪费大量时间。使用Jenkins就可以解决这个问题,当代码提交时就可以通过Jenkins自动构建与发布项目。什么是持续集成持续集成就是每完成一部分功能就向下个环节交付,通过快速的版本迭代,尽早的发现存在的问题以便开发人员修复。一个完整的持续集成系统应包含如下内容:1、一个自动构建过程(自动编译、分发、部署和测试等)2、一个代码存储库(版本控制与维护)3、一个持续集成服务器(Jenkins)什么是JenkinsJenkins是一个开源的持续集成(CI)工具,主要用于持续、自动的构建/测试软件项目。Jenkins用Java语言编写,使用时必须配置JDk环境。Jenkins 通常与版本管理工具(Git、Svn)和构建工具(Maven、Gradle)结合使用。Jenkins拥有丰富的插件库,使用Jenkins可以帮助我们自动构建各类项目Jenkins 安装安装JDK环境# 检索1.8的列表 yum list java-1.8* # 安装JDK yum install java-1.8.0-openjdk* -y # 测试 java -version安装Jenkins# 新建文件夹并且定位到改目录 mkdir /usr/local/jenkins && cd /usr/local/jenkins # 下载安装包 wget http://mirrors.jenkins-ci.org/war/latest/jenkins.war # 安装Screen,以便后台运行 yum install screen # 启动应用 nohup java -jar /usr/local/jenkins/jenkins.war --httpPort=8000 &进入系统启动应用后,在浏览器输入:ip:端口Jenkins 第一次启动时会在控制台打印出密码或者使用提示中的路径获取密码cat /root/.jenkins/secrets/initialAdminPassword进入系统后,设置用户名与密码即可
2019年07月09日
1,416 阅读
0 评论
1 点赞
2019-01-07
GIT 常用命令整理
master : 默认开发分支; origin : 默认远程版本库初始化操作$ git config -global user.name <name> #设置提交者名字 $ git config -global user.email <email> #设置提交者邮箱 $ git config -global core.editor <editor> #设置默认文本编辑器 $ git config -global merge.tool <tool> #设置解决合并冲突时差异分析工具 $ git config -list #检查已有的配置信息创建新版本库$ git clone <url> #克隆远程版本库 $ git init #初始化本地版本库修改和提交$ git add . #添加所有改动过的文件 $ git add <file> #添加指定的文件 $ git mv <old> <new> #文件重命名 $ git rm <file> #删除文件 $ git rm -cached <file> #停止跟踪文件但不删除 $ git commit -m <file> #提交指定文件 $ git commit -m “commit message” #提交所有更新过的文件 $ git commit -amend #修改最后一次提交 $ git commit -C HEAD -a -amend #增补提交(不会产生新的提交历史纪录)查看提交历史$ git log #查看提交历史 $ git log -p <file> #查看指定文件的提交历史 $ git blame <file> #以列表方式查看指定文件的提交历史 $ gitk #查看当前分支历史纪录 $ gitk <branch> #查看某分支历史纪录 $ gitk --all #查看所有分支历史纪录 $ git branch -v #每个分支最后的提交 $ git status #查看当前状态 $ git diff #查看变更内容撤消操作$ git reset -hard HEAD #撤消工作目录中所有未提交文件的修改内容 $ git checkout HEAD <file1> <file2> #撤消指定的未提交文件的 修改内容 $ git checkout HEAD. #撤消所有文件 $ git revert <commit> #撤消指定的提交分支与标签$ git branch #显示所有本地分支 $ git checkout <branch/tagname> #切换到指定分支或标签 $ git branch <new-branch> #创建新分支 $ git branch -d <branch> #删除本地分支 $ git tag #列出所有本地标签 $ git tag <tagname> #基于最新提交创建标签 $ git tag -d <tagname> #删除标签合并与衍合$ git merge <branch> #合并指定分支到当前分支 $ git rebase <branch> #衍合指定分支到当前分支远程操作$ git remote -v #查看远程版本库信息 $ git remote show <remote> #查看指定远程版本库信息 $ git remote add <remote> <url> #添加远程版本库 $ git fetch <remote> #从远程库获取代码 $ git pull <remote> <branch> #下载代码及快速合并 $ git push <remote> <branch> #上传代码及快速合并 $ git push <remote> : <branch>/<tagname> #删除### 远程分支或标签 $ git push -tags #上传所有标签
2019年01月07日
1,537 阅读
1 评论
4 点赞
1
2