ballerina 学习二十九 数据库操作
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.0
ports:
- "9090:9090"
mysql:
build: ./
ports:
- 3306:3306
command: --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: EMPLOYEE_RECORDS
MYSQL_USER: gogs
MYSQL_PASSWORD: dalongrong
TZ: Asia/Shanghai
inid.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: 数据库操作代码,集成了docker
import 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 message
http:Response response;
Employee employeeData;
// Extract the data from the request payload
var payloadJson = check request.getJsonPayload();
employeeData = check <Employee>payloadJson;
// Check for errors with JSON payload using
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 insertData function to save data in the Mymysql database
json ret = insertData(employeeData.name, employeeData.age, employeeData.ssn,
employeeData.employeeId);
// Send the response back to the client with the employee data
response.setJsonPayload(ret);
_ = httpConnection->respond(response);
}
@http:ResourceConfig {
methods: ["GET"],
path: "/employee/{employeeId}"
}
retrieveEmployeeResource(endpoint httpConnection, http:Request request, string
employeeId) {
// Initialize an empty http response message
http:Response response;
// Convert the employeeId string to integer
int empID = check <int>employeeId;
// Invoke retrieveById function to retrieve data from Mymysql database
var employeeData = retrieveById(empID);
// Send the response back to the client with the employee data
response.setJsonPayload(untaint employeeData);
_ = httpConnection->respond(response);
}
@http:ResourceConfig {
methods: ["PUT"],
path: "/employee/"
}
updateEmployeeResource(endpoint httpConnection, http:Request request) {
// Initialize an empty http response message
http:Response response;
Employee employeeData;
// Extract the data from the request payload
var 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 database
json ret = updateData(employeeData.name, employeeData.age, employeeData.ssn,
employeeData.employeeId);
// Send the response back to the client with the employee data
response.setJsonPayload(ret);
_ = httpConnection->respond(response);
}
@http:ResourceConfig {
methods: ["DELETE"],
path: "/employee/{employeeId}"
}
deleteEmployeeResource(endpoint httpConnection, http:Request request, string
employeeId) {
// Initialize an empty http response message
http:Response response;
// Convert the employeeId string to integer
var empID = check <int>employeeId;
var deleteStatus = deleteData(empID);
// Send the response back to the client with the employee data
response.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 action
var ret = employeeDB->update(sqlString, name, age, ssn, employeeId);
// Use match operator to check the validity of the result from database
match 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 client
var ret = employeeDB->select(sqlString, (), employeeID);
match ret {
table dataTable => {
// Convert the sql data table into JSON using type conversion
jsonReturnValue = 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 client
var 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 client
var 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 学习二十九 数据库操作的更多相关文章
- Java从零开始学二十九(大数操作(BigIntger、BigDecimal)
一.BigInteger 如果在操作的时候一个整型数据已经超过了整数的最大类型长度long的话,则此数据就无法装入,所以,此时要使用BigInteger类进行操作. 不可变的任意精度的整数.所有操作中 ...
- ballerina 学习二十五 项目docker 部署&& 运行
ballerina 官方提供了docker 的runtime,还是比较方便的 基本项目创建 使用cli创建项目 按照提示操作就行 ballerina init -i 项目结构 添加了dockerfil ...
- 前端学习(二十九)nodejs(笔记)
后台语言 java php .Net python Node.js------------------------------------------------- ...
- ballerina 学习二十八 快速grpc 服务开发
ballerina 的grpc 开发模型,对于开发者来说简单了好多,不是schema first 的方式,而是我们 只要编写简单的ballerina service 就可以了,proto 文件是自动帮 ...
- ballerina 学习二十六 项目docker 部署&& 运行(二)
ballerina 从发布,到现在官方文档的更新也是很给力的,同时也有好多改进,越来越好用了 可以参考官方文档 https://ballerina.io/learn/by-guide/restful- ...
- ballerina 学习二十四 监控ballerina
ballerina 服务的监控还是比较方便的,以及集成了Prometheus Grafana Jaeger Elastic Stack 监控服务监控的集成 主要包含以下几个步骤 a. 安装docker ...
- ballerina 学习二十二 弹性服务
主要包含断路器模式,负载均衡模式,故障转移,重试 Circuit Breaker 参考代码 import ballerina/http; import ballerina/log; import ba ...
- ballerina 学习二十 http/https
提供http && https server && client 访问功能 client endpoint 说白了就是http client 参考代码 import b ...
- python学习笔记(十)完善数据库操作
1.cur = coon.cursor(cursor=pymysql.cursors.DictCursor)的用法 建立游标,指定cursor类型返回的是字典,如果不指定类型,返回的是元组类型数据 i ...
随机推荐
- inputsimulator - Windows Input Simulator
窗体输入模拟器提供一个基于 win32 SendInput 方法的 模拟键盘鼠标输入的.net 接口.windows 输入模拟器可用于 WPF.windows 窗体和控制台应用程序, 实现模拟任意按 ...
- Confluence 6 LDAP 用户组结构设置
用户组对象类(Group Object Class) 这是在 LDAP 用户组对象中使用的类的名字.例如: groupOfUniqueNames group 用户组对象过滤器(Group Object ...
- amoba读写分离
原文链接:http://www.abcdocker.com/abcdocker/81 Amoeba(变形虫)项目,该开源框架于2008年 开始发布一款 Amoeba for Mysql软件.这个软件致 ...
- CoderForce 140C-New Year Snowmen(贪心)
题目大意:有n个已知半径的雪球.堆一个雪人需要三个尺寸不同的雪球,问用这些雪球最多能堆多少个雪人? 题目分析:先统计一下每种尺寸的球的个数,从三种最多的种类中各取出一个堆成雪人,这样贪心能保证的到的数 ...
- Leetcode 22
//这题感觉不如前两题回溯清楚,还要再看看class Solution { public: vector<string> generateParenthesis(int n) { vect ...
- dp入门:最长不下降序列
#include "bits/stdc++.h" using namespace std; ],dp[]; int main() { int n; cin >> n; ...
- LOV抛出值无效的异常
在选择LOV中的行返回之后,点击提交的时候始终报值无效的异常. 症状:LOV中有值为 XXX项目,XXX项目(一期) 的时候,当你选择XXX项目 再进行提交,老是报出值无效的异常. 解决方式:在页 ...
- learning uboot how to enable watchdog in qca4531 cpu
find cpu datasheet , watchdog relate registers: 0x18060008 watchdong timer control 0x1806000c watchd ...
- IE11浏览器,按F12 检查元素,工具会出来,但是没法正常使用?
微软网站上找到IE11的累计安全更新,安装后就能正常使用了.https://www.microsoft.com/zh-cn/download/confirmation.aspx?id=45154
- (C/C++学习笔记) 十六. 预处理
十六. 预处理 ● 关键字typeof 作用: 为一个已有的数据类型起一个或多个别名(alias), 从而增加了代码的可读性. typedef known_type_name new_type_nam ...