Flutter JSON转Dart模型插件json2dart_safe的使用
Flutter JSON转Dart模型插件json2dart_safe的使用
I. 概述
json2dart
是一个Flutter插件集合,提供以下功能:
-
JSON到Dart模型转换
- 空安全支持
- 多字段解析
- 类型安全转换
- 默认值处理
-
SQLite数据库操作
- 自动生成表结构
- 完整的CRUD操作
- 复杂类型支持
- 批量操作支持
-
数据库可视化调试
- 查看所有数据表
- 查看表结构
- 查看表数据
- SQL语句高亮显示
II. 安装
1. 添加依赖
在 pubspec.yaml
文件中添加以下依赖:
dependencies:
# JSON解析基础包
json2dart_safe: ^1.5.8
# 数据库支持(选择一个)
json2dart_db: ^latest_version # 标准版
json2dart_dbffi: ^latest_version # FFI版(性能更好)
# 数据库查看工具(选择一个)
json2dart_viewer: ^latest_version # 标准版
json2dart_viewerffi: ^latest_version # FFI版
2. 调试工具配置
需要使用 flutter_ume
:
import 'package:json2dart_viewerffi/json2dart_viewerffi.dart';
void main() {
PluginManager.instance
..register(const DBViewer()) // 注册数据库查看插件
// ... 其他插件注册
}
III. 基本用法
1. JSON解析
// 从Map解析
Map json = {...};
json.asString("key"); // 获取String,如果为null返回""
json.asInt("key"); // 获取int,如果为null返回0
json.asDouble("key"); // 获取double,如果为null返回0.0
json.asBool("key"); // 获取bool,如果为null返回false
json.asBean<T>("key"); // 解析对象
json.asList<T>("key"); // 解析数组
// 多字段解析
json.asStrings(["name", "user_name"]); // 尝试解析name然后是user_name
json.asInts(["id", "user_id"]);
json.asBools(["is_vip", "vip"]);
2. 错误处理
// 添加错误回调
Json2Dart.instance.addCallback((String error) {
print("解析错误: $error");
});
// 详细错误信息
Json2Dart.instance.addDetailCallback((String method, String key, Map? map) {
print("方法: $method, 键: $key, 数据: $map");
});
IV. 使用场景
1. 仅JSON解析
如果你只需要JSON解析功能,只需添加基础包:
dependencies:
json2dart_safe: ^1.5.8
示例模型:
import 'package:json2dart_safe/json2dart.dart';
class UserModel {
final String? username;
final String? nickname;
final int? age;
final List<String>? hobbies;
UserModel({
this.username,
this.nickname,
this.age,
this.hobbies,
});
// JSON序列化
Map<String, dynamic> toJson() => {
'username': username,
'nickname': nickname,
'age': age,
'hobbies': hobbies,
};
// JSON反序列化
factory UserModel.fromJson(Map json) {
return UserModel(
username: json.asString('username'),
nickname: json.asString('nickname'),
age: json.asInt('age'),
hobbies: json.asList<String>('hobbies'),
);
}
}
使用示例:
// 解析JSON
Map<String, dynamic> json = {
'username': 'test',
'age': 18,
'hobbies': ['reading', 'gaming']
};
var user = UserModel.fromJson(json);
// 转换为JSON
Map<String, dynamic> data = user.toJson();
2. 带数据库支持
如果你需要数据库支持,添加完整依赖:
dependencies:
json2dart_safe: ^1.5.8
json2dart_db: ^latest_version
json2dart_viewer: ^latest_version
在这种情况下,你需要:
- 让你的Model类继承
BaseDbModel
- 实现
primaryKeyAndValue
方法 - 创建相应的Dao类
参见下一章的完整示例。
V. 完整示例
1. 模型定义 (user_model.dart
)
import 'dart:convert';
import 'package:json2dart_safe/json2dart.dart';
/// 用户信息模型
class UserModel with BaseDbModel {
// 数据库主键,自增
int? userId;
// 基础字段
String? username;
String? nickname;
String? avatar;
int? age;
double? height;
bool? isVip;
DateTime? birthday;
// 复杂类型
List<String>? hobbies; // 爱好列表
List<int>? followingIds; // 关注用户ID
Map<String, dynamic>? extra; // 扩展字段
// 构造函数
UserModel({
this.userId,
this.username,
this.nickname,
this.avatar,
this.age,
this.height,
this.isVip,
this.birthday,
this.hobbies,
this.followingIds,
this.extra,
});
// JSON序列化
Map<String, dynamic> toJson() => {
'user_id': userId,
'username': username,
'nickname': nickname,
'avatar': avatar,
'age': age,
'height': height,
'is_vip': isVip,
'birthday': birthday?.millisecondsSinceEpoch,
'hobbies': hobbies,
'following_ids': followingIds,
'extra': extra,
};
// JSON反序列化
factory UserModel.fromJson(Map json) {
return UserModel(
userId: json.asInt('user_id'),
username: json.asString('username'),
nickname: json.asString('nickname'),
avatar: json.asString('avatar'),
age: json.asInt('age'),
height: json.asDouble('height'),
isVip: json.asBool('is_vip'),
birthday: json.asInt('birthday') != null
? DateTime.fromMillisecondsSinceEpoch(json.asInt('birthday'))
: null,
hobbies: json.asList<String>('hobbies'),
followingIds: json.asList<int>('following_ids'),
extra: json.asMap('extra'),
);
}
// 静态方法用于数据库操作
static UserModel toBean(Map json) => UserModel.fromJson(json);
// 重写toString用于调试
@override
String toString() => jsonEncode(toJson());
// 重写相等运算符
@override
bool operator ==(Object other) =>
identical(this, other) ||
other is UserModel &&
runtimeType == other.runtimeType &&
userId == other.userId;
@override
int get hashCode => userId.hashCode;
// 实现BaseDbModel方法,返回主键和值
@override
Map<String, dynamic> get primaryKeyAndValue => {'user_id': userId};
}
2. 数据库操作类 (user_dao.dart
)
import 'package:json2dart_db/database/base_dao.dart';
import '../models/user_model.dart';
class UserDao extends BaseDao<UserModel> {
UserDao() : super('tb_user', UserModel.toBean);
// 根据用户名查询
Future<UserModel?> queryByUsername(String username) async {
List<UserModel> users = await query(
where: 'username = ?',
whereArgs: [username],
);
return users.isEmpty ? null : users.first;
}
// 查询VIP用户
Future<List<UserModel>> queryVipUsers() async {
return query(
where: 'is_vip = ?',
whereArgs: [1],
orderBy: 'user_id DESC',
);
}
// 更新用户VIP状态
Future<bool> updateVipStatus(int userId, bool isVip) async {
int count = await update(
{'is_vip': isVip ? 1 : 0},
where: 'user_id = ?',
whereArgs: [userId],
);
return count > 0;
}
// 批量更新关注状态
Future<void> updateFollowingIds(int userId, List<int> followingIds) async {
await update(
{'following_ids': followingIds},
where: 'user_id = ?',
whereArgs: [userId],
);
}
}
3. 使用示例 (user_page.dart
)
import '../database/dao/user_dao.dart';
import '../models/user_model.dart';
class UserPage extends StatefulWidget {
@override
_UserPageState createState() => _UserPageState();
}
class _UserPageState extends State<UserPage> {
final UserDao _userDao = UserDao();
Future<void> _addUser() async {
// 创建用户
var user = UserModel(
username: 'test_user',
nickname: 'Test User',
age: 18,
isVip: false,
hobbies: ['reading', 'gaming'],
followingIds: [1, 2, 3],
extra: {'score': 100},
);
// 插入数据库
int userId = await _userDao.insert(user);
print('插入成功,用户ID:$userId');
// 查询用户
UserModel? dbUser = await _userDao.queryOne(userId);
print('查询结果:$dbUser');
// 更新VIP状态
await _userDao.updateVipStatus(userId, true);
// 更新关注列表
await _userDao.updateFollowingIds(userId, [4, 5, 6]);
// 查询所有VIP用户
List<UserModel> vipUsers = await _userDao.queryVipUsers();
print('VIP用户数量:${vipUsers.length}');
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('用户管理')),
body: Center(
child: ElevatedButton(
onPressed: _addUser,
child: Text('添加测试用户'),
),
),
);
}
}
VI. 数据库表结构
上述模型会自动生成如下表结构:
CREATE TABLE IF NOT EXISTS tb_user (
user_id INTEGER PRIMARY KEY AUTOINCREMENT,
username TEXT,
nickname TEXT,
avatar TEXT,
age INTEGER,
height REAL,
is_vip INTEGER,
birthday INTEGER,
hobbies TEXT, -- 列表类型将自动转换为JSON字符串
following_ids TEXT, -- 列表类型将自动转换为JSON字符串
extra TEXT -- 映射类型将自动转换为JSON字符串
)
关键特性:
-
支持的数据类型:
- INTEGER:用于int类型
- REAL:用于double类型
- TEXT:用于String类型
- INTEGER:用于bool类型(0/1)
-
复杂类型处理:
- 列表和映射类型将自动转换为JSON字符串
- 在读取时自动解析回原始类型
- 不需要手动编写类型转换器
-
主键配置:
- 使用
user_id
作为主键 - 设置为自增
- 通过
primaryKeyAndValue
方法指定
- 使用
VII. 重要注意事项
-
数据库相关:
- 新字段必须在数据库升级时手动添加
- 复杂类型会占用更多存储空间
- 调试工具建议仅在调试模式下使用
- FFI版本性能更好但需要额外配置
-
类型安全:
- 所有字段应为可空类型
- JSON解析时进行类型检查
- 数据库操作期间进行类型转换
-
性能优化:
- 避免存储大型复杂类型
- 合理设计表结构和索引
- 使用事务进行批量操作
VIII. 示例项目
完整的示例项目请参考:
以上内容提供了如何使用 json2dart_safe
插件进行JSON到Dart模型的转换,并结合数据库操作的完整示例。希望对你有所帮助!
更多关于Flutter JSON转Dart模型插件json2dart_safe的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter JSON转Dart模型插件json2dart_safe的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,以下是如何在Flutter项目中使用json2dart_safe
插件将JSON转换为Dart模型的详细步骤,包括相关的代码示例。
步骤 1: 添加依赖
首先,在你的pubspec.yaml
文件中添加json2dart_safe
依赖:
dependencies:
flutter:
sdk: flutter
json2dart_safe: ^x.y.z # 请替换为最新版本号
然后在项目根目录下运行flutter pub get
来安装依赖。
步骤 2: 准备JSON数据
假设你有以下的JSON数据:
{
"id": 1,
"name": "John Doe",
"email": "john.doe@example.com"
}
步骤 3: 使用json2dart_safe生成Dart模型
你可以在命令行中使用json2dart_safe
工具来生成Dart模型。假设你的JSON数据保存在一个名为data.json
的文件中,你可以运行以下命令:
flutter pub run json2dart_safe --input data.json --output models/user_model.dart
这个命令会根据data.json
的内容生成一个名为user_model.dart
的Dart文件,并将其保存到models
目录下。生成的user_model.dart
文件可能看起来像这样:
// user_model.dart
class UserModel {
int? id;
String? name;
String? email;
UserModel({this.id, this.name, this.email});
UserModel.fromJson(Map<String, dynamic> json) {
id = json['id'];
name = json['name'];
email = json['email'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
data['id'] = id;
data['name'] = name;
data['email'] = email;
return data;
}
}
步骤 4: 在Flutter项目中使用生成的模型
现在你可以在Flutter项目中使用这个生成的模型了。例如,你可以从一个API获取JSON数据,并将其解析为UserModel
对象:
import 'package:flutter/material.dart';
import 'dart:convert';
import 'models/user_model.dart'; // 导入生成的模型文件
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('JSON to Dart Model'),
),
body: Center(
child: FutureBuilder<UserModel>(
future: fetchUser(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
if (snapshot.hasError) {
return Text('Error: ${snapshot.error}');
}
UserModel user = snapshot.data!;
return Text(
'Name: ${user.name}, Email: ${user.email}',
);
} else {
return CircularProgressIndicator();
}
},
),
),
),
);
}
Future<UserModel> fetchUser() async {
// 模拟从API获取JSON数据
final response = await http.get(Uri.parse('https://api.example.com/user/1'));
if (response.statusCode == 200) {
// 解析JSON数据为UserModel对象
Map<String, dynamic> jsonData = jsonDecode(response.body);
return UserModel.fromJson(jsonData);
} else {
throw Exception('Failed to load user');
}
}
}
请注意,上面的代码示例使用了http
包来模拟从API获取数据。如果你还没有添加http
包到你的项目中,可以在pubspec.yaml
中添加它:
dependencies:
http: ^0.13.3 # 请替换为最新版本号
然后运行flutter pub get
来安装它。
这样,你就完成了使用json2dart_safe
插件将JSON数据转换为Dart模型并在Flutter项目中使用它的整个过程。