oxmysql sorguları kılavuzu: MySQL.query.await, single, scalar, insert

FiveM Lua'da oxmysql nasıl kullanılır: MySQL.query.await, single, scalar, insert, update, prepare, güvenli ? parametreleri, MySQL.lua içe aktarımı, döngülerden ve işlemlerden kaçınma.

Sunucu betiğinden veritabanını okuymanız veya yazmanız gerekir, ve çevrimiçi örnekler eski MySQL.Async çağrılarını, geri çağırmaları ve exports.oxmysql'ı farklı stillerde karıştırır. Bu makale mevcut MySQL işlevlerini, hangi sonuç için hangisini kullanacağınızı ve sorguları nasıl güvenli ve ucuz tutacağınızı gösterir.

MySQL nesnesi yükleyin

Genel MySQL'i kullanmak için, kaynağın manifestinde kendi sunucu betiklerinizden önce oxmysql'in Lua sarmalayıcısını içe aktarın:

lua
-- fxmanifest.lua
fx_version 'cerulean'
game 'gta5'

server_scripts {
    '@oxmysql/lib/MySQL.lua',
    'server/main.lua',
}

dependency 'oxmysql'

Bu satır olmadan, MySQL nil olur ve attempt to index a nil value (global 'MySQL') hatası alırsınız. Dosya yalnızca sunucuda çalışır. oxmysql kendisi bağlantı kuramıyorsa, bkz. oxmysql connection errors.

İşlevler ve döndürdükleri

Her işlevin sonucu bekleyen ve döndüren bir .await formu vardır. Bir iş parçacığında veya bir olay işleyicisinde çalışmalıdır, çoğu kodunuz zaten orada çalışır.

İşlev Döndürür Şu durumlarda kullanın
MySQL.query.await Satırlar tablosu (hiç yoksa boş) Birçok satırlı SELECT
MySQL.single.await Bir satır veya nil Bir kayıt için SELECT
MySQL.scalar.await Bir değer veya nil COUNT, SUM, bir sütun
MySQL.insert.await Yeni otomatik artış id'si INSERT
MySQL.update.await Etkilenen satır sayısı UPDATE, DELETE
lua
-- all rows
local rows = MySQL.query.await('SELECT identifier, name FROM users WHERE job = ?', { 'police' })
for _, row in ipairs(rows) do
    print(row.identifier, row.name)
end

-- one row
local user = MySQL.single.await('SELECT * FROM users WHERE identifier = ?', { identifier })
if not user then return end

-- one value
local count = MySQL.scalar.await('SELECT COUNT(*) FROM owned_vehicles WHERE owner = ?', { identifier })

-- insert
local id = MySQL.insert.await('INSERT INTO my_logs (identifier, action) VALUES (?, ?)', { identifier, 'login' })

-- update or delete
local changed = MySQL.update.await('UPDATE users SET job = ? WHERE identifier = ?', { 'unemployed', identifier })

Sonuçları kontrol edin. Hiçbir şey bulamayan bir single veya scalar sorgusu nil verir ve bunu kontrol etmeden kullanmak birçok attempt to index a nil value hatasının kaynağıdır.

? ile parametreler

Değerleri her zaman ? yer tutucuları ve ikinci argüman (aynı sırada bir tablo) aracılığıyla iletin:

lua
-- safe
MySQL.query.await('SELECT * FROM users WHERE name = ?', { name })

-- dangerous: SQL injection
MySQL.query.await('SELECT * FROM users WHERE name = "' .. name .. '"')

Güvenli olmayan sürümle, x" OR 1=1 -- gibi bir ad sorgunuzu yeniden yazar. Yer tutucularla, oxmysql değerleri ayrı olarak gönderir, bu nedenle asla SQL olamazlar. Bu, oyuncudan, bir olay argümanından veya bir komuttan gelen her değer için geçerlidir.

Dikkat: Yer tutucular yalnızca değerler için çalışır, tablo veya sütun adları için değil. Bir sütun adı dışarıdan gelirse, bunu bir sabit liste karşısında kontrol edin, yapıştırmayın.

Geri çağırma stili

Aynı işlevler, beklemek istemiyorsanız bir geri çağırma kabul eder. Bu, bir iş parçacığı dışında kullanışlıdır:

lua
MySQL.query('SELECT * FROM users WHERE job = ?', { 'police' }, function(rows)
    print(#rows)
end)

.await daha iyi okunur ve etkinlik içinde iyidir. Aşağıdaki kodu beklemeden çalışmaya devam etmesini istediğinizde geri çağırma stilini kullanın.

MySQL.prepare

MySQL.prepare, aynı sorguyu tekrar tekrar çalıştırdığınızda veritabanının yeniden kullanabileceği hazırlanmış bir ifadeyi çalıştırır. Aynı ? parametrelerini kullanır:

lua
local row = MySQL.prepare.await('SELECT * FROM users WHERE identifier = ?', { identifier })

Döndürdüğü, sonuca bağlıdır: tek bir satır bir tablo olarak geri gelir ve bir sütun ve bir satırlı bir sorgu bir değer olarak geri gelebilir. Sonuç şekli önemli olan kod için, single ve scalar daha tahmin edilebilir, bu nedenle sık sık çalışan bir sıcak sorgunuz olduğunda prepare'a yönelik olun.

Döngüde sorgu yapmayın

Her sorgu veritabanına gidiş-dönüş yolculuğudur. Öğe başına bir sorgu çalıştıran bir döngü hızlı bir şekilde yavaşlar ve beklerken iş parçacığını engeller:

lua
-- one query per player
for _, id in ipairs(ids) do
    local row = MySQL.single.await('SELECT * FROM users WHERE id = ?', { id })
end

Her şeyi tek bir sorguda getirin, ardından Lua'da sonuç üzerinde döngü yapın:

lua
local rows = MySQL.query.await('SELECT * FROM users WHERE job = ?', { 'police' })

Birçok eklemeler için, birkaç satırı olan bir ifade oluşturun veya bunları bir işlem içinde çalıştırın. Ayrıca her işlem işaretinde veya her çerçevede sorgu yapmaktan kaçının: bir değeri bir kez okuyun ve bir Lua tablosunda tutun. Sorgu yavaşsa, aramanız yapılan sütuna bir dizin ekleyin. Yavaş sorgular server thread hitch warnings olarak görünür.

İşlemler

Birden fazla yazma, paranın bir satırdan alınması ve başka bir satıra verilmesi gibi tümü başarılı olmalı veya tamamı başarısız olmalıysa, bir işlem kullanın:

lua
local ok = MySQL.transaction.await({
    { query = 'UPDATE bank SET balance = balance - ? WHERE identifier = ?', values = { 100, fromId } },
    { query = 'UPDATE bank SET balance = balance + ? WHERE identifier = ?', values = { 100, toId } },
})

if not ok then
    print('transfer failed, nothing was changed')
end

Herhangi bir ifade başarısız olursa, veritabanı hepsini geri alır. Her şey yolunda gittiğinde true döndürür.

Tablolar önce var olmalı

Orada olmayan bir tabloya karşı bir sorgu Table 'x' doesn't exist verir. Betiği yüklediğinizde bir SQL dosyasıyla tabloyu oluşturun veya kaynağın başında MySQL.query.await('CREATE TABLE IF NOT EXISTS …') ile oluşturun. Daha fazla bilgi için bkz. SQL table doesn't exist.

Kontrol listesi

Belirtisi Çözüm
MySQL nil server_scripts'e '@oxmysql/lib/MySQL.lua' ekleyin, dosyalarınızdan önce
Sonuç nil ve betik hata verir single ve scalar hiçbir şey bulunamadığında nil döndürür: kontrol edin
Değerler oyunculardan gelir ? ve parametre tablosu kullanın, asla birleştirme
Sunucu bir komutta kilitleniyor Döngüde sorgu yok: bir kez getirin, Lua'da döngü yapın
İki yazma birlikte gitmeli MySQL.transaction.await
Aynı sorgu sürekli çalışır MySQL.prepare, bir dizin veya Lua'da değeri önbelleğe alın

Kısa yanıtlar

Kodumda MySQL.query.await'i nasıl kullanırım?

Sunucu betiklerinizden önce fxmanifest.lua'da server_script '@oxmysql/lib/MySQL.lua' ekleyin, ardından bir iş parçacığında veya olay işleyicisinde MySQL.query.await('SELECT * FROM users WHERE id = ?', { id }) çağırın.

oxmysql ile SQL injection'ı nasıl önlerim?

Sorguyu asla string birleştirmesiyle oluşturmayın. Sorguya ? yer tutucuları koyun ve değerleri bir tablo içinde iletin, böylece oxmysql bunları ayrı olarak gönderir.

query, single ve scalar arasındaki fark nedir?

query tüm satırları döndürür, single ilk satırı veya nil döndürür, scalar ilk satırın ilk sütununu döndürür, örneğin bir sayı.

Bu sorunu yaşatmayan scriptler

Shop CreatorBir dakikadan kısa sürede dükkân kurun — sahipler, çalışanlar, kasalar ve soygunlar dahil.Scripti gör →Item Creator V2Animasyonlar, proplar, efektler ve daha fazlasıyla kullanılabilir eşyalar oluşturun — kod yazmadan.Scripti gör →Crypto MiningBir depo alın, rigleri parça parça kurun ve sürekli hareket eden bir piyasada coin kazın.Scripti gör →

Okumaya devam edin