golang – GORM

本文章簡單介紹Gorm 的操作:

安裝需要的包:

go get -u gorm.io/gorm
go get -u gorm.io/driver/mysql

gorm.io/driver/mysql 是針對 github.com/go-sql-driver/mysql 進行封裝,是之適用 gorm.io/gorm 接口。

引用包:

import (
	"gorm.io/driver/mysql"
	"gorm.io/gorm"
)

模型, 是標準的struct,下面包含設置

type UserInfo struct {
	ID       int
	User     string `gorm:"column:user"`
	Password string `gorm:"column:password"`
}

func (UserInfo) TableName() string {
	return "user"
}

以下是列的一些約定:

type Foo struct {
  ID        uint      // 列名是 `id`
  Name      string    // 列名是 `name`
  Birthday  time.Time // 列名是 `birthday`
  CreatedAt time.Time // 列名是 `created_at`
}

默認情況下 ID 是主鍵,可以通過 gorm:"primaryKey" 指定其他的,例如:

UUID   string `gorm:"primaryKey"`

連結Mysql 以及查詢

  db, _ := gorm.Open(mysql.Open("root:xxxx@tcp(127.0.0.1:3306)/test_db?charset=utf8"))

	var user UserInfo
	//db.Where("id = ?", 1).First(&user)

	db.First(&user, "id = ?", 2)
	fmt.Println(user)

	var users []UserInfo
	db.Where("id > ?", 0).Find(&users)
	fmt.Println(users)

更新&刪除

user.User = "xxx"
db.Save(&user)

db.Delete(&user)

Gorm是功能很全面的ORM,全功能ORM也會損耗一些效率。

參考:https://gorm.io/zh_CN/docs/

golang – sqlx

這篇文章介紹 sqlx 。在項目中我們通常可能會使用database/sql連接MySQL資料庫。sqlx可以認為是Go語言內置database/sql的超集。增加了 scan 內容到 struct,並增加了一些 Get(),Select() 等函數。

安裝:

go get -u github.com/jmoiron/sqlx

同樣需要安裝 github.com/go-sql-driver/mysql,並加載:

import (
	_ "github.com/go-sql-driver/mysql"
	"github.com/jmoiron/sqlx"
)

連結資料庫:

db, _ := sqlx.Open("mysql", "root:xxx@tcp(127.0.0.1:3306)/test_db?charset=utf8")

查詢:

type User struct {
	Id       int    `db:"id"` // 必須大寫Id, 格式必須是 `db:"id"` 要有 : 要有 ""
	User     string `db:"user"`
	Password string `db:"password"`
}

func main() {
  ...

  var u2 User
	db.Get(&u2, "select * from user where id = ?", 1)
	fmt.Println(u2)
	u3 := []User{}
	db.Select(&u3, "select * from user limit 2")
	fmt.Println(u3)

  ...
}

插入&更新&刪除:

sqlStr := "insert into user(name, password) values (?,?)"
ret, err := db.Exec(sqlStr, "沙河小王子","xxxxxx")

sqlStr := "update user set name=? where id = ?"
ret, err := db.Exec(sqlStr, 39, "xxxxx")

sqlStr := "delete from user where id = ?"
ret, err := db.Exec(sqlStr, 6)

參考: http://jmoiron.github.io/sqlx/

golang 操作 mysql

本篇文章介紹:database/sql。 它是golang 內建的,只提供一個sql操作的統一接口。不過要連結mysql需要安裝 mysql 的實現。

安裝需要的包:

go get -u github.com/go-sql-driver/mysql

程序中必須加載2個包:

import (
	"database/sql"
	_ "github.com/go-sql-driver/mysql"
)

database/sql 包 是golang官方提供的一個接口。 github.com/go-sql-driver/mysql 包 mysql 的對接口的實現。

_ "github.com/go-sql-driver/mysql" 表示只加载 “github.com/go-sql-driver/mysql” 包的 init。然后统一有 标准的 database/sql调用。

連結Mysql:

db, err := sql.Open("mysql", "root:xxx@/test_db?charset=utf8mb4")
if err != nil {
    panic(err)
}

defer db.Close()

defer db.Close() 当程序结束时,执行关闭mysql连接。

查詢&處理數據:

rows, err := db.Query("SELECT id, area FROM zip limit 3")
defer rows.Close()

for rows.Next() {
    var id int
    var area string

    if err := rows.Scan(&id, &area); err != nil {
        panic(err)
    }

    fmt.Printf("%d \t %s\n", id, area)
}

必须通过 rows.Scan() 读取到对应变量

tar.xz 文檔解壓、創建

今天看到了 php-8.2.9.tar.xz 文檔。 先了解一下 xz, 用 man xz 命令看一下。

xz is a general-purpose data compression tool with command line syntax 
similar to gzip(1) and bzip2(1)

一種壓縮格式,和 gzip bizp2 類似。

# 壓縮
xz filename
# 解壓縮
xz -d filename.xz or unxz filename.xz

在 man tar 命令的解釋中 有:

-J, --xz
    filter the archive through xz

所以解壓縮命令:

tar -xJf php-8.2.9.tar.xz 

Javascript IIFE自调用表达式

在 JavaScript 中,您可以使用自調用表達式(也稱為自執行函數)來創建一個立即執行的函數。這種函數會在定義後立即執行,並且通常用於創建一個作用域,以防止外部代碼訪問內部變量。

書寫格式:

(function () {
  // …
})();

(() => {
  // …
})();

(async () => {
  // …
})();

以下是一個立即執行函數的示例:

(function() {
  var secretVariable = "This is a secret";
  console.log(secretVariable);
})();

在上面的代碼中,我們定義了一個自調用函數,它創建了一個名為 secretVariable 的變量,並將其輸出到控制台。由於該函數是立即執行的,因此 secretVariable 的值不會暴露給外部代碼。

您還可以將參數傳遞給立即執行函數。以下是一個帶有參數的示例:

(function(value) {
  console.log(value);
})("Hello, World!");

在上面的代碼中,我們將字符串 “Hello, World!” 作為參數傳遞給自調用函數,並在函數內部將其輸出到控制台。

JavaScript async和defer作用

在JavaScript中,async和defer是兩個屬性,它們用於控制腳本的加載和執行方式。

在浏览器加载 script 时, 如果没有 async和defer。 则表示立刻执行。

async屬性是用於標記一個腳本是否異步加載和執行。當腳本的async屬性為true時,瀏覽器會在需要時異步加載該腳本,並且在加載完成後立即執行。這意味著腳本的執行不會阻塞頁面的解析和渲染。
以下是一個使用async屬性的示例:

<script async src="script.js"></script>

在這個例子中,script.js會異步加載並在加載完成後執行。 另一方面,defer屬性是用於控制腳本的執行時間。當腳本的defer屬性為true時,瀏覽器會延遲執行該腳本,直到文檔解析完成後才會執行。這意味著腳本的執行不會阻塞頁面的解析和渲染。
以下是一個使用defer屬性的示例:

<script defer src="script.js"></script>

在這個例子中,script.js會延遲執行,直到文檔解析完成後才會執行。

總之,async和defer屬性都是用於控制腳本加載和執行的方式,它們可以幫助優化頁面的性能和用戶體驗。

python send_message() & sendmail()

在Python中,您可以使用SMTP(簡單郵件傳輸協議)來發送電子郵件。有兩個主要的方法可以使用:SMTP.send_message()和SMTP.sendmail()。

send_message() 是一種快捷方法,用于带着消息调用 sendmail(),消息由 email.message.Message 对象表示。参数的含义与 sendmail() 中的相同,除了 msg,它是一个 Message 对象。

import smtplib
from email.message import EmailMessage

# 创建邮件对象
msg = EmailMessage()
msg['Subject'] = 'Test Email'
msg['From'] = 'sender@example.com'
msg['To'] = 'recipient@example.com'
msg.set_content('Hello word.')

# 创建SMTP对象
server = smtplib.SMTP('smtp.example.com', 587)
server.starttls()

# 登录SMTP服务器
server.login('sender@example.com', 'password')

# 打印出和SMTP服务器交互的所有信息。
smtp.set_debuglevel(1)               

# 发送电子邮件
server.send_message(msg)

# 关闭SMTP连接
server.quit()

初學者推薦使用send_message()

Gin、 Iris 簡單比較

Golang Gin和Iris 都是很優秀的Web框架。 優缺點比較如下:

  • 性能方面 。Gin在處理高併發請求時,性能更優越。
  • 易用性方面 。Gin比Iris更簡潔、更易於使用。
  • 功能方面 。Iris支援更多的應用場景,例如Web服務、RESTful API、Websocket、RPC等。
  • 可擴展性方面 。Iris具有可擴展性和高性能,適合處理大型企業級應用和高負載的Web應用。

選擇適合的工具取決於具體需求,不同的需求場景,存在不同的選擇。對於簡單的RESTful API或輕量級Web應用,可以選擇Gin;對於大型企業級應用和高負載的Web應用,可以選擇Iris。

官方提供的文檔方面:

Gin文檔 有多種語言,中文、日文、英文等,但功能全部已案例的方式說明。

Iris文檔 目前只有英文(對英文不好的同學、不友好)。功能說明很詳細。

PHP SPL 擴展

Standard PHP Library (SPL) 標準PHP類庫;內容主要包括數據結構類、叠代器、異常類、SPL函數,還提供了一系列的接口。

不需要安裝,它們是 PHP 核心的一部分。

以下是一些常用的SPL數據結構:

  • SplQueue:基於隊列的數據結構,支持先進先出(FIFO)的元素操作。
  • SplStack:基於棧的數據結構,支持後進先出(LIFO)的元素操作。
  • SplHeap:基於堆的數據結構,支持非比較排序和插入、刪除等操作。
  • SplObjectStorage:用於存儲和跟蹤PHP對象引用的數據結構。
  • SplFixedArray:基於哈希表實現的小型數組,具有常數時間的訪問和
  • SplPriorityQueue:基於堆的數據結構,支持帶優先級元素的插入、刪除等操作。

SPL函數裏面有個很重要的東西,spl_autoload_register(),在oop中用來實現自動加載。除了上述數據結構,SPL還提供了其他一些有用的類和方法,例如叠代器、集合等

PHP 7.2 棄用 __autoload(), 可用spl_autoload_register() 

php7.2 及以後的版本, __autoload() 方法已被廢棄, 因為和 spl_autoload_register() 相比功能較差 (因為無法鏈式處理多個 autoloader), 而且也無法在兩種 autoloading 洋式中配合使用。

作為 __autoload() 函數的替代:

<?php

// 棄用
// function __autoload($class) {
//     include 'classes/' . $class . '.class.php';
// }

function my_autoloader($class) {
    include 'classes/' . $class . '.class.php';
}

spl_autoload_register('my_autoloader');

// 或者可以使用匿名函數
spl_autoload_register(function ($class) {
    include 'classes/' . $class . '.class.php';
});