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:
-- 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 |
-- 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:
-- 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:
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:
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:
-- one query per player
for _, id in ipairs(ids) do
local row = MySQL.single.await('SELECT * FROM users WHERE id = ?', { id })
endHer şeyi tek bir sorguda getirin, ardından Lua'da sonuç üzerinde döngü yapın:
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:
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')
endHerhangi 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 →