Java 直接插入 CLOB/BLOB 数据到 Oracle 数据库

向数据库中插入 CLOB 或 BLOB 类型的数据,Oracle 总是比其他类型的数据库操作上要麻烦多了。当然,对于不大于 4K 长度的 CLOB 字符串在 JDBC 中可简单的用 PreparedStatement.setString(idx, "short string") 。如果要插入大于 4K 长度的内容,网上找来的例子许多都是分两步走

  1. 先插入 EMPTY_CLOB() 或 EMPTY_BLOB()
  2. 然后 SELECT 原来的记录 FOR UPDATE, 再更新先前插入的记录

这就存在两个问题,含 CLOB/BLOB 的表必需要有主键,还有因为 FOR UPDATE 的使用我们需要开启事物,不能采用自动提交。

其实还有更简单的方法可直接插入大的 CLOB/BLOB 数据,要用到 Oracle JDBC 驱动的 setStringForClob(),  CLOB.createTemporary(), 或 BLOB.createTemporary() 方法。来看下面的例子,例子中只演示 CLOB, 类似的方法可应用于 BLOB, NCLOB。

本文中所使用的 Oracle JDBC 驱动比较老,是 ojdbc:ojdbc:5。Docker 启动一个本地的 Oracle 11G 作为测试数据库

$ docker run -d -p 1521:1521 -p 8080:8080 wnameless/oracle-xe-11g-r2

默认的 SID 是 xe, 数据库用户名和密码分别是 system/oracle 阅读全文 >>

FastAPI - 一款新型的 Python Web 框架(对比 Flask)

近日曾想尽办法为 Flask 实现 Swagger UI 文档功能,找到的实现方式基本上是 Flask + Flasgger, 记录在 Flask 应用集成 Swagger UI。然而不断的 Google 过程中偶然发现了一款集成了 Swagger UI 的比 Flask 还好的 Python Web 框架 -- FastAPI 。起初想要在标题中表达的意思大概是 Flask + Swagger = FastAPI, 后来发现 FastAPI 的闪亮点不仅如此,于是乎又找了些 Flask 与 FastAPI 对比的文章读一读,在文后附有链接。

本文不对 Flask 与 FastAPI 的各个方面对进行对比,本人兴趣依然还是在 FastAPI 的 Swagger UI 功能,以及与 Flask 的 Blueprint 类似的特性。如果要拿 Flask 与 FastAPI 比较的话,应该用 Flask 2.x, 因为它开始支持类似 @app.get 的装饰器,并引入了 async 路由函数。

Flask 是在 2010 年发布的,它构建于 WSGI(Python Web Server Gateway Interface) 之上的,产品环境中运行需与 uWSGI, Gunicorn 搭配,或用 mod_wsgi 模块与 Apache 集成。因发布较早,所以目前应该有较多的使用者。Flask 2.0 需要 Python 3.6+ 的支持,如果支持 async, 需 Python 3.7+

FastAPI 发布于 2018 年,构建于 ASGI(Asynchronous Server Gateway Interface) 之上,在 IO 密集型的应用中有更优越的性能。生成环境中配合 ASGI 服务器,如 UvicornHypercorn. FastAPI 最为亮丽的特性是集成了 Swagger UI -- 外加一个福利 ReDoc。FastAPI 需 Python 3.6+ 版本。 阅读全文 >>

Python async, await 的理解与使用

关于 Python 中 async, await 关键字的一些知识在去年的一篇 探索 Flask 对 asyncio 的支持 有讲到,一直没在实际上用过它们,所以基本上也就忘干净了。随着 Flask 2 加入了 async 的特性,以及 FastAPI 从一开始支持 async, 又觉得有必要重新温习一下 Python 中如何使用 async, await 关键字了。

注:由于 Flask 支持了 async, 号称 async 化 Flask 的  Quart 项目开始变得无足轻重了。

本文主要的学习材料是在 YouTube 上的一个视频 Fear and Awaiting in Async (Screencast), 其中用 Python REPL 以 Live 的形式展示,对 async, await 关键字循序渐进的讲解。

如今不少语言都支持 async, await 关键字,如 C#, JavaScript, Kotlin, Rust 等,还有今天的主角 Python。而 Java 仍然很重视函数返回值的意义,未支持 async, 只能显式的返回 Future/CompletableFuture, 而且自己控制如何在线程池中执行。 阅读全文 >>

Flask 应用集成 Swagger UI

成熟的 Web  API 框架总有一款 API 文档与之伴随,当前最知名的莫过于支持 Open API 的 Swagger 了。Python 的 Flask 框架支持 Swagger UI 也有几条路子

  1. Flasgger : 好像是 flask-swagger 的 fork
  2. flask-swagger: 许久未更新了,不用考虑
  3. flask-restful-swagger: 到目前也两年未更新了
  4. Flask-RESTPlus 的 Swagger 特性: 真需要用到 Flask-RESTPlus 就可以用它

单纯用 Flask 构建 API 的话,细数起来也就 Flasgger 比较合适,如果甩开 Flask 而用 FastAPI 的话,就不用操心 Swagger 了,因为 FastAPI 原生的支持 Swagger。

本文中我们将体验如何使用 Flasgger, 关于使用方法,在它源码的 README.md 已经描述的很清楚了。Flasgger 提供了以下几种主要的使用方式 阅读全文 >>

逐步理解 Flask 的 Blueprint(蓝本)

Python 的 Flask 框架能让我们快速的建立一个轻量级的 Web 或 REST API。对于小应用由一个 @app 装饰一撸到底就行,当项目稍具规模或要更清晰就要考虑模块化,于是来到了我们今天的话题,首先是

为什么需要 Blueprint?

比如说我们一定超级简单的 Flask 应用 main.py 的代码如下:

阅读全文 >>

Terraform 的变量使用及赋值规则

本人在 AWS 上建立基础架构的时候倾向于用 Terraform, 而不是 AWS 自家的 CloudFormation。倒不是因为 Terraform 支持多种类型的 Provider,而是它能模块化,不同项目共享 AWS 资源时也更方便。而使用 CloudFormation 的话,一不小心就会写出一个超大的 YAML 文件来,要使用共同的 AWS 资源时,谁来创建是个不小的问题。CloudFormation 稍值得称道的地方也就是有一个可视化的  Stack,但把  Terraform 执行的 state 存到 S3 也不差。使用 Terraform 还有一个最享受的地方就是它的官方文档组织的非常清晰。

出品 Terraform 的公司 HashiCorp 秉持着 Infrastructure as Code,近日在忙着 IPO, 估值在 $13B, Ticker 将为 HCP(该链接直接可用时便以上市),介时也值得关注一下。扯远了,回到日常使用 Terraform 的变量上来。

本文直接参考自 Terraform 官网的 Input Variables。不管英文好不好都应该读原文去理解 Terraform 变量的详细使用方法。这里主要是了解各种输入变量的方式,以及验证一下当同时用多种方式输入重复的变量时,以谁为最终的结果。 阅读全文 >>

SpringBoot2 应用 Axis 1.4 开发 WebService

有了前一篇 应用 Axis 1.4 开发 WebService 的对 Axis 1 较为深刻的理解后,现在正式给古老的 Axis 1.4  拉个伴,那就是 SpringBoot2。SpringBoot2 + Axis 1 的主要工作就是把 Axis 的 web.xml 用 SpringBoot2 的方式进行转述。

在 SpringBoot 中用 Axis 1 后,有两个特性不再支持

  1. 不再支持 jws 即时发布 Web Service,不能直接搬用 url-pattern *.jws,没继续深究,实际中希望这么部署的方式用得较少
  2. 不再支持 SOAPMonitorService,它是一个 Java Applet,  Java Applet 在新版的 JDK 中已被移除,早就不推荐使用了

在 SpringBoot 中配置 Servlet 或 ServletListener 有两种方式

  1. ServletRegistrationBean/ServletListenerRegistrationBean
  2. @WebServlet/@WebListener

spring-boot-starter 引入了 log4j-to-slf4j, jul-to-slf4j, 所以不需要配置 log4j.properties, 需要的话可用 logback.xml 配置日志输出。 阅读全文 >>

应用 Axis 1.4 开发 WebService

Axis 1 的最后一个版本还是 2006-04-22 发布的 1.4 Final 版,当前的版本是  Axis 2, 即于  2021-08-01 发布的  Axis v1.8.0 版本。想想在  2006 年 4 月份,软件开发是一种什么样的景象,JDK 5 于 2004-09-30 发布,同年 12 月 12 日 JDK 6 才出来, Spring 还是 1.x 的版本。那时候仍是 EJB 兴旺的年代,微服务概念的出现还有等好多年。

那为什么还要学习 Axis 1.4 呢?目的就是为了放弃,先前的 Axis 1.4 的项目不稍加理解,怎么能顺利的过度到 Axis 2 呢?要说眼下更好的用来开发 SOAP WebService 的库应该首选 Apache CXF。本来拟定的文章标题的 Springboot2 应用 Axis 1.4 开发 WebService, 但一发挥就用力过猛,只得下回另立新篇来再加上 Springboot2 了,因此本篇就是为 SpringBoot2 与 Axis 1 的结合铺路的。

什么是 SOAP,Simple Object Access Protocol, 简单对象访问协议,一种 XML-RPC 的实现。谁都敢号称简单,与当今的 REST API 一对照,任何人都会觉得 SOAP 是把一个远程调用搞得无比的复杂。SOAP 有 1.1 和 1.2 两个版本,现在提 SOAP 基本就是 SOAP 1.2 的代名词。另外,SOAP 1.2 开始也承认不简单,不再明确为 Simple Object Access Protocol 的缩写,而叫做 Messaging Framework (Second Edition)。 阅读全文 >>

mvn 命令上传文件到 Maven 仓库

针对一个 Maven 的 Java 项目,我们执行 mvn deploy 命令时想要把生成的 jar 包上传到 Maven 仓库(本文将使用私有的 Nexus 仓库)中去。所要用到的插件 Maven Deploy Plugin,本文实际就是讲述如何用该插件上传 jar 包到 Maven  仓库,更多用法请参考该插件的官方文档。

本文关键性的两个配置文件是 pom.xml 和 settings.xml。前者配置仓库的地址,后者中配置用户名和密码。要确定 Maven 使用了哪个 settings.xml 文件,用 mvn -X 查看,比如下面的输出

[DEBUG] Reading global settings from /usr/local/Cellar/maven/3.8.3/libexec/conf/settings.xml
[DEBUG] Reading user settings from /Users/yanbin/.m2/settings.xml

Maven 还允许在执行 mvn 命令时用  -s 或 --settings 参数指定 settings.xml 文件,如 mvn deploy --settings settings.xml

所以对于 settings.xml 文件的修改,可修改全局的,用户的或参数 --settings 指定的。 阅读全文 >>

AWS Assume IAM role 的使用

AWS 要授权给他人访问指定资源有哪几种方式呢?

  1. 创建一个 AWS 帐号让别人用,那是 AWS 干的事
  2. 在自己帐号下创建一个用户,把 Access Key ID 和 Secret Access Key 告诉别人。可为该用户限定权限,但任何获得那两个 Key 的人都能使用该用户。
  3. 创建一个 IAM Role, 并指定谁(帐号或 Role) 能以该 Role 的身份来访问。被 Assume 的 Role 可限定权限和会话有效期。

用 Assume Role 的方式具有更高的安全可控性,还不用维护 Access Key ID 和 Secret Access Key。比如在构建和部署时通常是有一个特定的 Account, 然后 Assume 到别的 IAM Role 去操作资源。

本文将详细介绍在帐号 A 创建一个 IAM Role(标注为 R) 并分配一些权限,然后允许另一个帐号 B 以 IAM Role - R 的身份来访问帐号 A 下的资源。IAM Role 将用 awscli 来创建,Assume Role 的过程用 awscli 和 boto3 Python 代码两种方式来演示。 阅读全文 >>