数据库ormlite
之前使用数据库的做法:
-创建SqliteOpenHelper子类,指定版本 和数据库名称,并执行sql语句创建表结构
-创建一个Dao类,里面用helper获取SqliteDatabase对象对数据库进行增删改查
-获取这个Dao类对象,就可以对数据库进行增删改查
在项目中基本不这样做了,我们可以采用轻量级ormlite数据库框,用法与原生数据库差不多,但是不写sql语句,采用注解的方式来写表结构,对不喜欢sql语句的宝宝甚是受用。
1.添加依赖
compile 'com.j256.ormlite:ormlite-android:5.0'
2.创建数据库帮助类
OrmLiteSqliteOpenHelper 其实是SqliteOpenHelper的子类
public class UserDbHelper extends OrmLiteSqliteOpenHelper {
private static final String TABLE_NAME = "user.db";
private Dao<UserInfo, Integer> userDao;
public UserDbHelper(Context context) {
super(context, TABLE_NAME, null, 1);
}
@Override
public void onCreate(SQLiteDatabase database, ConnectionSource connectionSource) {
try {
TableUtils.createTable(connectionSource, UserInfo.class);
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void onUpgrade(SQLiteDatabase database, ConnectionSource connectionSource, int oldVersion, int newVersion) {
try {
TableUtils.dropTable(connectionSource, UserInfo.class, true);
onCreate(database, connectionSource);
} catch (Exception e) {
e.printStackTrace();
}
}
private static UserDbHelper instance;
/**
* 单例获取该Helper
*/
public static synchronized UserDbHelper getHelper(Context context) {
if (instance == null) {
synchronized (UserDbHelper.class) {
if (instance == null)
instance = new UserDbHelper(context);
}
}
return instance;
}
/**
* 获得userDao
*/
public Dao<UserInfo, Integer> getUserDao() throws Exception {
if (userDao == null) {
userDao = getDao(UserInfo.class);
}
return userDao;
}
@Override
public void close() {
super.close();
userDao = null;//释放资源
}
}
3.在javabean类里面使用注解标识表结构
有几点要求:
1.有无参构造函数
2.有get() set()方法
3.映射表名 例如: @DatabaseTable(tableName = "t_user")
4.映射表字段 例如:@DatabaseField(columnName = "name")
5.将一个字段指定为为主键,并自增长(一般是_id),这个特殊字段必须是int integer long Uuid类型数据,
配置方式:@DatabaseField(generatedId = true)
/**
* 用户表javabean类
*/
//1.映射表名
@DatabaseTable(tableName = "t_user")
public class UserInfo {
//2.将一个字段指定为主键并自增长(一般是_id)
@DatabaseField(columnName = "_id", generatedId = true)
private Integer id;
//3.映射表字段
@DatabaseField(columnName = "name")
private String name;
@DatabaseField(columnName = "age")
private String age;
//4.有无参构造函数
public UserInfo() {}
//5.有get() set()方法
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
}
4.写对数据库进行CRUD的Dao类
通过数据库帮助类获取Dao类。
泛型解读:Dao<映射表结构的javabean,主键id类型>
Dao<UserInfo, Integer> userDao = new MyOpenHelper(this).getDao(UserInfo.class);
增加记录:
1.创建一条用户记录
UserInfo userInfo = new UserInfo("小明","1");
2.添加到数据库
//添加一条记录
userDao.create(userInfo );
//在表中添加一条记录,如果表不存在这条数据,根据设置的主键来判断是否存在
3.userDao.createOrUpdate(userInfo );
// 在表中添加一条记录,如果存在则更新主键对应的一条记录,
userDao.createIfNotExists(userInfo );
删除记录:
//根据传入id集合删除
userDao.deleteIds(ids);
//根据ID删除
userDao.deleteById(id);
//根据数据实体删除
userDao.delete(user);
//根据集合删除
userDao.delete(list);
更新记录:
//根据传入的实体更新数据,ID为唯一标志
mDao.update(user);
//更新ID,其他值不变
mDao.updateId(new User(mId, mName), 10000);
查询:
//查询所有数据
mDao.queryForAll();
//根据id查询数据
mDao.queryForId(mId);
//组拼sql语句查询数据
例如:dao.queryBuilder().orderBy("age", false).query();
---queryBuilder()创建查询方式,select * from t_address order by age
---orderBy()参数:列名 是否升序
---query():执行查询操作
dao.queryBuilder().where().like("name", "%" + keyword + "%").query();
----select * from table where 1==1 like
----like()参数:列名 通配符
public class UserDao {
private static final String TAG = "UserDao";
private Context context;
Dao<UserInfo, Integer> dao;
public UserDao(Context context) {
this.context = context;
try {
dao = UserDbHelper.getHelper(context).getUserDao();
} catch (Exception e) {
e.printStackTrace();
}
}
//增
public void add(UserInfo user) {
try {
dao.create(user);
} catch (Exception e) {
e.printStackTrace();
}
}
//删,根据用户名删除
public void delete(String name) {
try {
List<UserInfo> list = dao.queryForAll();
for (UserInfo user : list) {
if (name.equals(user.getName())) {
dao.deleteById(user.getId());
Toast.makeText(context, "删除了" + user.getName(), Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(context, "删除错误,查无此人", Toast.LENGTH_SHORT).show();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
//改,根据用户名改年龄
public void update(String name, String newAge) {
try {
List<UserInfo> list = dao.queryForAll();
for (UserInfo user : list) {
if (name.equals(user.getName())) {
user.setAge(newAge);
dao.update(user);
Toast.makeText(context, "将" + name + "的年龄改成了" + newAge, Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(context, "更改错误,查无此人", Toast.LENGTH_SHORT).show();
}
}
} catch (SQLException e) {
e.printStackTrace();
}
}
//查,根据用户名查询
public void find(String name) {
List<UserInfo> list = null;
try {
list = dao.queryForAll();
for (UserInfo user : list) {
if (name.equals(user.getName())) {
Toast.makeText(context, "查到记录,id:" + user.getId() + "--" + user.getName() + "--" + user.getAge(), Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(context, "查无此人", Toast.LENGTH_SHORT).show();
}
}
} catch (SQLException e) {
e.printStackTrace();
}
}
//查询所有记录
public List<UserInfo> findAll() {
try {
List<UserInfo> list = dao.queryForAll();
return list;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}
我们可以采用单元测试来测试我们写的Dao类,为了简单起见,就再此只示例add()方法的测试。
在这里我就不介绍原生的单元测试的操作了,在这里采用测试框架-junit。
单元测试框架-junit
用junit的优势:
不需要在清单文件中配置指令集和测试库
不需要继承谁,只需要用注解标识测试类
testCompile 'junit:junit:4.12'
生成一个类的测试类:可以选中这个类 --Go To---Test,
也可以自己新建,注意格式。
配置你测试类的类名以及测试哪几个方法
第一个是安卓测试,第二个是普通测试,在这里我们选择第一个安卓测试
需要在测试类上写注解:@RunWith(AndroidJUnit4.class)
献上代码:
@RunWith(AndroidJUnit4.class) //写注解
public class UserDaoTest {
private static final String TAG = "UserDaoTest";
@Test
public void add() throws Exception {
//获取当前测试用到的上下文,注意这里不要写成了getContext()了,否则会报打不开数据库的异常了
Context cotext = InstrumentationRegistry.getTargetContext();
UserDao dao = new UserDao(cotext);
dao.add(new UserInfo("小明", "22"));
dao.findAll();
}
}
然后可以选中方法点击右键进行debug模式
同样绿线表示测试没有问题,红线代表出错了。
最后说一句代码没有经过严格的测试,有问题的地方还望见谅并指出。谢谢
嫌弃我代码罗列的比较长的宝宝可以参考我的 moudle示例