ballerina 数据操作也是比较方便的,官方也我们提供了数据操作的抽象,但是我们还是依赖数据库驱动的。
数据库驱动还是jdbc模式的

项目准备

  • 项目结构
├── mysql_demo
│ ├── Dockerfile
│ ├── docker-compose.yaml
│ ├── inid.sql
│ ├── mysql-connector-java-8.0.13.jar
│ └── mysql_service.bal

  • 代码说明
dockerfile:
mysql 数据库的dockerfile,包含数据的初始化
FROM mysql/mysql-server:5.7
COPY inid.sql /docker-entrypoint-initdb.d
docker-compose.yaml: docker-compose 运行包含ballerina api 以及数据库
version: "3"
services:api:image: dalongrong/mysql_demo:v1.0ports:- "9090:9090"mysql:build: ./ports:- 3306:3306command: --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_cienvironment:MYSQL_ROOT_PASSWORD: rootMYSQL_DATABASE: EMPLOYEE_RECORDSMYSQL_USER: gogsMYSQL_PASSWORD: dalongrongTZ: Asia/Shanghaiinid.sql: 操作依赖的数据库模型
/* * MySQL Script - initializeDataBase.sql.* Create EMPLOYEE_RECORDS database and EMPLOYEES table.*/-- Create EMPLOYEE_RECORDS database
CREATE DATABASE IF NOT EXISTS EMPLOYEE_RECORDS;     -- Switch to EMPLOYEE_RECORDS database
USE EMPLOYEE_RECORDS;-- create EMPLOYEES table in the database
CREATE TABLE IF NOT EXISTS EMPLOYEES (EmployeeID INT, Name VARCHAR(50), Age INT, SSN INT, PRIMARY KEY (EmployeeID))mysql_service.bal: 数据库操作代码,集成了dockerimport ballerina/config;
import ballerina/http;
import ballerina/log;
import ballerina/mysql;
import ballerina/sql;
import ballerinax/docker;type Employee record {string name;int age;int ssn;int employeeId;
};// Create SQL endpoint to MySQL database
endpoint mysql:Client employeeDB {host: "mysql",port: config:getAsInt("DATABASE_PORT", default = 3306),name: config:getAsString("DATABASE_NAME", default = "EMPLOYEE_RECORDS"),username: config:getAsString("DATABASE_USERNAME", default = "gogs"),password: config:getAsString("DATABASE_PASSWORD", default = "dalongrong"),dbOptions: { useSSL: false }
};
@docker:Config {registry: "dalongrong",name: "mysql_demo",tag: "v1.0"
}@docker:CopyFiles {// 注意此处mysql jdbc 驱动地址,为了使用简单,我写的是绝对路径,实际上构建之后会copy 到target 目录,方便镜像构建files: [{ source: "/Users/dalong/mylearning/ballerina-project/learning/guide/mysql_demo/mysql-connector-java-8.0.13.jar",target: "/ballerina/runtime/bre/lib" }]
}@docker:Expose {}
endpoint http:Listener listener {,port: 9090
};// Service for the employee data service
@http:ServiceConfig {basePath: "/records"
}
service<http:Service> EmployeeData bind listener {@http:ResourceConfig {methods: ["POST"],path: "/employee/"}addEmployeeResource(endpoint httpConnection, http:Request request) {// Initialize an empty http response messagehttp:Response response;Employee employeeData;// Extract the data from the request payloadvar payloadJson = check request.getJsonPayload();employeeData = check <Employee>payloadJson;// Check for errors with JSON payload usingif (employeeData.name == "" || employeeData.age == 0 || employeeData.ssn == 0 ||employeeData.employeeId == 0) {response.setTextPayload("Error : json payload should contain{name:<string>, age:<int>, ssn:<123456>,employeeId:<int>} ");response.statusCode = 400;_ = httpConnection->respond(response);done;}// Invoke insertData function to save data in the Mymysql databasejson ret = insertData(employeeData.name, employeeData.age, employeeData.ssn,employeeData.employeeId);// Send the response back to the client with the employee dataresponse.setJsonPayload(ret);_ = httpConnection->respond(response);}@http:ResourceConfig {methods: ["GET"],path: "/employee/{employeeId}"}retrieveEmployeeResource(endpoint httpConnection, http:Request request, stringemployeeId) {// Initialize an empty http response messagehttp:Response response;// Convert the employeeId string to integerint empID = check <int>employeeId;// Invoke retrieveById function to retrieve data from Mymysql databasevar employeeData = retrieveById(empID);// Send the response back to the client with the employee dataresponse.setJsonPayload(untaint employeeData);_ = httpConnection->respond(response);}@http:ResourceConfig {methods: ["PUT"],path: "/employee/"}updateEmployeeResource(endpoint httpConnection, http:Request request) {// Initialize an empty http response messagehttp:Response response;Employee employeeData;// Extract the data from the request payloadvar payloadJson = check request.getJsonPayload();employeeData = check <Employee>payloadJson;if (employeeData.name == "" || employeeData.age == 0 || employeeData.ssn == 0 ||employeeData.employeeId == 0) {response.setTextPayload("Error : json payload should contain{name:<string>, age:<int>, ssn:<123456>,employeeId:<int>} ");response.statusCode = 400;_ = httpConnection->respond(response);done;}// Invoke updateData function to update data in mysql databasejson ret = updateData(employeeData.name, employeeData.age, employeeData.ssn,employeeData.employeeId);// Send the response back to the client with the employee dataresponse.setJsonPayload(ret);_ = httpConnection->respond(response);}@http:ResourceConfig {methods: ["DELETE"],path: "/employee/{employeeId}"}deleteEmployeeResource(endpoint httpConnection, http:Request request, stringemployeeId) {// Initialize an empty http response messagehttp:Response response;// Convert the employeeId string to integervar empID = check <int>employeeId;var deleteStatus = deleteData(empID);// Send the response back to the client with the employee dataresponse.setJsonPayload(deleteStatus);_ = httpConnection->respond(response);}
}public function insertData(string name, int age, int ssn, int employeeId) returns (json){json updateStatus;string sqlString ="INSERT INTO EMPLOYEES (Name, Age, SSN, EmployeeID) VALUES (?,?,?,?)";// Insert data to SQL database by invoking update actionvar ret = employeeDB->update(sqlString, name, age, ssn, employeeId);// Use match operator to check the validity of the result from databasematch ret {int updateRowCount => {updateStatus = { "Status": "Data Inserted Successfully" };}error err => {updateStatus = { "Status": "Data Not Inserted", "Error": err.message };}}return updateStatus;
}public function retrieveById(int employeeID) returns (json) {json jsonReturnValue;string sqlString = "SELECT * FROM EMPLOYEES WHERE EmployeeID = ?";// Retrieve employee data by invoking select action defined in ballerina sql clientvar ret = employeeDB->select(sqlString, (), employeeID);match ret {table dataTable => {// Convert the sql data table into JSON using type conversionjsonReturnValue = check <json>dataTable;}error err => {jsonReturnValue = { "Status": "Data Not Found", "Error": err.message };}}return jsonReturnValue;
}public function updateData(string name, int age, int ssn, int employeeId) returns (json){json updateStatus = {};string sqlString ="UPDATE EMPLOYEES SET Name = ?, Age = ?, SSN = ? WHERE EmployeeID = ?";// Update existing data by invoking update action defined in ballerina sql clientvar ret = employeeDB->update(sqlString, name, age, ssn, employeeId);match ret {int updateRowCount => {if (updateRowCount > 0) {updateStatus = { "Status": "Data Updated Successfully" };}else {updateStatus = { "Status": "Data Not Updated" };}}error err => {updateStatus = { "Status": "Data Not Updated", "Error": err.message };}}return updateStatus;
}public function deleteData(int employeeID) returns (json) {json updateStatus = {};string sqlString = "DELETE FROM EMPLOYEES WHERE EmployeeID = ?";// Delete existing data by invoking update action defined in ballerina sql clientvar ret = employeeDB->update(sqlString, employeeID);match ret {int updateRowCount => {updateStatus = { "Status": "Data Deleted Successfully" };}error err => {updateStatus = { "Status": "Data Not Deleted", "Error": err.message };}}return updateStatus;
}

构建&&运行

  • 构建容器镜像(ballerina mysql 操作)
ballerina build mysql_demo

  • docker-compose 启动(数据库以及服务的启动)
docker-compose up -d

数据操作

  • post 数据
curl -v -X POST -d '{"name":"Alice", "age":20,"ssn":123456789,"employeeId":1}' \
"http://localhost:9090/records/employee" -H "Content-Type:application/json"

  • get 查询数据
curl -v "http://localhost:9090/records/employee/1"

  • 效果

说明

使用起来还是比较简单的,同时集合match的模式匹配操作,开发起来很方便

参考资料

https://ballerina.io/learn/by-guide/data-backed-service/

ballerina 学习二十九 数据库操作相关推荐

  1. Java多线程学习二十九:AtomicInteger(原子类) 和 synchronized 的异同点?

    原子类和 synchronized 关键字都可以用来保证线程安全,在本课时中,我们首先分别用原子类和 synchronized 关键字来解决一个经典的线程安全问题,给出具体的代码对比,然后再分析它们背 ...

  2. Golang学习(二十九)序列化和反序列化

    我们不同编程语言之间的数据是无法直接交互的,我们想要解决这个问题 就需要将不同语言之间传输的数据做一个统一规范,而json是目前最流行的数据格式 一.json是什么 json 是一种数据交换格式,主要 ...

  3. ballerina 学习二十六 项目docker 部署 运行(二)

    ballerina 从发布,到现在官方文档的更新也是很给力的,同时也有好多改进,越来越好用了 可以参考官方文档 https://ballerina.io/learn/by-guide/restful- ...

  4. ballerina 学习二十八 快速grpc 服务开发

    ballerina 的grpc 开发模型,对于开发者来说简单了好多,不是schema first 的方式,而是我们 只要编写简单的ballerina service 就可以了,proto 文件是自动帮 ...

  5. OpenGL学习二十九:模板缓冲区与模板测试

    帧缓冲区有许多缓冲区构成,这些缓冲区大致分为: 颜色缓冲区:用于绘图的缓冲区,它包含了颜色索引或者RGBA颜色数据. 深度缓冲区:存储每个像素的深度值,当启动深度测试时,片段像素深度值和深度缓冲区深度 ...

  6. python学习 (二十九) range函数

    1:list函数可以将其他类型转成list. print(list(range(0, 10))) 2: list函数把元组转成list t = (1, 3, 3, 5) print(list(t)) ...

  7. JavaScript学习(二十九)—JS常用的事件

    JavaScript学习(二十九)-JS常用的事件 一.页面相关事件 onload事件:当页面中所有的标签都加载完成后厨房该事件,格式:window.onload <body><sc ...

  8. 2021年大数据Hadoop(二十九):​​​​​​​关于YARN常用参数设置

    全网最详细的Hadoop文章系列,强烈建议收藏加关注! 后面更新文章都会列出历史文章目录,帮助大家回顾知识重点. 目录 本系列历史文章 前言 关于yarn常用参数设置 设置container分配最小内 ...

  9. OpenCV C++案例实战二十九《遥感图像分割》

    OpenCV C++案例实战二十九<遥感图像分割> 前言 一.准备数据 二.K-Means分类 三.效果显示 四.源码 总结 前言 本案例基于k-means机器学习算法进行遥感图像分割.主 ...

最新文章

  1. vue 中watch函数名_vue中避免使用函数来绑定依赖
  2. Java NIO框架Mina
  3. Mac下的浏览器速度比较,Chrome 得分最高
  4. 推荐算法在招聘商业化场景中的应用实践
  5. mysql获取多张表中的数据_mysql之多表查询
  6. jQuery Mobile中页面page的data-*选项
  7. ios开发 静音键设置_RGB、机械、静音全都要,入手新的居家办公利器
  8. Flash MX 2004 帮助CHM 在线版
  9. 路由器wifi信号测试软件,常用路由器WIFI测速效果比对
  10. Ti c64x 优化基本策略
  11. Problem G: 小勇学分数
  12. 一张纸对折多少次后能达到珠穆朗玛峰的高度
  13. fabric-ca-client 详解动态添加组织
  14. cba篮球暂停次数和时间_篮球比赛一节有几次暂停?
  15. 在线高德地图Demo(新测)
  16. 为多孔介质的当量直径_CFX多孔介质模型介绍
  17. 源码时代UI干货分享|Axure基础教程
  18. 马云的故事:缔造阿里巴巴帝国秘诀
  19. 优秀的量化研究员具备哪些特质?
  20. Plugin xxx was was not found in any of the following sources:

热门文章

  1. 转载:JAVA中获取项目文件路径
  2. wxWidgets3.0.2媒体播放器
  3. pxe+kickstart 实现基于网络的无人值守安装操作系统
  4. 在php.ini中safe_mode开启之后对于PHP系统函数有什么影响呢?
  5. BZOJ 1996 [Hnoi2010]chorus 合唱队
  6. [MySQL 5.1 体验]MySQL 复制
  7. md5加密用户登陆遇到的问题及解决办法
  8. Verilog有符号数运算
  9. WP8.1学习系列(第十二章)——全景控件Panorama开发指南
  10. 【书评】OSPF Anatomy of an Internet Routing Protocol