关于响应式:在Spring-data中使用r2dbc

简介上篇文章咱们讲到了怎么在Spring webFlux中应用r2dbc,明天咱们看一下怎么应用spring-data-r2dbc这个Spring data对r2dbc的封装来进行r2dbc操作。 依赖关系要应用Spring-datea-r2dbc须要配置上面的依赖关系: <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-r2dbc</artifactId> <version>2.3.3.RELEASE</version> </dependency> <!-- R2DBC H2 Driver --> <dependency> <groupId>io.r2dbc</groupId> <artifactId>r2dbc-h2</artifactId> <version>${r2dbc-h2.version}</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-webflux</artifactId> </dependency>数据库连贯配置Spring-data-r2dbc应用的是R2dbcProperties来进行配置文件的读取: 简略看一下R2dbcProperties的定义: @ConfigurationProperties(prefix = "spring.r2dbc")public class R2dbcProperties { /** * Database name. Set if no name is specified in the url. Default to "testdb" when * using an embedded database. */ private String name; /** * Whether to generate a random database name. Ignore any configured name when * enabled. */ private boolean generateUniqueName; /** * R2DBC URL of the database. database name, username, password and pooling options * specified in the url take precedence over individual options. */ private String url; /** * Login username of the database. Set if no username is specified in the url. */ private String username; /** * Login password of the database. Set if no password is specified in the url. */ private String password;相应的,看一下咱们的配置文件是怎么样的: ...

November 28, 2020 · 2 min · jiezi

关于响应式:深入理解r2dbcmysql

简介mysql应该是咱们在日常工作中应用到的一个十分广泛的数据库,尽管mysql当初是oracle公司的,然而它是开源的,市场占有率还是十分高的。 明天咱们将会介绍r2dbc在mysql中的应用。 r2dbc-mysql的maven依赖要想应用r2dbc-mysql,咱们须要增加如下的maven依赖: <dependency> <groupId>dev.miku</groupId> <artifactId>r2dbc-mysql</artifactId> <version>0.8.2.RELEASE</version></dependency>当然,如果你想应用snapshot版本的话,能够这样: <dependency> <groupId>dev.miku</groupId> <artifactId>r2dbc-mysql</artifactId> <version>${r2dbc-mysql.version}.BUILD-SNAPSHOT</version></dependency><repository> <id>sonatype-snapshots</id> <name>SonaType Snapshots</name> <url>https://oss.sonatype.org/content/repositories/snapshots</url> <snapshots> <enabled>true</enabled> </snapshots></repository>创立connectionFactory创立connectionFactory的代码实际上应用的r2dbc的标准接口,所以和之前讲到的h2的创立代码基本上是一样的: // Notice: the query string must be URL encodedConnectionFactory connectionFactory = ConnectionFactories.get( "r2dbcs:mysql://root:database-password-in-here@127.0.0.1:3306/r2dbc?" + "zeroDate=use_round&" + "sslMode=verify_identity&" + "useServerPrepareStatement=true&" + "tlsVersion=TLSv1.3%2CTLSv1.2%2CTLSv1.1&" + "sslCa=%2Fpath%2Fto%2Fmysql%2Fca.pem&" + "sslKey=%2Fpath%2Fto%2Fmysql%2Fclient-key.pem&" + "sslCert=%2Fpath%2Fto%2Fmysql%2Fclient-cert.pem&" + "sslKeyPassword=key-pem-password-in-here")// Creating a Mono using Project ReactorMono<Connection> connectionMono = Mono.from(connectionFactory.create());不同的是ConnectionFactories传入的参数不同。 咱们也反对unix domain socket的格局: // Minimum configuration for unix domain socketConnectionFactory connectionFactory = ConnectionFactories.get("r2dbc:mysql://root@unix?unixSocket=%2Fpath%2Fto%2Fmysql.sock")Mono<Connection> connectionMono = Mono.from(connectionFactory.create());同样的,咱们也反对从ConnectionFactoryOptions中创立ConnectionFactory: ...

November 22, 2020 · 4 min · jiezi

关于响应式:深入理解h2和r2dbch2

简介本文将会介绍R2DBC的H2实现r2dbc-h2的应用办法和要留神的事项。一起来看看吧。 H2数据库简介什么是H2数据库呢? H2是一个Java SQL database,它是一个开源的数据库,运行起来十分快。 H2风行的起因是它既能够当做一个独立的服务器,也能够以一个嵌套的服务运行,并且反对纯内存模式运行。 H2的jar包十分小,只有2M大小,所以非常适合做嵌套式数据库。 如果作为嵌入式数据库,则须要将h2*.jar增加到classpath中。 上面是一个简略的建设H2连贯的代码: import java.sql.*;public class Test { public static void main(String[] a) throws Exception { Connection conn = DriverManager. getConnection("jdbc:h2:~/test", "sa", ""); // add application code here conn.close(); }}如果给定地址的数据库并不存在, 同时H2还提供了一个简略的治理界面,应用上面的命令就能够启动H2治理界面: java -jar h2*.jar默认状况下拜访http://localhost:8082就能够拜访到治理界面: r2dbc-h2r2dbc-h2是r2dbc spi的一种实现。同样的应用r2dbc-h2也提供了两种h2的模式,一种是文件系统,一种是内存。 同时还提供了事务反对,prepared statements和batch statements等个性的反对。 r2dbc-h2的Maven依赖要想应用r2dbc-h2,咱们须要增加如下依赖: <dependency> <groupId>io.r2dbc</groupId> <artifactId>r2dbc-h2</artifactId> <version>${version}</version></dependency>如果你体验snapshot版本,能够增加上面的依赖: <dependency> <groupId>io.r2dbc</groupId> <artifactId>r2dbc-h2</artifactId> <version>${version}.BUILD-SNAPSHOT</version></dependency><repository> <id>spring-libs-snapshot</id> <name>Spring Snapshot Repository</name> <url>https://repo.spring.io/libs-snapshot</url></repository>建设连贯h2有两种连贯形式,file和内存,咱们别离看一下都是怎么建设连贯的: ConnectionFactory connectionFactory = ConnectionFactories.get("r2dbc:h2:mem:///testdb");Publisher<? extends Connection> connectionPublisher = connectionFactory.create();ConnectionFactory connectionFactory = ConnectionFactories.get("r2dbc:h2:file//my/relative/path");Publisher<? extends Connection> connectionPublisher = connectionFactory.create();咱们还能够通过ConnectionFactoryOptions来创立更加具体的连贯信息: ...

November 20, 2020 · 2 min · jiezi

关于响应式:响应式关系数据库处理R2DBC

简介之前咱们提到过,对于底层的数据源来说,MongoDB, Redis, 和 Cassandra 能够间接以reactive的形式反对Spring Data。而其余很多关系型数据库比方Postgres, Microsoft SQL Server, MySQL, H2 和 Google Spanner 则能够通过应用R2DBC 来实现对reactive的反对。 明天咱们就来具体解说一下R2DBC的应用。 R2DBC介绍之前咱们介绍了Reactor还有基于其之上的Spring WebFlux框架。包含vert.x,rxjava等等reactive技术。咱们实际上在应用层曾经有很多优良的响应式解决框架。 然而有一个问题就是所有的框架都须要获取底层的数据,而基本上关系型数据库的底层读写都还是同步的。 为了解决这个问题,呈现了两个规范,一个是oracle提出的 ADBC (Asynchronous Database Access API),另一个就是Pivotal提出的R2DBC (Reactive Relational Database Connectivity)。 R2DBC是基于Reactive Streams规范来设计的。通过应用R2DBC,你能够应用reactive API来操作数据。 同时R2DBC只是一个凋谢的规范,而各个具体的数据库连贯实现,须要实现这个规范。 明天咱们以r2dbc-h2为例,解说一下r2dbc在Spring webFlux中的应用。 我的项目依赖咱们须要引入r2dbc-spi和r2dbc-h2两个库,其中r2dbc-spi是接口,而r2dbc-h2是具体的实现。 同时咱们应用了Spring webflux,所以还须要引入spring-boot-starter-webflux。 具体的依赖如下: <!-- R2DBC H2 Driver --> <dependency> <groupId>io.r2dbc</groupId> <artifactId>r2dbc-h2</artifactId> <version>${r2dbc-h2.version}</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-webflux</artifactId> </dependency>创立ConnectionFactoryConnectionFactory是数据库连贯的一个具体实现,通过ConnectionFactory咱们能够创立到数据库的连贯。 先看一下数据库的配置文件,为了不便起见,这里咱们应用的是内存数据库H2 : r2dbc.url=r2dbc:h2:mem://./r2dbcr2dbc.user=sar2dbc.password=password第一个url指定的是数据库的连贯形式,上面两个是数据库的用户名和明码。 接下来咱们看一下,怎么通过这些属性来创立ConnectionFactory: @Bean public ConnectionFactory connectionFactory() { ConnectionFactoryOptions baseOptions = ConnectionFactoryOptions.parse(url); ConnectionFactoryOptions.Builder ob = ConnectionFactoryOptions.builder().from(baseOptions); if (!StringUtil.isNullOrEmpty(user)) { ob = ob.option(USER, user); } if (!StringUtil.isNullOrEmpty(password)) { ob = ob.option(PASSWORD, password); } return ConnectionFactories.get(ob.build()); }通过url能够parse失去ConnectionFactoryOptions。而后通过ConnectionFactories的get办法创立ConnectionFactory。 ...

November 18, 2020 · 2 min · jiezi

关于响应式:Reactor中的Thread和Scheduler

简介明天咱们要介绍的是Reactor中的多线程模型和定时器模型,Reactor之前咱们曾经介绍过了,它实际上是观察者模式的延长。 所以从实质上来说,Reactor是和多线程无关的。你能够把它用在多线程或者不必在多线程。 明天将会给大家介绍一下如何在Reactor中应用多线程和定时器模型。 Thread多线程先看一下之前举的Flux的创立的例子: Flux<String> flux = Flux.generate( () -> 0, (state, sink) -> { sink.next("3 x " + state + " = " + 3*state); if (state == 10) sink.complete(); return state + 1; }); flux.subscribe(System.out::println);能够看到,不论是Flux generator还是subscriber,他们实际上都是运行在同一个线程中的。 如果咱们想让subscribe产生在一个新的线程中,咱们须要新启动一个线程,而后在线程外部进行subscribe操作。 Mono<String> mono = Mono.just("hello "); Thread t = new Thread(() -> mono .map(msg -> msg + "thread ") .subscribe(v -> System.out.println(v + Thread.currentThread().getName()) ) ); t.start(); t.join();下面的例子中,Mono在主线程中创立,而subscribe产生在新启动的Thread中。 ...

November 11, 2020 · 2 min · jiezi

vue响应式原理

建立反应系统在本课程中,我们将使用与Vue源代码中发现的非常相同的技术来构建一个简单的反应系统。这将使您更好地了解Vue.js及其设计模式,并使您熟悉观察者和Dep类。 反应系统当您第一次看到Vue的反应性系统时,它就像魔术一样。 使用这个简单的应用程序: <div id="app"> <div>Price: ${{ price }}</div> <div>Total: ${{ price * quantity }}</div> <div>Taxes: ${{ totalPriceWithTax }}</div></div><script src="https://cdn.jsdelivr.net/npm/vue"></script><script> var vm = new Vue({ el: '#app', data: { price: 5.00, quantity: 2 }, computed: { totalPriceWithTax() { return this.price * this.quantity * 1.03 } } })</script>Vue以某种方式只知道如果price发生更改,它应该做三件事: 更新price我们网页上的值。重新计算相乘的表达式price * quantity,然后更新页面。totalPriceWithTax再次调用该函数并更新页面。但是,等等,我听说您想知道,Vue如何知道price更改时要更新的内容,以及如何跟踪所有内容? 这不是JavaScript编程通常的工作方式 如果您觉得不明显,那么我们必须解决的主要问题是编程通常无法采用这种方式。例如,如果我运行以下代码: let price = 5let quantity = 2let total = price * quantity // 10 right?price = 20console.log(`total is ${total}`)您认为它将打印什么?由于我们不使用Vue,因此它将进行打印10。 ...

November 5, 2019 · 4 min · jiezi

响应式开发

现在响应式没有以前那么火了,因为响应式有一个缺点,它需要将所有的资源进行加载,即使是没有显示的,很浪费资源,影响用户体验,但是日常开发中,我们仍需要使用它进行一些开发。 媒体查询(@media)媒体类型all 所有设备print 打印机设备screen 彩色的电脑屏幕speech 听觉设备(针对有听力障碍的人士,可以把页面的内容以语音的方式呈现的设备)注意:tty、tv、projection、handheld、braille、embossed、aural等几种类型在媒体查询4中已经废弃 媒体特性width 宽度 min-width 最小宽度,宽度只能比这个值大height 高度 max-height 最大高度,高度只能比这个值小orientation 方向,有下面两个值 landscape 宽度大于高度(横屏)portrait 高度大于宽度(竖屏)aspect-ratio 宽高比-webkit-device-pixel-ratio 像素比(webkit内核私有的属性)逻辑运算符and 合并多个媒体类型(并且的意思)/* 所有设备、宽度必需大于700px、横屏,这三个条件同时满足才为true */ @media (min-width:700px) and (orientation:landscape){ div{ background: green; } }, 匹配某个媒体查询(或者的意思)/* 屏幕尺寸要小于800px, 横屏,这两个只要有一个满足,整个条件就会满足*/ @media (max-width:800px),(orientation:landscape){ div{ background: pink; } }not 对媒体查询结果取反(不能单独使用,后面必需是复合语句)/* 屏幕的尺寸大于800,这个条件才能成立 */ @media not all and (max-width:800px){ div{ background: blue; } }only 仅在媒体查询匹配成功后应用样式(防范老旧浏览器)/* 彩色的屏幕,宽度大于1000px,这两个条件同时满足,整体条件才满足 */ @media only screen and (min-width:1000px){ div{ background: grey; } }响应式引入样式第一种是直接将响应式和普通样式写在一起第二种方法是将不同尺寸的样式分开,然后按需引入 <link rel="stylesheet" href="css/200.css" media="all and (min-width:200px)"> <link rel="stylesheet" href="css/400.css" media="(min-width:400px)"> <link rel="stylesheet" href="css/600.css" media="(min-width:600px)"> <link rel="stylesheet" href="css/800.css" media="(min-width:800px)"> <link rel="stylesheet" href="css/1000.css" media="(min-width:1000px)">

June 5, 2019 · 1 min · jiezi

WEB页面实现等比例缩放自适应-通过-rem-和-vw-实现

WEB页面实现等比例缩放自适应 - 通过 rem 和 vw 实现一、rem 和 vw 简介1. remrem 是相对长度单位,是指相对于根元素(即html元素)font-size(字号大小)的倍数。 浏览器支持:Caniuse 示例若根元素 font-size 为 12pxhtml { font-size: 12px;}h1 { font-size: 2rem; /* 2 × 12px = 24px */} p { font-size: 1.5rem; /* 1.5 × 12px = 18px */}div { width: 10rem; /* 10 × 12px = 120px */} 若根元素 font-size 为 16pxhtml { font-size: 16px;}h1 { font-size: 2rem; /* 2 × 16px = 32px */} p { font-size: 1.5rem; /* 1.5 × 16px = 24px */}div { width: 10rem; /* 10 × 16px = 160px */} 2. vwvw 是相对长度单位,相对于浏览器窗口的宽度,浏览器窗口宽度被均分为100个单位的vw ...

May 25, 2019 · 3 min · jiezi

创建自己的 CSS 网格系统【转载 | 译】

此文翻译自 Creating Your Own CSS Grid System | Jan,英文不好如有错误 ✖ ,请指正。CSS 网格已经存在很长时间了。它们通常捆绑在 Bootstrap 等框架中。我不是一个 Bootstrap 仇恨者,但如果你真正需要的只是一个网格,有时使用一个框架就“太过分”了。以下是如何从头开始制作自己的 CSS 网格。CSS 网格的元素我们可以看到,基本网格只包含几个元素:Container(容器)row(行)Column(列)Gutter(列之间的空间)容器(Container)容器的目的是设置整个网格的宽度。容器的宽度通常为 100%,但你可能希望设置一个最大宽度。.grid-container { width: 100%; max-width: 1200px;}列之间的空间(gutter)row 元素的目的是使其中的列不会溢出到其他行上。为此,我们将使用 clearfix hack 来确保行内的所有内容都保留在行内。/* 我们的 cleafix hack /.row: before,.row: after { content: “”; display: table; clear: both;}列(Column)column 是网格中最复杂的部分。首先,有几种不同的方法在 CSS 中定位 column,然后有各种宽度要考虑,以及响应式设计等因素。在本教程中,我们将定义 column 并赋予它们宽度。列定位(Column Positioning)float, inline-block, display: table, display: flex。这些都是在 CSS 中定位 column 的不同方法。这些方法中最容易出错和最广泛使用的是“浮动”方法。如果我们的列是空的,那么我们的浮动列将堆叠在一起。为了防止这种情况,给 column 提供 1px 的最小高度并使它们浮动。[class=‘col-’] { float: left; min-height: 1px; }列宽(Column Widths)要查找一列的宽度,我们所要做的就是将总列数除以容器的宽度。在我们的例子中,容器的宽度是 100%,我们想要6 列,所以 100/6 = 16.66,所以我们的基本列宽度是 16.66%。[class*=‘col-’] { float: left; min-height: 1px; width: 16.66%; }这当然只是一个开始。如果我们想要一个 2 列宽的部分,我们必须创建一个 2 列宽的 column。计算非常简单。我们在使用这些列组合时唯一考虑的是,一行中的总列数最多为 6(或者总列数是多少)。响应式系统中内边距问题在 W3C 标准盒模型条件下,在响应式系统中给宽度单位为百分比的元素设置内边距很麻烦。幸运的是,使用 border-box 模型,我们可以轻松设置内边距。 /* 在网格内的所有元素上改变盒模型 /.grid-container { box-sizing: border-box; }[class=‘col-’] { float: left; min-height: 1px; width: 16.66%; / 设置内边距 / padding: 12px;}使用 * {box-sizing: border-box;} 在 CSS 中改变所有元素的盒模型。基本网格准备好了<div class=“grid-container outline”> <div class=“row”> <div class=“col-1”><p>col-1</p></div> <div class=“col-1”><p>col-1</p></div> <div class=“col-1”><p>col-1</p></div> <div class=“col-1”><p>col-1</p></div> <div class=“col-1”><p>col-1</p></div> <div class=“col-1”><p>col-1</p></div> </div> <div class=“row”> <div class=“col-2”><p>col-2</p></div> <div class=“col-2”><p>col-2</p></div> <div class=“col-2”><p>col-2</p></div> </div> <div class=“row”> <div class=“col-3”><p>col-3</p></div> <div class=“col-3”><p>col-3</p></div> </div> </div>CSS.grid-container{ width: 100%; max-width: 1200px;}/ cleafix hack /.row:before,.row:after { content:""; display: table ; clear:both;}[class=‘col-’] { float: left; min-height: 1px; width: 16.66%; padding: 12px; background-color: #FFDCDC;}.col-1{ width: 16.66%; }.col-2{ width: 33.33%; }.col-3{ width: 50%; }.col-4{ width: 66.66%; }.col-5{ width: 83.33%; }.col-6{ width: 100%; }.outline, .outline { outline: 1px solid #F6A1A1;}/ 一些额外的列内容样式 /[class=‘col-’] > p { background-color: #FFC2C2; padding: 0; margin: 0; text-align: center; color: white;}HTML<div class=“grid-container outline”> <div class=“row”> <div class=“col-1”><p>col-1</p></div> <div class=“col-1”><p>col-1</p></div> <div class=“col-1”><p>col-1</p></div> <div class=“col-1”><p>col-1</p></div> <div class=“col-1”><p>col-1</p></div> <div class=“col-1”><p>col-1</p></div> </div> <div class=“row”> <div class=“col-2”><p>col-2</p></div> <div class=“col-2”><p>col-2</p></div> <div class=“col-2”><p>col-2</p></div> </div> <div class=“row”> <div class=“col-3”><p>col-3</p></div> <div class=“col-3”><p>col-3</p></div> </div></div>使我们的网格系统响应调整我们的网格以实现移动布局非常简单。我们所要做的就是调整列的宽度。为了简单起见,我将为 800px 以下的屏幕加倍列宽。唯一需要注意的是一些例外,例如:大于 col-3 的列在视口小于 800px 时铺满。@media all and (max-width:800px){ .col-1{ width: 33.33%; } .col-2{ width: 50%; } .col-3{ width: 83.33%; } .col-4{ width: 100%; } .col-5{ width: 100%; } .col-6{ width: 100%; } .row .col-2:last-of-type{ width: 100%; } .row .col-5 ~ .col-1{ width: 100%; }}对于小于 650px 的屏幕。@media all and (max-width:650px){ .col-1{ width: 50%; } .col-2{ width: 100%; } .col-3{ width: 100%; } .col-4{ width: 100%; } .col-5{ width: 100%; } .col-6{ width: 100%; }}我们现在创建了自己的响应式网格系统,而不使用框架。<div class=“grid-container outline”> <div class=“row”> <div class=“col-1”><p>col-1</p></div> <div class=“col-1”><p>col-1</p></div> <div class=“col-1”><p>col-1</p></div> <div class=“col-1”><p>col-1</p></div> <div class=“col-1”><p>col-1</p></div> <div class=“col-1”><p>col-1</p></div> </div> <div class=“row”> <div class=“col-2”><p>col-2</p></div> <div class=“col-2”><p>col-2</p></div> <div class=“col-2”><p>col-2</p></div> </div> <div class=“row”> <div class=“col-3”><p>col-3</p></div> <div class=“col-3”><p>col-3</p></div> </div> <div class=“row”> <div class=“col-4”><p>col-4</p></div> <div class=“col-2”><p>col-2</p></div> </div> <div class=“row”> <div class=“col-5”><p>col-5</p></div> <div class=“col-1”><p>col-1</p></div> </div> <div class=“row”> <div class=“col-6”><p>col-6</p></div> </div></div>注意:本指南只是创建自己响应式网格系统的起点。它不是一个框架,甚至不是一个完整的解决方案,我希望它能够揭开 CSS 网格的神秘面纱。参考【1】Creating Your Own CSS Grid System | Jan ...

January 27, 2019 · 2 min · jiezi