关于java中使用split方法末尾空值被丢弃的问题

在最近的一次项目中,使用split方法分割字符串后得到的数组与预期不符。 查找原因后发现,使用默认的split方法时,会默认丢弃字符串末尾的空值,而字符串中间的空值则>会作为数组中的一项数据,不会被丢弃。 查询相关资料得知java中的split方法有两个参数,第一个参数是被分割的字符串,第二个参数则是一个int值,此值默认为0,丢弃末尾空数据。 而当第二个参数值大于0时,代表分割字符串后数组的最大长度,当它小于0时,代表获取数组所有值,不会丢弃末尾空值。 `String a="a,"; String[] charsArr=a.split(","); System.out.println(charsArr.length); 代码输出的是1 ` `String a="a,"; String[] charsArr=a.split(",",-1); System.out.println(charsArr.length); 代码输出的是2 `

2022年6月29日 · 1 分钟 · 天边的星星

按揭贷款的计算原理与java实现

题目描述: Mortgage Calculator – Calculate the monthly payments of a fixed term mortgage over given Nth terms at a given interest rate. Also figure out how long it will take the user to pay back the loan. 题目翻译: 按揭贷款计算器——在给定利率下,计算固定期限按揭贷款在第N期的月还款。同时计算用户需要多长时间来偿还贷款。 按揭贷款的相关概念(Mortgage) 什么是按揭贷款 抵押贷款是指提供私人资产作为债务担保进行借款,多发生于购买房地产时英航借出的抵押贷款。 抵押贷款的类型 抵押贷款的类型有多种,主要通过一下几个因素来定义抵押贷款的类型。 利率(interest) :分为固定利率和浮动利率 期限(Term) :按揭贷款通常拥有最大还款期限 还款数额与还款频率(Payment amount and frequency) :规定两次还款之间的时间间隔以及在每个周期内需要还款的数目 预付款(PrePayment):贷款方提前支付的预付款 还款方式 按揭贷款一般采用分期还款,在固定汇率的情况下,规定一个还款期限,然后每月按时还一定数额。 常见的两种还款方式:等额本息还款和等额本金还款 两种还款方案每月还款金额计算如下: 假定贷款的年利率为r,还款年限为Y年,贷款本金为P,每月还款金额为A 贷款的月利率R=r/12R=r/12, 还款期数为N=12YN=12Y 等额本息还款: 等额本息还款是指在还款时,每个月总的还款金额是相同的。每月所还本金和所还利息是变化的 假定第t个还款月还款后,剩余的总还款金额为 p(t)p(t).p(0)=Pp(1)=p(0)(1+R)−A=P(1+R)−Ap(2)=P(1)(1+R)−A=P(1+R)−A−A=P(1+R)2−(1+R)A−A…p(t)=P(1+R)t−A(1+R)t−1−A(1+R)t−2−…−A(1+R)−Ap(0)=Pp(1)=p(0)(1+R)−A=P(1+R)−Ap(2)=P(1)(1+R)−A=P(1+R)−A−A=P(1+R)2−(1+R)A−A…p(t)=P(1+R)t−A(1+R)t−1−A(1+R)t−2−…−A(1+R)−A我们可以得到每月还款后剩余还款金额p(t)p(t)的表达式:p(t)=P(1+R)t−A∑i=0t−1(1+R)i=P(1+R)t−A1−(1+R)t1−(1+R)=P(1+R)t−A(1+R)t−1Rp(t)=P(1+R)t−A∑i=0t−1(1+R)i=P(1+R)t−A1−(1+R)t1−(1+R)=P(1+R)t−A(1+R)t−1R我们给定的还款期数为N,也就是说p(N)=0p(N)=0,我们可以求出每月还款数额A。 由方程P(n)=P(1+R)N−A(1+R)N−1R=0P(n)=P(1+R)N−A(1+R)N−1R=0可以得到A=PR(1+R)N(1+R)N−1A=PR(1+R)N(1+R)N−1也就是说,如果采用等额本息的方式来还款,每月需要还款的数额为PR(1+R)N(1+R)N−1PR(1+R)N(1+R)N−1虽然每个月的还款数额相同,每月所还得利息和本金是变化的 第t+1个还款月需要还的利息i(t+1)i(t+1),为该月还款前的剩余还款金额p(t)p(t)乘以月利率Ri(t+1)=p(t)R=PR(1+R)t−A(1+R)t+A=(PR−A)(1+R)t+A=((PR−A)(1+R)t−1+A)(1+R)−A(1+R)+A=i(t)(1+R)−ARi(t+1)=p(t)R=PR(1+R)t−A(1+R)t+A=(PR−A)(1+R)t+A=((PR−A)(1+R)t−1+A)(1+R)−A(1+R)+A=i(t)(1+R)−AR因为(PR−A)<0(PR−A)<0,所以i(t)i(t)是关于t的减函数,也就是说每个月的还款金额中,利息所占的比重是降低的,而本金所占的比重是上升的 等额本金还款: 在等额本金还款方式中,每个月还款的本金是相同,但是每个月所还的利息不同,所以每个月的还款总金额是变化的。 每个月需要还得本金pr为总本金除以总的还款月数。pr=PNpr=PN每个月需要还得利息pi(t)pi(t) = (本金-已归还的本金之和)*每月利率pi(t)=(P−pr(t−1))R=−prAt+(A+P)R=−PRNt+(PN+P)Rpi(t)=(P−pr(t−1))R=−prAt+(A+P)R=−PRNt+(PN+P)R可以看到,每个月所还利息pi(t)pi(t)是关于t的减函数,说明每个月所还的利息是逐渐减少的。由于每个月所还的本金数额不变,所以每个月所还贷款总额是递减的。 ...

2021年1月18日 · 2 分钟 · 天边的星星

HTML5服务器推送事件(Server-sent-event)

HTML5服务器推送事件(Server-sent-event) 在前端开发中,实现界面推送的方式,这里大概总结下三种方式 轮询(ajax),比较耗费服务器资源。COMET方式(COMET 技术并不是 HTML 5 ) websocket 双向数据推送,灵活,功能强大 Server-sent-event(简称SSE),单项数据推送(Server-sent Events 规范是 HTML 5 规范的一个组成部分) 这里我们只讨论SSE SSE的本质:严格地说,HTTP协议无法做到服务器主动推送信息。但是有一种变通的发光法,就是服务器向客户端声明,接下来要发送的是流信息,也就是说,发送的不是一次性的数据包,而是一个数据流,会连续不断的发送过来。这是客户端不会关闭连接,会一直等待服务器发过来的数据流,视频播放就是这样的例子。本质上这种通信就是以流信息的方式,完成一次用时很长的下载。 SSE就是利用这种机制,使用流信息想浏览器推送信息。它基于HTTP协议,除了IE/Edge,其他浏览器都支持 闲谈 在Web开发中,浏览器和服务器之间使用请求/响应的交互模式。浏览器发出请求,服务器根据请求来生成响应。这种交互方式,服务器端产生数据变化后不能及时的通知给浏览,只能在浏览器下次请求的时候,才能获取(对于某些对数据实时性要求很高的应用,这种延迟是不能接受的)。 使用浏览器原生的EventSource对象的一个比较大的问题是IE并不支持(为实现在IE上COMET或轮询,第二种使用polyfill技术) SSE的客户端API部署在EventSource对象上,使用之前检测浏览器是否支持SSE if(typeof(EventSource)!=="undefined") { // 浏览器支持 Server-Sent // 一些代码..... } else { // 浏览器不支持 Server-Sent.. } var source = new EventSource(url); // url可以在当前网址同域,也可以跨域,跨域时可以指定第二个参数withCredentials 表示是否一起发送Cookies > > EventSource的readyState 表明连接的当前状态,该属性只读 > > * 0: 相当于常量EventSource.CONNECTIONG 表示连接还未建立,或者断线正在重连 > * 1:相当于常量EventSource.OPEN 表示连接已经建立,可以接受数据 > * 2:相当于常量EventSource.CLOSED 表示连接已断,且不会重连 ### Server-sent Events {#toc_2} > Server-sent Events 规范是 HTML 5 规范的一个组成部分,该规范比较简单,主要由两部分组成: > > 第一部分:服务器端与浏览器之间的通讯协议 > > 第二部分:浏览器端可以提供JavaScript中使用EventSource对象。 > > 通讯协议是基于纯文本的简单协议 > > 服务器端响应的内容类型为:text/event-stream,响应文本内容可以看成是一个事件流,有不同的事件组成。 > > 每个事件由类型和数据两个部分组成,同时每个事件可以有一个可选的标识符。不同事件的内容之间通过仅包含回车符和换行符的空行来分隔。每个事件的数据可能由多行组成。 > > 清单1 > > > ``` `data: first event data: second event id: 100 event: myevent data: third event id: 101 : this is a comment data: fourth event data: fourth event continue ` 每个事件之间通过空行来分隔。对于每行来说,冒号(:)前面表示的该行的类型,冒号后面则是对应的值。 ...

2020年8月19日 · 8 分钟 · 天边的星星

Spring boot 自定义处理404 500等

Spring boot 自定义处理404 500等 有时候我们会遇到一些问题,需要我们自定义一些异常,例如404、403、502、500等,我们这里就说说Springboot 修改自定义这些。 处理方式一 我们重写ErrorController接口,重写handleError方法 `import javax.servlet.http.HttpServletRequest; import org.springframework.boot.web.servlet.error.ErrorController; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; @Controller public class MainsiteErrorController implements ErrorController{ @RequestMapping("/error") public ModelAndView handleError(HttpServletRequest request,HttpServletResponse response){ //获取statusCode:401,404,500 //Integer statusCode = (Integer) request.getAttribute(“javax.servlet.error.status_code”); Integer statusCode =response.getStatus(); ModelAndView model = new ModelAndView(); if(statusCode == 401){ model.setViewName(“401.html”); }else if(statusCode == 404){ model.setViewName(“404.html”); }else if(statusCode == 403){ model.setViewName(“403.html”); }else{ model.setViewName(“500.html”); } return model; } @Override public String getErrorPath() { return “/error”; } ...

2020年8月12日 · 2 分钟 · 天边的星星

PDF转图片

PDF转图片 在开发过程中,我们遇到PDF 转图片的需求,这里主要介绍下Java(Apache pdfbox) Java Apache PdfBox使用 首先我们要引入Apache Pdfbox的包 gradle compile ‘org.apache.pdfbox:pdfbox:2.0.14’ maven &lt;!-- https://mvnrepository.com/artifact/org.apache.pdfbox/pdfbox --&gt; &lt;dependency&gt; &lt;groupId&gt;org.apache.pdfbox&lt;/groupId&gt; &lt;artifactId&gt;pdfbox&lt;/artifactId&gt; &lt;version&gt;2.0.14&lt;/version&gt; &lt;/dependency&gt; > > 接下来几行代码搞定 > > ``` ` import org.apache.pdfbox.pdmodel.PDDocument; import org.apache.pdfbox.pdmodel.PDPageTree; import org.apache.pdfbox.rendering.ImageType; import org.apache.pdfbox.rendering.PDFRenderer; import javax.imageio.ImageIO; import java.awt.image.BufferedImage; import java.io.File; public class App { public static void main(String[] args) { Long currentTimeMillis = System.currentTimeMillis(); File dir = new File("."); File[] filesList = dir.listFiles(); if (filesList != null) { for (File file : filesList) { if (file.isFile() && getFileExtension(file.getName()).equalsIgnoreCase("pdf")) { convert(file); } } } long diff = System.currentTimeMillis() - currentTimeMillis; System.out.print(diff); } private static String getFileExtension(String fileName) { if (fileName == null || fileName.equals("")) return "undefined"; int dotIndex = fileName.lastIndexOf("."); return (dotIndex == -1) ? "" : fileName.substring(dotIndex + 1); } private static void convert(File sourceFile) { try { String destinationDir = sourceFile.getName().replace(".pdf", "") + "/"; // converted images from pdf document are saved here File destinationFile = new File(destinationDir); if (!destinationFile.exists()) { boolean fileCreated = destinationFile.mkdir(); if (fileCreated) System.out.println("Folder Created -&gt; "+ destinationFile.getAbsolutePath()); } if (sourceFile.exists()) { System.out.println("Images copied to Folder: "+ destinationFile.getName()); PDDocument document = PDDocument.load(sourceFile); PDPageTree pdPageTree = document.getDocumentCatalog().getPages(); System.out.println("Total files to be converted -&gt; "+ pdPageTree.getCount()); PDFRenderer pdfRenderer = new PDFRenderer(document); String fileName = sourceFile.getName().replace(".pdf", ""); int pageNumber = 1; for (int page = 0; page &lt; document.getNumberOfPages(); ++page) { BufferedImage image = pdfRenderer.renderImageWithDPI(page, 150, ImageType.RGB); File outputFile = new File(destinationDir + fileName +"_"+ pageNumber +".jpg"); System.out.println("Image Created -&gt; "+ outputFile.getName()); ImageIO.write(image, "jpg", outputFile); pageNumber++; } document.close(); System.out.println("Converted Images are saved at -&gt; "+ destinationFile.getAbsolutePath()); } else { System.err.println(sourceFile.getName() +" File not exists"); } } catch (Exception e) { e.printStackTrace(); } } } ` 这里主要使用了BufferedImage与ImageIO输出图片,通Pdfbox获取到PDF的内容 ...

2020年6月30日 · 2 分钟 · 天边的星星

Spring boot 集成ElasticSearch

Spring boot 集成ElasticSearch * [第一步Spring boot集成ELasticSearch][2] * [第二步Spring boot中配置ElasticSearch][3] * [第三步 创建操作的实体Bean(我创建的是UserItemBean)][4] * [第四步 使用ElasticSearch的API进行测试][5] Spring boot 集成ElasticSearch 第一步Spring boot集成ELasticSearch `<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-elasticsearch</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> &lt;dependency&gt; &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt; &lt;artifactId&gt;spring-boot-starter-test&lt;/artifactId&gt; &lt;scope&gt;test&lt;/scope&gt; &lt;exclusions&gt; &lt;exclusion&gt; &lt;groupId&gt;org.junit.vintage&lt;/groupId&gt; &lt;artifactId&gt;junit-vintage-engine&lt;/artifactId&gt; &lt;/exclusion&gt; &lt;/exclusions&gt; &lt;/dependency&gt; &lt;dependency&gt; &lt;groupId&gt;com.alibaba&lt;/groupId&gt; &lt;artifactId&gt;fastjson&lt;/artifactId&gt; &lt;version&gt;1.2.68&lt;/version&gt; &lt;/dependency&gt; </dependencies> ` > > Spring boot集成ElasticSearch主要依赖 > > ``` `spring-boot-starter-data-elasticsearch ` 这里需要大家特别注意自己使用的ElasticSearch的版本 是否和自己的版本一致 我这里是使用的最新的ElasticSearch 7.8.0 需要配置版本 &lt;properties&gt; &lt;java.version&gt;1.8&lt;/java.version&gt; &lt;elasticsearch.version&gt;7.8.0&lt;/elasticsearch.version&gt; &lt;/properties&gt; ### 第二步Spring boot中配置ElasticSearch {#toc_2} > 创建一个<mark>ElasticSearchConfig</mark>的类,配置在下ElasticSearch的高级客户端api > > ``` `import org.apache.http.HttpHost; import org.elasticsearch.client.RestClient; import org.elasticsearch.client.RestHighLevelClient; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; /** * Elasticsearch 配置 */ @Configuration public class ElasticSearchConfig { @Bean public RestHighLevelClient restHighLevelClient(){//配置rest客户端 RestHighLevelClient client = new RestHighLevelClient( RestClient.builder( new HttpHost("192.168.1.187", 9200, "http"))); return client; } } ` 注意:这里可以配置多个ElasticSearch 只需要创建多个HttpPost即可 ...

2020年6月28日 · 4 分钟 · 天边的星星

java保留两位小数

java保留两位小数 1.使用java类库中自带的DecimalFormat类,使数字输出结果保留2位小数 代码如下: 运行结果如下: 2. 输出结果为: String.format表示字符串的格式化 3.使用BigDecimal四舍五入方法 需要导入BigDecimal类:import java.math.BigDecimal; 输出结果为: 1:scale指的是你小数点后的位数。比如123.456则score就是3. score()就是BigDecimal类中的方法啊。 比如:BigDecimal b = new BigDecimal(“123.456”); b.scale(),返回的就是3. 2:roundingMode是小数的保留模式。它们都是BigDecimal中的常量字段,有很多种。 比如:BigDecimal.ROUND_HALF_UP表示的就是4舍5入。 setScale(1)表示保留一位小数,默认用四舍五入方式 setScale(1,BigDecimal.ROUND_DOWN)直接删除多余的小数位,如2.35会变成2.3 setScale(1,BigDecimal.ROUND_UP)进位处理,2.35变成2.4 setScale(1,BigDecimal.ROUND_HALF_UP)四舍五入,2.35变成2.4 setScaler(1,BigDecimal.ROUND_HALF_DOWN)四舍五入,2.35变成2.3,如果是5则向下舍 BigDecimal的用法详解(保留两位小数,四舍五入,数字格式化,科学计数法转数字,数字里的逗号处理) 一、简介 Java在java.math包中提供的API类BigDecimal,用来对超过16位有效位的数进行精确的运算。双精度浮点型变量double可以处理16位有效数。在实际应用中,需要对更大或者更小的数进行运算和处理。float和double只能用来做科学计算或者是工程计算,在商业计算中要用java.math.BigDecimal。BigDecimal所创建的是对象,我们不能使用传统的+、-、*、/等算术运算符直接对其对象进行数学运算,而必须调用其相对应的方法。方法中的参数也必须是BigDecimal的对象。构造器是类的特殊方法,专门用来创建对象,特别是带有参数的对象。 二、构造器描述 BigDecimal(int) 创建一个具有参数所指定整数值的对象。 BigDecimal(double) 创建一个具有参数所指定双精度值的对象。 BigDecimal(long) 创建一个具有参数所指定长整数值的对象。 BigDecimal(String) 创建一个具有参数所指定以字符串表示的数值的对象。 三、方法描述 add(BigDecimal) BigDecimal对象中的值相加,然后返回这个对象。 subtract(BigDecimal) BigDecimal对象中的值相减,然后返回这个对象。 multiply(BigDecimal) BigDecimal对象中的值相乘,然后返回这个对象。 divide(BigDecimal) BigDecimal对象中的值相除,然后返回这个对象。 toString() 将BigDecimal对象的数值转换成字符串。 doubleValue() 将BigDecimal对象中的值以双精度数返回。 floatValue() 将BigDecimal对象中的值以单精度数返回。 longValue() 将BigDecimal对象中的值以长整数返回。 intValue() 将BigDecimal对象中的值以整数返回。 四、常用方法 4.1、保留两位小数 /** 保留两位小数 */ @org.junit.Test public void formatTest() { double num=13.154215; ` //方式一 DecimalFormat df1 = new DecimalFormat("0.00"); String str = df1.format(num); System.out.println(str); //13.15 //方式二 // #.00 表示两位小数 #.0000四位小数 DecimalFormat df2 =new DecimalFormat("#.00"); String str2 =df2.format(num); System.out.println(str2); //13.15 //方式三 //%.2f %. 表示 小数点前任意位数 2 表示两位小数 格式后的结果为f 表示浮点型 String result = String.format("%.2f", num); System.out.println(result); //13.15 }` String.formate用法详解: ...

2020年3月27日 · 4 分钟 · 天边的星星

Spring boot+mybatis+Sqlite环境配置

Spring boot+mybatis+Sqlite+mybatis-generator环境配置 有的时候 我们开发不需要一定要用到mysql、oracle等数据库,Sqlite也是我们的一种选择。 Sqlite使用场景 小型网站 SQLite适用于中小规模流量的网站. 日访问在10万以下的网站可以很好的支持,适用于读多写少的操作,如管理员在后台添加数据,其他访客多为浏览. 10万/天是一个临界值,事实上在100万的数据量之下,SQLite的表现还是可以的,在往上就不适合了. 使用它无需单独购买数据库服务,无需服务器进程,配置成本几乎为零,加上数据的导入导出都是复制文件,维护难度也几乎为零,迁移到别的服务器无需任何配置即可支持,加上其读取的速度非常快,省去了远程数据库的链接,能够极大提升网站访问速度. 嵌入式设备 SQLite适用于手机, PDA, 机顶盒, 以及其他嵌入式设备. 作为一个嵌入式数据库它也能够很好的应用于客户端程序. 因为其轻量,小巧,不怎么占用内存,数据的读写性能好,加上嵌入式设备数据量并不大,不需要频繁的维护,所以比较适合. 数据库教学 SQLite 支持 SQL92(SQL2)标准的大多数查询语言的功能。 其无配置,无依赖,小巧,单一文件的特性让它的安装和使用非常简单,非常适合用来讲解SQL语句. 学生可以在很短的时候使用并操作SQLite,不受系统和商业限制等影响,学习的结果可以通过邮件或者云文件等形式发送给老师进行评分. 可以通过它快速实现一个最小化应用,适合学生快速了解SQLite,以及SQL语法,从而实现数据库的触类旁通,了解其他数据库系统的设计实现原则. 本地应用程序 其单一磁盘文件的特性,并且不支持远程连接,使其适用于本地的应用程序,如PC客户端软件. 常用的应用类型为金融分析工具、CAD 包、档案管理程序等等. (手机上的通讯录也是用此开发的) 没有远程,意味着适用于内部或者临时的数据库,用来处理一些数据,让程序更加灵活. 不适用场景 很明显其适合小型网站,相对的就不适合高流量网站.,也不适合超大的数据集,在其缺点也提到,不适合高并发访问. POM.xm配置 `<?xml version=“1.0” encoding=“UTF-8”?> <project xmlns=“http://maven.apache.org/POM/4.0.0" xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=“http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.2.1.RELEASE</version> <relativePath/> <!– lookup parent from repository –> </parent> <groupId>com.zdltech.test</groupId> <artifactId>sqlitetest</artifactId> <version>0.0.1-SNAPSHOT</version> <name>sqlitetest</name> <description>Demo project for Spring Boot</description> &lt;properties&gt; &lt;java.version&gt;1.8&lt;/java.version&gt; &lt;/properties&gt; &lt;dependencies&gt; &lt;dependency&gt; &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt; &lt;artifactId&gt;spring-boot-starter-jdbc&lt;/artifactId&gt; &lt;/dependency&gt; &lt;dependency&gt; &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt; &lt;artifactId&gt;spring-boot-starter-thymeleaf&lt;/artifactId&gt; &lt;/dependency&gt; &lt;dependency&gt; &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt; &lt;artifactId&gt;spring-boot-starter-web&lt;/artifactId&gt; &lt;/dependency&gt; &lt;dependency&gt; &lt;groupId&gt;org.mybatis.spring.boot&lt;/groupId&gt; &lt;artifactId&gt;mybatis-spring-boot-starter&lt;/artifactId&gt; &lt;version&gt;2.1.1&lt;/version&gt; &lt;/dependency&gt; &lt;dependency&gt; &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt; &lt;artifactId&gt;spring-boot-starter-test&lt;/artifactId&gt; &lt;scope&gt;test&lt;/scope&gt; &lt;exclusions&gt; &lt;exclusion&gt; &lt;groupId&gt;org.junit.vintage&lt;/groupId&gt; &lt;artifactId&gt;junit-vintage-engine&lt;/artifactId&gt; &lt;/exclusion&gt; &lt;/exclusions&gt; &lt;/dependency&gt; &lt;!-- https://mvnrepository.com/artifact/org.xerial/sqlite-jdbc --&gt; &lt;dependency&gt; &lt;groupId&gt;org.xerial&lt;/groupId&gt; &lt;artifactId&gt;sqlite-jdbc&lt;/artifactId&gt; &lt;version&gt;3.28.0&lt;/version&gt; &lt;/dependency&gt; &lt;!-- druid--&gt; &lt;dependency&gt; &lt;groupId&gt;com.alibaba&lt;/groupId&gt; &lt;artifactId&gt;druid&lt;/artifactId&gt; &lt;version&gt;1.1.14&lt;/version&gt; &lt;/dependency&gt; &lt;/dependencies&gt; &lt;build&gt; &lt;plugins&gt; &lt;plugin&gt; &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt; &lt;artifactId&gt;spring-boot-maven-plugin&lt;/artifactId&gt; &lt;/plugin&gt; &lt;plugin&gt; &lt;groupId&gt;org.mybatis.generator&lt;/groupId&gt; &lt;artifactId&gt;mybatis-generator-maven-plugin&lt;/artifactId&gt; &lt;version&gt;1.3.7&lt;/version&gt; &lt;/plugin&gt; &lt;/plugins&gt; &lt;/build&gt; </project> ` ...

2019年11月28日 · 2 分钟 · 天边的星星

Redis 安装及使用

Redis 安装及使用 Redis是一个开源的使用ANSI [C语言][1]编写、支持网络、可基于内存亦可持久化的日志型、Key-Value[数据库][2],并提供多种语言的API redis是一个key-value[存储系统][3]。和Memcached类似,它支持存储的value类型相对更多,包括string(字符串)、list([链表][4])、set(集合)、zset(sorted set –有序集合)和hash(哈希类型)。这些[数据类型][5]都支持push/pop、add/remove及取交集并集和差集及更丰富的操作,而且这些操作都是原子性的。在此基础上,redis支持各种不同方式的排序。与memcached一样,为了保证效率,数据都是缓存在内存中。区别的是redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,并且在此基础上实现了master-slave(主从)同步。 Redis 是一个高性能的key-value数据库。 redis的出现,很大程度补偿了[memcached][6]这类key/value存储的不足,在部 分场合可以对关系数据库起到很好的补充作用。它提供了Java,C/C++,C#,PHP,JavaScript,Perl,Object-C,Python,Ruby,Erlang等客户端,使用很方便。 Redis支持主从同步。数据可以从主服务器向任意数量的从服务器上同步,从服务器可以是关联其他从服务器的主服务器。这使得Redis可执行单层树复制。存盘可以有意无意的对数据进行写操作。由于完全实现了发布/订阅机制,使得从数据库在任何地方同步树时,可订阅一个频道并接收主服务器完整的消息发布记录。同步对读取操作的可扩展性和数据冗余很有帮助。 Redis应用场景 缓存(数据查询、短连接、新闻内容、商品内容等等)。(使用最多) 分布式集群架构中的session分离。 聊天室的在线好友列表。 任务队列。(秒杀、抢购、12306等等) 应用排行榜。 网站访问统计。 数据过期处理(可以精确到毫秒) 安装Redis 这里通过源码编译安装,大家也可以使用其他打包好的直接安装 进入服务器 wget 和tar要是没有 通过yum install wget tar来进行安装 执行下载源码命令 wget http://download.redis.io/releases/redis-5.0.5.tar.gz > > 解压 > > ``` `tar xzf redis-5.0.5.tar.gz ` 进入解压目录 cd redis-5.0.5 > > 编译 > > ``` `make ` make[1]: Entering directory `/opt/redis-5.0.5/src' CC Makefile.dep make[1]: Leaving directory`/opt/redis-5.0.5/src' ...

2019年9月26日 · 3 分钟 · 天边的星星

Shiro 简单入门

Shiro 简单入门 Apache Shiro是一个强大且易用的Java安全框架,执行身份验证、授权、密码和会话管理。使用Shiro的易于理解的API,您可以快速、轻松地获得任何应用程序,从最小的移动应用程序到最大的网络和企业应用程序。 三个核心组件:Subject, SecurityManager 和 Realms. Subject:即“当前操作用户”。但是,在Shiro中,Subject这一概念并不仅仅指人,也可以是第三方进程、后台帐户(Daemon Account)或其他类似事物。它仅仅意味着“当前跟软件交互的东西”。 Subject代表了当前用户的安全操作,SecurityManager则管理所有用户的安全操作。 SecurityManager:它是Shiro框架的核心,典型的Facade模式,Shiro通过SecurityManager来管理内部组件实例,并通过它来提供安全管理的各种服务。 Realm: Realm充当了Shiro与应用安全数据间的“桥梁”或者“连接器”。也就是说,当对用户执行认证(登录)和授权(访问控制)验证时,Shiro会从应用配置的Realm中查找用户及其权限信息。 从这个意义上讲,Realm实质上是一个安全相关的DAO:它封装了数据源的连接细节,并在需要时将相关数据提供给Shiro。当配置Shiro时,你必须至少指定一个Realm,用于认证和(或)授权。配置多个Realm是可以的,但是至少需要一个。 Shiro内置了可以连接大量安全数据源(又名目录)的Realm,如LDAP、关系数据库(JDBC)、类似INI的文本配置资源以及属性文件等。如果缺省的Realm不能满足需求,你还可以插入代表自定义数据源的自己的Realm实现。 第一步创建Springboot项目 通过自己熟悉的工具,创建一个Springboot项目 pom.xml `<?xml version=“1.0” encoding=“UTF-8”?> <project xmlns=“http://maven.apache.org/POM/4.0.0" xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=“http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.1.7.RELEASE</version> <relativePath/> <!– lookup parent from repository –> </parent> <groupId>com.zdltech.demo</groupId> <artifactId>shiro</artifactId> <version>0.0.1-SNAPSHOT</version> <name>shiro</name> <description>shiro demo</description> &lt;properties&gt; &lt;java.version&gt;1.8&lt;/java.version&gt; &lt;/properties&gt; &lt;dependencies&gt; &lt;dependency&gt; &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt; &lt;artifactId&gt;spring-boot-starter-thymeleaf&lt;/artifactId&gt; &lt;/dependency&gt; &lt;dependency&gt; &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt; &lt;artifactId&gt;spring-boot-starter-web&lt;/artifactId&gt; &lt;/dependency&gt; &lt;dependency&gt; &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt; &lt;artifactId&gt;spring-boot-starter-test&lt;/artifactId&gt; &lt;scope&gt;test&lt;/scope&gt; &lt;/dependency&gt; &lt;!--shiro 依赖添加--&gt; &lt;!-- https://mvnrepository.com/artifact/org.apache.shiro/shiro-spring --&gt; &lt;dependency&gt; &lt;groupId&gt;org.apache.shiro&lt;/groupId&gt; &lt;artifactId&gt;shiro-spring&lt;/artifactId&gt; &lt;version&gt;1.4.1&lt;/version&gt; &lt;/dependency&gt; &lt;/dependencies&gt; &lt;build&gt; &lt;plugins&gt; &lt;plugin&gt; &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt; &lt;artifactId&gt;spring-boot-maven-plugin&lt;/artifactId&gt; &lt;/plugin&gt; &lt;/plugins&gt; &lt;/build&gt; </project> ` ...

2019年9月17日 · 4 分钟 · 天边的星星