一、传统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
前几天在CSDN社区巧遇到开源移动数据库框架:Realm
下面是文章中部分内容的几张截图、也是简单的介绍下该框架的特色
可以看到 该框架虽然目前还只支持IOS平台、但是他的特点中有介绍到 数据可以直接做为对象使用、
接下来有两个demo实例将简单介绍Realm在代码中如何用对象来操作数据
Realm代码示例:
1、针对Objective-C:
2、针对Swift:
对于红色圈起来的代码部分、Realm框架的设计思想 你能否产生共鸣感呢?
PS: 小吕正在不断的学习中完善自身、希望能与大家一起学习、交流... ...
下面是我的微信公众号:Ice资讯助手 欢迎大家扫一扫 关注小吕、给小吕留言!