一、传统DB数据库模块封装
1、继承SQLiteOpenHelper,重写OnCreate(SQLiteDatabase db)和OnUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)方法, 如下图:
2、在OnCreate(SQLiteDatabasedb)方法中初始化创建应用所有的数据库表
这里跟一下代码,我们会发现他首先是把获得每一个表的建表CREATE TABLE语句,然后execSQL该语句,这样就完成了一个具体表的新建,如产品表的新建语句代码片段截图如下:
思考一下、你觉得这种方式好吗?代码好看吗?你是否想到以后表结构变动后的场景吗?能否有一种更高效方式呢?动态生成sql语句?
传统DB模块代码 小小总结:
以上我们可以很明显的看到传统DB模块的代码具有以下几个缺点:
缺点一:如果表字段多,会显得代码臃肿
缺点二:代码灵活性差
缺点三:维护性差
二、寻求新的DB设计思想
思想:IOC注解 + ORM映射
机制:Java反射机制
基本思路:
1、创建一个数据库表对应的实体对象
2、通过注解的方式自定义表名、字段名和缺省值 [也可省略这一步]
3、通过获取注解字段信息、反射实体类名和字段名动态生成sql语句、
4、每一个实体Entity都将有一个Mapping映射类:TableInfo对象 对应着相应的数据库表
TableInfo对象包含实体类名、数据库表名、主键key、其他字段HashMap集合
5、操作实体类 == 间接性的操作DB数据 [数据可以直接做为对象使用]
实例:
一、非注解方式完成对实体的数据操作: 如:创建产品表并添加一条数据
1、创建产品实体类Product.java,代码片段如下:
public class Product {
private int id; // 主键id
private String itemNumber; // 产品编号
private String itemName; // 产品名称
private double price; // 价钱
private String description; // 产品描述
private String imageUrl; // 图片URL
public Product(){}
public Product(String itemNumber, String itemName, double price,String description, String imageUrl) {
this.itemNumber = itemNumber;
this.itemName = itemName;
this.price = price;
this.description = description;
this.imageUrl = imageUrl;
}
/** get/set方法 */
..........
2、获取对数据库操作的入口类IceDB<小吕自己封装的一个类>对象<获取方式有很多种>,代码片段如下:
// IceDb icedb = IceDb.getIceDb(DbTestActivity.this);
IceDb icedb = IceDb.getIceDb(DbTestActivity.this, "icetest.db", true);
3、实例化实体对象数据、并对实体对象进行数据操作,代码片段如下:
// 实例化产品对象、并初始化产品数据
Product product = new Product("999", "蛋白粉", 255.5, "营养蛋白", "http://pic.xxx.jpg");
// 保存产品信息到数据库
icedb.save(product);
// 查找所有的产品信息
List<Product> products = icedb.queryAll(Product.class);
4、运行效果:
我们可以使用Eclipse集成插件sqlitemanager 查看SQLite数据库情况,如下图生成产品实体类映射出来的数据表 com_ice_demo_entity_Product <表名= 包名_实体类名>
表数据情况如下图:
这里我们可以看到 产品实体类 Product 通过映射生成的数据表名为 包名_实体类名,数据也都正常保存进了数据库、唯一缺陷就是这表名太丑啦!那我们能否通过配置自定义生成表名呢?答案是可以的、在做服务端开发使用Spring时 我们会大量的使用Ioc注解、那么通过注解来配置表名、字段名、缺省值将是非常不错的一种方案。
二、注解方式完成对实体的数据操作: 如:创建人员表并添加一条数据
1、创建人员实体类Person.java <含注解>,代码片段如下:
@Table(name = "t_person")
public class Person {
@Column(name = "_id")
@Key private int id;
@Column(name = "name")
private String name;
@Column(name = "age", defaultValue = "23")
private int age;
@Column(name = "sex", defaultValue = "男")
private String sex;
// 缺省Column注解时 会生成表字段名为属性本身
private boolean isMarryed;
@Transient // 注解 该属性 标识为 该实体类字段为非数据库字段
private boolean flag;
public Person(){}
public Person(String name, int age, String sex, boolean isMarryed,
boolean flag) {
this.name = name;
this.age = age;
this.sex = sex;
this.isMarryed = isMarryed;
this.flag = flag;
}
// ---get/set方法
.........
2、获取对数据库操作的入口类IceDB对象<获取方式有很多种>,代码片段如下:
// IceDb icedb = IceDb.getIceDb(DbTestActivity.this);
IceDb icedb = IceDb.getIceDb(DbTestActivity.this, "icetest.db", true);
3、实例化实体对象数据、并对实体对象进行数据操作
// 实例化人员对象、并初始化人员数据
Person p = new Person("ice", 24, "男", false, true);
// 保存人员信息到数据库
icedb.save(p);
// 查找所有的人员数据
List<Person> persons = icedb.queryAll(Person.class);
<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);"> </span>
4、运行效果:
生成人员实体类映射出来的数据表 t_person <通过注解属性Table 定义的表名> 如下图:
表数据情况如下图:
小结:相比前面的传统DB模块代码,具有以下优点:
1、易用性、简化了DB的CURD操作,除去了用代码组拼sql语句的过程。
2、增强了代码的可读性、可维护性
3、易用性
三、巧遇开源移动数据库框架:Realm
前几天在优快云社区巧遇到开源移动数据库框架:Realm
下面是文章中部分内容的几张截图、也是简单的介绍下该框架的特色
可以看到 该框架虽然目前还只支持IOS平台、但是他的特点中有介绍到 数据可以直接做为对象使用、
接下来有两个demo实例将简单介绍Realm在代码中如何用对象来操作数据
Realm代码示例:
1、针对Objective-C:
2、针对Swift:
对于红色圈起来的代码部分、Realm框架的设计思想 你能否产生共鸣感呢?
PS: 小吕正在不断的学习中完善自身、希望能与大家一起学习、交流... ...
下面是我的微信公众号:Ice资讯助手 欢迎大家扫一扫 关注小吕、给小吕留言!