NXUI.Storage().query() NexaModels
Query builder SQL react di NXUI. Mulai dari
NXUI.Storage().query("nama_tabel"), lalu rantai
select, where, get(), dan seterusnya.
Ringkasan alur Storage: NXUI.Storage().
Overview
NexaModels adalah query builder SQL yang terintegrasi dalam framework NXUI. Anda menyusun query database dengan method chaining, tanpa menyusun string SQL mentah secara manual, dengan pola yang mudah dibaca.
Fitur utama
- Method chaining — sintaks mudah dibaca.
- SQL injection protection — prepared statements.
- Security features — filter field sensitif otomatis.
- Promise support — async/await dan .then()/.catch().
- Type safety — validasi input dan parameter.
- Flexible query building — operasi SQL standar.
- NXUI integration — lewat
NXUI.Storage().query().
Installation & setup
1. Lewat NXUI.Storage().query() (cara di app)
Query builder tabel SQL dimulai dari NXUI.Storage().query(namaTabel).
Rantai .select() / .where() / .get() sama seperti pada
NexaModels; untuk data dari server gunakan misalnya const rows = await NXUI.Storage()….
Penting — jangan tertukar:
| Pemanggilan | Fungsi |
|---|---|
NXUI.Storage().query("news") |
Tabel SQL news — query builder (NexaModels). |
NXUI.Storage().querys("News", { method, params }) |
Class model PHP News — bukan builder tabel. |
const rows = await NXUI.Storage()
.query("news")
.select("*")
.get();
Setelah .query("…") Anda memakai seluruh method NexaModels
(where, join, orderBy, toSql, dll.).
Contoh dengan variabel query di bawah mengasumsikan
const query = NXUI.Storage().query("users"); (ganti nama tabel sesuai kebutuhan).
Basic usage
1. Simple SELECT query
const sqlQuery = NXUI.Storage()
.query("users")
.select(["id", "name", "email"])
.where("status", "=", "active")
.toSql();
console.log(sqlQuery);
// Output: SELECT id, name, email FROM users WHERE status = ?2. Complex query dengan JOIN
const sqlQuery = NXUI.Storage()
.query("users")
.select(["users.name", "profiles.bio", "departments.name as dept_name"])
.join("profiles", "users.id", "=", "profiles.user_id")
.leftJoin("departments", "users.department_id", "=", "departments.id")
.where("users.status", "=", "active")
.orderBy("users.name", "ASC")
.toSql();3. Query dengan kondisi lanjutan
const sqlQuery = NXUI.Storage()
.query("users")
.select(["*"])
.whereIn("id", [1, 2, 3, 4, 5])
.whereBetween("created_at", ["2024-01-01", "2024-12-31"])
.whereNotNull("email")
.groupBy("department_id")
.having("COUNT(*)", ">", 5)
.toSql();Query building methods
Table selection
// Basic: tabel dari Storage (disarankan)
const query = NXUI.Storage().query("users");
// Alias untuk table
query.from("users as u");
// Tabel lain — builder baru
const products = NXUI.Storage().query("products");
// Eksekusi async
const rows = await NXUI.Storage().query("news").select("*").get();Column selection
query.select(["id", "name", "email"]);
query.select("*");
query.select(["id", "name as full_name", "email"]);
query.except(["password", "secret_key"]);
query.noSensitive();
query.noTimestamps();WHERE clauses
query.where("status", "=", "active");
query.where("age", ">", 18);
query.where("name", "LIKE", "%john%");
query.orWhere("role", "=", "admin");
query.whereIn("id", [1, 2, 3, 4, 5]);
query.whereNotIn("status", ["banned", "suspended"]);
query.whereBetween("created_at", ["2024-01-01", "2024-12-31"]);
query.whereNotBetween("age", [18, 65]);
query.whereNull("deleted_at");
query.whereNotNull("email");
query.whereLike("name", "%john%");
query.orWhereLike("email", "%gmail%");
query.whereDate("created_at", "=", "2024-01-01");
query.whereYear("created_at", "=", 2024);
query.whereMonth("created_at", "=", 12);
query.whereDay("created_at", "=", 25);JOIN operations
query.join("profiles", "users.id", "=", "profiles.user_id");
query.leftJoin("departments", "users.department_id", "=", "departments.id");
query.rightJoin("orders", "users.id", "=", "orders.user_id");
query.innerJoin("profiles", "users.id", "=", "profiles.user_id");ORDER BY & GROUP BY
query.orderBy("name", "ASC");
query.orderBy("created_at", "DESC");
query.latest("created_at");
query.oldest("updated_at");
query.inRandomOrder();
query.groupBy("department_id");
query.groupBy(["department_id", "status"]);
query.having("COUNT(*)", ">", 5);
query.having("SUM(amount)", ">", 1000);LIMIT & OFFSET
query.limit(10);
query.offset(20);
query.take(10);
query.skip(20);
query.paginateQuery(1, 10);UNION operations
query.union(otherQuery);
query.unionAll(otherQuery);Security features
1. Sensitive data filtering
query.noSensitive();
query.except(["password", "secret_key", "api_token"]);
query.noTimestamps();
query.noSystem();
query.noId();2. Input validation
query.validateTableName("users");
query.validateTableName("users; DROP TABLE users;");
query.validateColumnName("name");
query.validateColumnName("name; DROP TABLE users;");3. SQL injection protection
const query = NXUI.Storage()
.query("users")
.where("name", "=", userInput);
const { sql, bindings } = query.toSqlWithBindings();Aggregate functions
Count
query.countSql("id");
query.countSql("*");
query.countByConditions("id", [
{ column: "status", operator: "=", value: "active" },
{ column: "age", operator: ">", value: 18 },
]);
query.countWithPercentage("id", [
{ column: "status", operator: "=", value: "active" },
]);
query.countByGroup("department_id", "id");Sum, average, min, max
query.sumSql("amount");
query.sumColumns(["price", "tax", "shipping"]);
query.avgSql("rating");
query.avgColumns(["score1", "score2", "score3"]);
query.minSql("created_at");
query.maxSql("updated_at");Custom aggregate
query.aggregateSql("COUNT", "id");
query.aggregateSql("AVG", "rating");API integration
1. HTTP methods
const query = NXUI.Storage()
.query("users")
.where("status", "=", "active");
const rows = await query.get("Fetch");
const newUser = await query.insert(
{ name: "John Doe", email: "john@example.com" },
"Create"
);
const updated = await query.update({ name: "Jane Doe" }, "Update");
const deleted = await query.delete("Delete");2. Promise support
query
.get("Fetch")
.then((rows) => console.log("Data:", rows))
.catch((error) => console.error("Error:", error));
try {
const rows = await query.get("Fetch");
console.log("Data:", rows);
} catch (error) {
console.error("Error:", error);
}3. Pagination
const rows = await query.paginate(1, 10, "Fetch");
const paginationInfo = query.paginateInfo(1, 10);Advanced features
1. Query cloning
const baseQuery = NXUI.Storage()
.query("users")
.where("status", "=", "active");
const clonedQuery = baseQuery.clone();
const activeUsers = await clonedQuery.get("Fetch");
const adminUsers = clonedQuery.where("role", "=", "admin").get("Fetch");2. Query debugging
query.dump();
query.dd();
const queryInfo = query.inspect();
console.log(queryInfo);3. Raw SQL
query.rawSql("SELECT * FROM users WHERE age > ?", [18]);
query.rawSql("SELECT COUNT(*) FROM users");4. Transaction support
const transactionQueries = [
{ sql: "INSERT INTO users (name) VALUES (?)", bindings: ["John"] },
{
sql: "INSERT INTO profiles (user_id, bio) VALUES (?, ?)",
bindings: [1, "Bio"],
},
];
query.transactionSql(transactionQueries);Practical examples
1. User management
async function getActiveUsers(page = 1, perPage = 10) {
const query = NXUI.Storage()
.query("users")
.select(["id", "name", "email", "created_at"])
.where("status", "=", "active")
.orderBy("created_at", "DESC");
try {
return await query.paginate(page, perPage, "Fetch");
} catch (error) {
console.error("Error loading users:", error);
return null;
}
}
async function searchUsers(searchTerm, filters = {}) {
const query = NXUI.Storage()
.query("users")
.select(["id", "name", "email"]);
if (searchTerm) {
query
.whereLike("name", `%${searchTerm}%`)
.orWhereLike("email", `%${searchTerm}%`);
}
if (filters.department) query.where("department_id", "=", filters.department);
if (filters.status) query.where("status", "=", filters.status);
return await query.get("Fetch");
}
async function createUser(userData) {
return await NXUI.Storage().query("users").insert(userData, "Create");
}2. Dashboard statistics
async function getDashboardStats() {
try {
const [totalUsers, totalRevenue, totalProducts] = await Promise.all([
NXUI.Storage().query("users").count("id", "Fetch"),
NXUI.Storage().query("orders").sum("total", "Fetch"),
NXUI.Storage().query("products").count("id", "Fetch"),
]);
return { totalUsers, totalRevenue, totalProducts };
} catch (error) {
console.error("Error loading dashboard stats:", error);
return null;
}
}3. E-commerce products
async function getProductsWithCategories(filters = {}) {
const query = NXUI.Storage()
.query("products")
.select(["products.*", "categories.name as category_name"])
.join("categories", "products.category_id", "=", "categories.id")
.where("products.status", "=", "active");
if (filters.category) query.where("categories.id", "=", filters.category);
if (filters.priceMin) query.where("products.price", ">=", filters.priceMin);
if (filters.priceMax) query.where("products.price", "<=", filters.priceMax);
if (filters.search) query.whereLike("products.name", `%${filters.search}%`);
query.orderBy("products.name", "ASC");
return await query.get("Fetch");
}
async function getProductStats() {
const [totalProducts, avgPrice, maxPrice, minPrice] = await Promise.all([
NXUI.Storage().query("products").count("id", "Fetch"),
NXUI.Storage().query("products").avg("price", "Fetch"),
NXUI.Storage().query("products").max("price", "Fetch"),
NXUI.Storage().query("products").min("price", "Fetch"),
]);
return { totalProducts, avgPrice, maxPrice, minPrice };
}Integrasi NXUI components
1. NexaTabel
async function loadTableData() {
const query = NXUI.Storage()
.query("users")
.select(["id", "name", "email", "status"])
.where("active", "=", 1)
.orderBy("name", "ASC");
const rows = await query.get("Fetch");
const table = new NXUI().NexaTabel();
table.render("#users-table", rows);
return rows;
}2. NexaModal
async function loadUserForm(userId) {
const row = await NXUI.Storage()
.query("users")
.select(["*"])
.where("id", "=", userId)
.first("Fetch");
if (row) NXUI().nexaModal.open("user-form", row);
}3. NexaFilter
function setupDataFilter() {
const query = NXUI.Storage()
.query("users")
.select(["id", "name", "email", "department_id"]);
const filter = new NXUI().NexaFilter();
filter.setup("#filter-container", {
data: query,
filters: [
{ field: "name", type: "text", placeholder: "Search by name" },
{ field: "department_id", type: "select", options: departmentOptions },
{ field: "status", type: "select", options: statusOptions },
],
onFilter: (filteredData) => updateTable(filteredData),
});
}Best practices
Query optimization & error handling
// Pilih kolom yang perlu saja
query.select(["id", "name", "email"]);
// Error handling
try {
return await query.get("Fetch");
} catch (error) {
console.error("Query failed:", error);
return null;
}
// Pagination untuk data besar
query.paginate(1, 10, "Fetch");Security & performance
// Gunakan binding / where terparameter
query.where("name", "=", userInput);
// Hindari konkatenasi mentah ke raw SQL untuk input pengguna
// query.rawSql(`SELECT * FROM users WHERE name = '${userInput}'`); // burukAPI reference
Constructor (internal / library)
new NexaModels((secretKey = "nexa-default-secret-key-2025"));
Di aplikasi mulai dari NXUI.Storage().query("nama_tabel"); jangan menginstansiasi
NexaModels langsung kecuali untuk pengembangan inti library.
Table methods
table(tableName)— set nama tabelfrom(tableName)— alias tableStorage(tableName)— alias table
Selection methods
select(columns),except(columns)noSensitive(),noTimestamps(),noSystem()
WHERE methods
where,orWhere,whereIn,whereNotInwhereBetween,whereNotBetween,whereNull,whereNotNullwhereLike,orWhereLikewhereDate,whereYear,whereMonth,whereDay
JOIN methods
join,leftJoin,rightJoin,innerJoin
Order & group
orderBy,latest,oldest,inRandomOrdergroupBy,having
Limit
limit,offset,take,skip
SQL generation
toSql(),toSqlWithBindings(),toSqlWithParams(),getBindings()
API methods
get(endpoint, options),post(endpoint, options)insert(data, endpoint, options),update(data, endpoint, options)delete(endpoint, options),paginate(page, perPage, endpoint, options)
Utility
clone(),reset(),dump(),dd(),inspect()
Troubleshooting
- Query tanpa hasil — cek nama tabel, kondisi WHERE, dan data di database.
- SQL injection — gunakan prepared statements /
whereterparameter; hindari konkatenasi string. - Performa — pagination, pilih kolom secukupnya, indeks di DB.
- Memori — chunking untuk data besar; reset query jika perlu.
console.log(query.toSql());
console.log(query.getBindings());
query.dump();
console.log(query.inspect());