基于HarmonyOS关系型数据库的房间管理系统设计与实现代码放置位置
·
代码放置位置:
将上述完整代码复制到 entry/src/main/ets/pages/Index.ets 文件中,替换原有内容即可。
功能说明
本实验实现了一个完整的智能家居房间管理应用,通过HarmonyOS的关系型数据库(relationalStore)对房间数据进行持久化存储,支持房间的添加、删除、修改、查询等核心功能。用户可以在应用首页查看所有房间列表,通过“编辑”模式对房间进行修改或删除操作,点击“添加房间”按钮可输入房间名称或从推荐的房间列表中选择快速添加。应用采用卡片式UI设计,每个房间以不同颜色的圆点进行视觉区分,界面简洁美观。该实验全面覆盖了数据库的建表、增删改查、结果集处理等核心知识点,是理解HarmonyOS数据持久化存储的完整实践案例。
代码:(ArkTS 语言)
// Index.ets - 简化完整版房间管理应用
// 功能:基于HarmonyOS关系型数据库实现房间的增删改查操作
// 导入关系型数据库模块 - 用于数据持久化存储
import relationalStore from '@ohos.data.relationalStore';
// 导入提示框模块 - 用于显示操作结果提示
import promptAction from '@ohos.promptAction';
/**
* 房间数据模型类
* 用于封装房间的数据结构,对应数据库中的ROOMS表
*/
class RoomData {
id: number = -1; // 房间ID,主键,自动递增
name: string = ''; // 房间名称
constructor(id: number, name: string) {
this.id = id;
this.name = name;
}
}
@Entry
@Component
struct Index {
// ==================== 状态变量定义 ====================
@State rooms: RoomData[] = []; // 房间列表数据,驱动UI更新
@State isEditMode: boolean = false; // 编辑模式标志:true显示编辑/删除按钮,false显示详情按钮
@State showCreateDialog: boolean = false; // 对话框显示控制:true显示,false隐藏
@State newRoomName: string = ''; // 新增房间的名称(临时存储)
@State editRoomName: string = ''; // 编辑房间的名称(临时存储)
@State editingRoomId: number = -1; // 正在编辑的房间ID,-1表示新增模式
@State isLoading: boolean = true; // 加载状态:true显示加载动画,false显示内容
// ==================== 私有成员变量 ====================
private rdbStore: relationalStore.RdbStore | null = null; // 数据库实例对象
private context: Context = getContext(this); // 应用上下文,用于获取数据库路径
private isDbReady: boolean = false; // 数据库就绪标志
// 推荐房间名称列表(快速选择用)
private recommendedRooms: string[] = [
'客厅', '卧室', '厨房', '卫生间', '书房',
'阳台', '餐厅', '儿童房', '主卧', '客房'
];
// ==================== 生命周期方法 ====================
/**
* 页面加载时自动调用
* 执行顺序:初始化数据库 -> 加载房间数据 -> 关闭加载动画
*/
async aboutToAppear() {
await this.initDatabase(); // 初始化数据库(建库、建表)
await this.loadRooms(); // 从数据库加载房间数据
this.isLoading = false; // 数据加载完成,关闭加载动画
}
// ==================== 数据库操作方法 ====================
/**
* 初始化数据库
* 1. 创建/打开数据库文件
* 2. 创建数据表(如果不存在)
*/
async initDatabase(): Promise<void> {
return new Promise((resolve) => {
// 数据库配置对象
const STORE_CONFIG: relationalStore.StoreConfig = {
name: 'RoomDatabase.db', // 数据库文件名
securityLevel: relationalStore.SecurityLevel.S1 // 安全级别
};
// 获取数据库实例(异步操作)
relationalStore.getRdbStore(this.context, STORE_CONFIG, (err, store) => {
if (err) {
console.error('数据库初始化失败');
resolve();
return;
}
this.rdbStore = store; // 保存数据库实例
// 创建表:ID主键自增,NAME非空
const sql = 'CREATE TABLE IF NOT EXISTS ROOMS (ID INTEGER PRIMARY KEY AUTOINCREMENT, NAME TEXT NOT NULL)';
this.rdbStore!.executeSql(sql); // 执行SQL语句
this.isDbReady = true; // 标记数据库已就绪
console.info('数据库初始化成功');
resolve();
});
});
}
/**
* 从数据库加载所有房间数据
* 使用RdbPredicates构建查询条件,按ID升序排列
*/
async loadRooms(): Promise<void> {
if (!this.rdbStore || !this.isDbReady) {
this.rooms = [];
return;
}
// 创建谓词(查询条件对象)
const predicates = new relationalStore.RdbPredicates('ROOMS');
predicates.orderByAsc('ID'); // 按ID升序排列
return new Promise((resolve) => {
// 执行查询,返回结果集
this.rdbStore!.query(predicates, ['ID', 'NAME'], (err, resultSet) => {
if (err) {
this.rooms = [];
resolve();
return;
}
const roomList: RoomData[] = [];
// 遍历结果集,将数据转换为RoomData对象
if (resultSet && resultSet.rowCount > 0) {
resultSet.goToFirstRow(); // 移动到第一行
for (let i = 0; i < resultSet.rowCount; i++) {
const id = resultSet.getLong(resultSet.getColumnIndex('ID')); // 获取ID
const name = resultSet.getString(resultSet.getColumnIndex('NAME')); // 获取名称
roomList.push(new RoomData(id, name));
resultSet.goToNextRow(); // 移动到下一行
}
}
// 关闭结果集,释放资源
if (resultSet) {
resultSet.close();
}
this.rooms = roomList; // 更新UI数据
resolve();
});
});
}
/**
* 添加新房间
* 1. 校验数据库是否就绪
* 2. 校验房间名称非空
* 3. 校验名称是否重复
* 4. 执行数据库插入操作
*/
async addRoom(): Promise<void> {
// 数据库未就绪提示
if (!this.isDbReady) {
promptAction.showToast({ message: '数据库初始化中...', duration: 1500 });
return;
}
// 名称非空校验
if (this.newRoomName.trim() === '') {
promptAction.showToast({ message: '请输入房间名称', duration: 1500 });
return;
}
// 名称重复校验
const exists = this.rooms.some(room => room.name === this.newRoomName);
if (exists) {
promptAction.showToast({ message: '房间名称已存在', duration: 1500 });
return;
}
// 构建要插入的数据
const valueBucket: relationalStore.ValuesBucket = { 'NAME': this.newRoomName };
// 执行插入操作
this.rdbStore!.insert('ROOMS', valueBucket, async (err, rowId) => {
if (err) {
promptAction.showToast({ message: '添加失败', duration: 1500 });
} else {
promptAction.showToast({ message: '添加成功', duration: 1500 });
this.newRoomName = ''; // 清空输入
this.showCreateDialog = false; // 关闭对话框
await this.loadRooms(); // 刷新列表
}
});
}
/**
* 删除房间
* @param room - 要删除的房间对象
*/
async deleteRoom(room: RoomData): Promise<void> {
if (!this.isDbReady) return;
// 构建删除条件:ID = 指定值
const predicates = new relationalStore.RdbPredicates('ROOMS');
predicates.equalTo('ID', room.id);
// 执行删除操作
this.rdbStore!.delete(predicates, async (err, rows) => {
if (!err && rows > 0) {
promptAction.showToast({ message: `已删除 ${room.name}`, duration: 1500 });
await this.loadRooms(); // 刷新列表
} else {
promptAction.showToast({ message: '删除失败', duration: 1500 });
}
});
}
/**
* 更新房间名称
* 1. 校验名称非空
* 2. 校验新名称是否与其他房间重复(排除自身)
* 3. 执行数据库更新操作
*/
async updateRoom(): Promise<void> {
if (!this.isDbReady) return;
// 名称非空校验
if (this.editRoomName.trim() === '') {
promptAction.showToast({ message: '请输入房间名称', duration: 1500 });
return;
}
// 名称重复校验(排除当前编辑的房间)
const exists = this.rooms.some(room =>
room.name === this.editRoomName && room.id !== this.editingRoomId
);
if (exists) {
promptAction.showToast({ message: '房间名称已存在', duration: 1500 });
return;
}
// 构建要更新的数据
const valueBucket: relationalStore.ValuesBucket = { 'NAME': this.editRoomName };
// 构建更新条件:ID = 指定值
const predicates = new relationalStore.RdbPredicates('ROOMS');
predicates.equalTo('ID', this.editingRoomId);
// 执行更新操作
this.rdbStore!.update(valueBucket, predicates, async (err, rows) => {
if (!err && rows > 0) {
promptAction.showToast({ message: '修改成功', duration: 1500 });
this.showCreateDialog = false; // 关闭对话框
await this.loadRooms(); // 刷新列表
} else {
promptAction.showToast({ message: '修改失败', duration: 1500 });
}
});
}
// ==================== UI交互方法 ====================
/**
* 显示删除确认对话框
* @param room - 要删除的房间对象
*/
showDeleteConfirm(room: RoomData): void {
AlertDialog.show({
title: '确认删除',
message: `确定要删除 "${room.name}" 吗?`,
autoCancel: true,
alignment: DialogAlignment.Center,
primaryButton: { value: '取消', action: () => {} },
secondaryButton: {
value: '删除',
fontColor: Color.Red,
action: () => { this.deleteRoom(room); }
}
});
}
/**
* 打开编辑对话框
* @param room - 要编辑的房间对象
*/
openEditDialog(room: RoomData): void {
this.editingRoomId = room.id; // 记录正在编辑的房间ID
this.editRoomName = room.name; // 预填当前名称
this.showCreateDialog = true; // 显示对话框
}
/**
* 获取房间卡片颜色(根据索引循环取色)
* @param index - 房间在列表中的索引
* @returns 颜色代码
*/
getRoomColor(index: number): string {
const colors = ['#FF6B6B', '#4ECDC4', '#45B7D1', '#96CEB4', '#FFEAA7', '#DDA0DD', '#98D8C8', '#F7B787'];
return colors[index % colors.length];
}
// ==================== UI构建方法 ====================
build() {
Column() {
// ---------- 顶部标题栏 ----------
Row() {
Text('🏠 智能家居')
.fontSize(28)
.fontWeight(FontWeight.Bold)
.fontColor('#1A1A2E')
Blank() // 弹性空间,将按钮推到右侧
// 编辑模式切换按钮
Button(this.isEditMode ? '完成' : '编辑')
.fontSize(16)
.fontColor(this.isEditMode ? '#FF6B6B' : '#4ECDC4')
.backgroundColor(this.isEditMode ? '#FFF0F0' : '#E8F8F5')
.borderRadius(20)
.padding({ left: 16, right: 16, top: 6, bottom: 6 })
.onClick(() => { this.isEditMode = !this.isEditMode; })
}
.width('90%')
.margin({ top: 20, bottom: 16 })
// ---------- 统计栏:显示房间数量 ----------
Row() {
Text('📋 我的房间')
.fontSize(18)
.fontWeight(FontWeight.Medium)
.fontColor('#2C3E50')
Blank()
Text(`${this.rooms.length} 个房间`)
.fontSize(14)
.fontColor('#7F8C8D')
.padding({ left: 10, right: 10, top: 4, bottom: 4 })
.backgroundColor('#F0F3F4')
.borderRadius(15)
}
.width('90%')
.margin({ bottom: 16 })
// ---------- 内容区域(三种状态:加载中、空列表、列表展示)----------
// 状态1:正在加载数据
if (this.isLoading) {
Column() {
LoadingProgress().width(50).height(50).color('#4ECDC4').margin({ top: 100 })
Text('加载中...').fontSize(14).fontColor('#95A5A6').margin({ top: 16 })
}
.width('100%')
.layoutWeight(1)
}
// 状态2:列表为空
else if (this.rooms.length === 0) {
Column() {
Text('🏠').fontSize(80).opacity(0.3).margin({ top: 100 })
Text('暂无房间').fontSize(18).fontColor('#BDC3C7').margin({ top: 16 })
Text('点击下方按钮添加第一个房间').fontSize(14).fontColor('#D5D8DC').margin({ top: 8 })
}
.width('100%')
.layoutWeight(1)
}
// 状态3:显示房间列表
else {
Scroll() {
Column() {
// ForEach循环渲染每个房间卡片
ForEach(this.rooms, (room: RoomData, index: number) => {
Row() {
// 左侧:彩色圆点 + 房间名称 + ID
Row() {
Circle().width(12).height(12).fill(this.getRoomColor(index)).margin({ right: 12 })
Text(room.name)
.fontSize(18)
.fontWeight(FontWeight.Medium)
.fontColor('#2C3E50')
Text(` #${room.id}`)
.fontSize(12)
.fontColor('#95A5A6')
}
Blank()
// 右侧按钮:根据编辑模式显示不同按钮
if (this.isEditMode) {
// 编辑模式:显示编辑和删除按钮
Row() {
Button('编辑')
.fontSize(14)
.fontColor('#4ECDC4')
.backgroundColor('#E8F8F5')
.borderRadius(20)
.padding({ left: 16, right: 16, top: 6, bottom: 6 })
.margin({ right: 8 })
.onClick(() => { this.openEditDialog(room); })
Button('删除')
.fontSize(14)
.fontColor('#FF6B6B')
.backgroundColor('#FFF0F0')
.borderRadius(20)
.padding({ left: 16, right: 16, top: 6, bottom: 6 })
.onClick(() => { this.showDeleteConfirm(room); })
}
} else {
// 正常模式:显示详情按钮
Button('详情')
.fontSize(14)
.fontColor(Color.White)
.backgroundColor('#4ECDC4')
.borderRadius(20)
.padding({ left: 20, right: 20, top: 6, bottom: 6 })
.onClick(() => {
AlertDialog.show({
title: room.name,
message: `房间ID: ${room.id}\n\n点击编辑按钮可修改房间名称`,
autoCancel: true,
alignment: DialogAlignment.Center,
confirm: { value: '知道了', action: () => {} }
});
})
}
}
.width('90%')
.padding({ left: 16, right: 16, top: 14, bottom: 14 })
.backgroundColor(Color.White)
.borderRadius(16)
.margin({ bottom: 12 })
.shadow({ radius: 6, color: '#1A000000', offsetY: 2 }) // 卡片阴影效果
}, (room: RoomData) => room.id.toString()) // 使用id作为唯一键
}
.width('100%')
.padding({ bottom: 20 })
}
.scrollBar(BarState.Off) // 隐藏滚动条
.layoutWeight(1)
}
// ---------- 底部添加按钮(固定位置)----------
Button() {
Row() {
Text('+').fontSize(28).fontWeight(FontWeight.Bold).fontColor(Color.White)
Text('添加房间').fontSize(18).fontWeight(FontWeight.Medium).fontColor(Color.White).margin({ left: 8 })
}
}
.width('90%')
.height(56)
.backgroundColor('#4ECDC4')
.borderRadius(28)
.margin({ bottom: 20 })
.onClick(() => {
// 数据库未就绪提示
if (!this.isDbReady) {
promptAction.showToast({ message: '数据库初始化中...', duration: 1500 });
return;
}
// 重置表单数据
this.newRoomName = '';
this.editingRoomId = -1;
this.editRoomName = '';
this.showCreateDialog = true; // 显示对话框
})
}
.width('100%')
.height('100%')
.backgroundColor('#F8F9FA')
// ---------- 底部弹出对话框(添加/编辑共用)----------
.bindSheet($$this.showCreateDialog, this.RoomDialogBuilder(), {
height: this.editingRoomId === -1 ? 480 : 280, // 添加模式更高(显示推荐列表),编辑模式较矮
dragBar: true, // 显示拖拽条
backgroundColor: '#FFFFFF',
showClose: true, // 显示关闭按钮
title: {
title: this.editingRoomId === -1 ? '添加房间' : '编辑房间',
subtitle: this.editingRoomId === -1 ? '选择或输入房间名称' : '修改房间名称'
}
})
}
/**
* 房间对话框构建器(添加/编辑共用)
* 包含:输入框、推荐列表(仅添加模式)、确认/取消按钮
*/
@Builder
RoomDialogBuilder() {
Column() {
// ---------- 名称输入框 ----------
TextInput({
placeholder: this.editingRoomId === -1 ? '请输入房间名称' : '请输入新的房间名称',
text: this.editingRoomId === -1 ? this.newRoomName : this.editRoomName
})
.width('90%')
.height(52)
.fontSize(16)
.backgroundColor('#F5F5F5')
.borderRadius(12)
.padding({ left: 16, right: 16 })
.onChange((value: string) => {
// 根据模式更新不同的状态变量
if (this.editingRoomId === -1) {
this.newRoomName = value;
} else {
this.editRoomName = value;
}
})
// ---------- 推荐房间列表(仅添加模式显示)----------
if (this.editingRoomId === -1) {
Text('💡 推荐房间')
.fontSize(14)
.fontColor('#7F8C8D')
.width('90%')
.margin({ top: 20, bottom: 12 })
// Flex布局实现换行效果
Flex({ wrap: FlexWrap.Wrap, justifyContent: FlexAlign.Start }) {
ForEach(this.recommendedRooms, (roomName: string) => {
Text(roomName)
.padding({ left: 16, right: 16, top: 8, bottom: 8 })
.fontSize(14)
.backgroundColor('#F0F3F4')
.borderRadius(20)
.margin({ right: 8, bottom: 8 })
.onClick(() => {
this.newRoomName = roomName; // 点击推荐名称自动填充
})
}, (roomName: string) => roomName)
}
.width('90%')
}
// ---------- 底部按钮区域 ----------
Row() {
// 取消按钮
Button('取消')
.width('45%')
.height(48)
.fontSize(16)
.backgroundColor('#ECF0F1')
.fontColor('#7F8C8D')
.borderRadius(24)
.onClick(() => {
this.showCreateDialog = false; // 关闭对话框
this.newRoomName = '';
this.editRoomName = '';
})
// 确认按钮(根据模式显示不同文字和颜色)
Button(this.editingRoomId === -1 ? '确认添加' : '保存修改')
.width('45%')
.height(48)
.fontSize(16)
.backgroundColor(this.editingRoomId === -1 ? '#4ECDC4' : '#FF6B6B')
.fontColor(Color.White)
.borderRadius(24)
.onClick(() => {
if (this.editingRoomId === -1) {
this.addRoom(); // 添加模式
} else {
this.updateRoom(); // 编辑模式
}
})
}
.width('90%')
.justifyContent(FlexAlign.SpaceBetween)
.margin({ top: 24, bottom: 16 })
}
.width('100%')
.padding({ top: 16, bottom: 16 })
}
}
具体效果:

更多推荐



所有评论(0)