介绍如何用 Fabric Java SDK
进行简单的数据块插入和查询
环境
- Hyperledger Fabric
2.0
- Fabric Java SDK
2.0.0
示例
1 | public class LocalUser implements User { |
1 | public class FabricTest { |
介绍如何用 Fabric Java SDK
进行简单的数据块插入和查询
2.0
2.0.0
1 | public class LocalUser implements User { |
1 | public class FabricTest { |
js中可以定义生成器函数, 使用yield
迭代结果, 例如
1 | function* gen() { |
本文中尝试在Java环境中实现类似的效果
生成器类
1 | import java.util.concurrent.Semaphore; |
1 | public class Main { |
1 | let generator = (function* Generator() { |
使用vue-cli-service build
对开发的库进行打包时使用--target lib
开发时Vue通常是以devDependencies
方式引入的只在开发中使用, 使用lib
方式打包也一样不会把Vue打包进去
官方文档中描述
在库模式中,Vue 是外置的。这意味着包中不会有 Vue,即便你在代码中导入了 Vue。
打包时通常会提示缺少vue-template-compiler
按以下安装并打包, 打包默认输出路径是./dist
1 | npm install -g @vue/cli-service |
在vue.config.js
中进行打包相关的配置
1 | module.exports = { |
发布到npm
上后, 若需要CDN方式引入, 可以使用unpkg
例如这个项目
https://github.com/GitHub-Laziji/menujs
1 | <script src="https://unpkg.com/vue-contextmenujs/dist/contextmenu.umd.js"> |
dubbo
官方文档中关于集成zookeeper
的说明在2.7.1
版本下缺少了必要的步骤, 做此记录
Dubbo
2.7.1Zookpper
3.5.5Springboot
2.1.1.RELEASE1 | <dependency> |
1 | # 服务端 |
1 | # 客户端 |
在js中需要将异步方法同步的时候, 经常使用的是async
和await
, 或者用Promise
偶然在dvajs中看到其使用yield
迭代器实现了同步的效果, 例如
1 | function* f(){ |
当然直接运行不能得到预期的效果, Promise
没用同步执行, yield
返回的结果也是undefined
, 因为还缺少对其的一层封装, 或者说还缺少个执行器
1 | var it = f(); |
传统的迭代器, 是这样使用的
1 | function* range(){ |
如下封装, 在每一次yield
返回的Promise
的then
中进行下一次迭代, 并把结果传入 g.next(r)
, 迭代函数的next(r)
中的参数r
会成为函数体中yield
标识的表达式的返回值, 从而达到类似await
的效果
1 | function async(g) { |
当本地搭建gitlab
服务器的时候经常使用的是直接ip访问, 没有域名, 所以无法访问到类似*.gitlab.io
的Pages
这里提供一个取巧的解决办法, 因为gitlab
仓库下的文件都可以通过/raw
访问原始文本文件, 响应返回类型是文本
所以只需要通过Nginx
把后缀为html
的文件返回类型改为text/html
, 图片类型的改为image/png
即可直接访问到网页了
gitlab
方面无需配置, Nginx
加入如下配置
1 | server { |
配置之后例如用户LLL
有个仓库blog
的主分支master
上存放着类似hexo
搭建的博客文件,
只需要访问http://127.0.0.1:8080/LLL/blog/raw/master/index.html
即可进入博客了
python
版本3.6
, 在windows以及linux上都进行过测试
由于python
中rsa
加密存在长度限制, 虽然可以通过分片加密来解决,
但是更好的做法是通过rsa
加密传输aes密钥
给服务器, 携带的信息通过该密钥进行aes
加密,
服务器通过rsa私钥
得到aes密钥
后解析信息, 并继续使用密钥进行双向通信
python中加密使用pycryptodome
模块
1 | pip install pycryptodome |
其中接受的参数text,key均为字符串
1 | from Crypto.PublicKey import RSA |
java的加密代码不依赖其他包
1 | import javax.crypto.Cipher; |
1 | import javax.crypto.Cipher; |
在JS中对于普通的json, 可用如下方式进行简单的深度拷贝
1 | let json = { a: "aa" }; |
不过当json中包含一些JS中的对象及函数的时候, 用这样的方法会使数据丢失, 并且这个无法解决循环引用的问题, 所谓循环引用指的是
1 | let b={}; |
这时JSON.stringify(a)
就出现了异常
由于存在这些问题, 所以就编写了一个拷贝函数, 来做这件事情, 代码实现如下
1 | function copyObject(o) { |
代码中通过let objectMap = new WeakMap();
保存拷贝过的对象, 解决循环引用的问题
通过递归拷贝其中的对象, 若是基本类型、正则对象或函数则直接返回
1 | class ObjA { |
经过测试, 以上场景的输出均与预计相同
MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生类型、接口和 Java 的 POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。
传统Mybatis
开发使用XML的方式编写SQL脚本进行数据库操作,Mybatis
允许使用动态SQL
但是即使如此, 依然存在许多重复性工作, 因为每个基本表的增删改查语句模式其实都是相同的
Mybatis
也可以使用Dao接口上以注解的形式编写SQL, 但是也是一样, 必须重复编写, 非常不方便
其实Mybatis
已经考虑到了这点, 为我们提供了自定义通用Mapper的实现机制
https://github.com/GitHub-Laziji/commons-mybatis
实现方法分为两步
在Dao接口的方法上以注解的形式声明, 使用哪个类的哪个方法, 如下
1 | public interface DODao<T extends DO> extends Dao<T> { |
在实现方法中可以接收Dao接口中传来的参数, 最后返回一个SQL字符串, 这个SQL可以是动态的, 例如可以使用id=#{id}
这样的语法
T selectById(Long id)
实现如下
1 | public String selectById(ProviderContext context) { |
我们可以通过context
获取Dao的泛型类, 也就是实体类
1 | private Class getEntityClass(ProviderContext context) { |
通过反射我们可以拿到对应的字段名, 类名, 字段名获取如下, Ignore
是自定义注解, 用于忽略一些字段
1 | private String[] getVariables(Class clazz, String[] prefixes) { |
使用通用Mapper
无需编写任何SQL 只需创建空Dao 继承通用的Dao<T>
即可
具体实现请看项目commons-mybatis
具体使用请看README
还可以更近一步使用代码生成器生成Bean, Dao, Service, 把工作简化到极致Java代码生成器mybatis-generator的使用
RPC是一种远程过程调用, 它是一种通过网络从远程计算机程序上请求服务, 而不需要了解底层网络技术的协议
RPC可以把远程服务像本地服务一样调用, 以Java
中为例, 客户端与服务端一般共用一个核心包, 核心包中包含了需要调用服务的接口
在服务端实现这些接口, 客户端通过Socket
等方式连接服务端, 发生调用的信息(方法名, 参数等)
服务端接收后执行相应动作, 最后通过网络返回计算结果, 一次RPC调用就完成了
下面是Java
中的简单实现
1 | public interface TestService { |
一个简单的打印服务, 不包含实现
在客户端代码中自始至终没有编写服务的实现, 只有一个接口, 但是又可以得到服务的实例,
要做到这点需要用到Java
中的动态代理Proxy.newProxyInstance
1 | import java.io.ObjectInputStream; |
通过对象流把参数等信息发送给服务端
一般服务端是预先实例化服务, 以完整类名为Key
把服务存进集合供调用, 或者依赖现成的Springboot
等框架管理服务, 下面是服务端的实现
1 | import java.io.IOException; |
服务端编写服务实例代码
1 | public class TestServiceImpl implements TestService{ |
至此可以看到客户端调用的
1 | System.out.println(service.print("abc")); |
打印出了
1 | **abc** |
就好像调用了本地服务一样