文章目录
- 一、OrmLite框架
- 二、案例演示 - 操作教师表
- 四、课后作业
一、OrmLite框架
(一)OrmLite框架概述
安卓采用SQLite作为数据库存储。由于SQLite代码写起来烦琐且容易出错,因此,开源社区逐渐出现了各种ORM(Object Relational Mapping)库。ORM是通过使用描述对象和数据库之间映射(对应关系,如类与表就是类的成员变量和表的列一 一对应,对象与表的行一 一对应)的元数据,将面向对象语言程序中的对象自动持久化到关系数据库中。本质就是将数据从一种形式转换到另一种形式。这些开源ORM 库都是为了方便 Sqlite 的使用而出现的,包括数据库的创建、升级、增/删/改/查等操作。常见的ORM库有 ORMLite(简单)、GreenDAO(高效)等。ORM主要是在Sqlite上提供了一层封装。
(二)OrmLite框架官网
二、案例演示 - 操作教师表
(一)运行效果
(二)涉及知识点
- 线性布局(LinearLayout)
- 按钮(Button)
- OrmLite框架
(三)实现步骤
1、创建安卓应用【OrmLiteDemo】
2、在模块构建文件里添加对OrmLite框架的依赖
dependencies {
implementation fileTree(dir: "libs", include: ["*.jar"])
implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
implementation 'com.j256.ormlite:ormlite-android:5.3'
}
3、创建entity子包,在子包里创建教师实体类 - Teacher
- 教师表(t_teacher)- 包含五个字段
id | name | gender | age | telephone |
---|---|---|---|---|
1 | 李克文 | 男 | 30 | 15890904567 |
2 | 王艳玲 | 女 | 28 | 15896565345 |
3 | 李小刚 | 男 | 34 | 13945673450 |
- 教师实体(Teacher)- 包含五个属性,与教师表五个字段一一对应
- 首先在Teacher类上添加
@DatabaseTable(tableName = "t_teacher")
,通过注解对应数据库中的一张表 - t_userteacher - 然后分别在属性上添加
@DatabaseField(columnName = "XXX")
,columnName的值为该字段在数据表中的列名(字段名) - 注意
@DatabaseField(generatedId = true)
注解,generatedId = true
表示id为主键且自动生成
package net.hw.ormlite_demo.entity;
import com.j256.ormlite.field.DatabaseField;
import com.j256.ormlite.table.DatabaseTable;
/**
* 功能:教师实体类
* 作者:华卫
* 日期:2021年01月17日
*/
@DatabaseTable(tableName = "t_teacher")
public class Teacher {
@DatabaseField(generatedId = true)
private int id;
@DatabaseField(columnName = "name")
private String name;
@DatabaseField(columnName = "gender")
private String gender;
@DatabaseField(columnName = "age")
private int age;
@DatabaseField(columnName = "telephone")
private String telephone;
public Teacher() {
}
public Teacher(int id, String name, String gender, int age, String telephone) {
this.id = id;
this.name = name;
this.gender = gender;
this.age = age;
this.telephone = telephone;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getTelephone() {
return telephone;
}
public void setTelephone(String telephone) {
this.telephone = telephone;
}
@Override
public String toString() {
return "Teacher{" +
"id=" + id +
", name='" + name + '\'' +
", gender='" + gender + '\'' +
", age=" + age +
", telephone='" + telephone + '\'' +
'}';
}
}
4、创建dbutil子包,在子包里创建DBHelper
(1)继承OrmLiteSqliteOpenHelper
- 添加构造方法,实现抽象方法 - onCreate()与onUpgrade()
(2)声明部分
(3)改写构造方法
(4)改写创建回调方法
(5)改写升级回调方法
(6)编写获取数据库助手单例的方法
(7)编写获取Dao的方法
(8)编写释放资源的方法
(9)查看数据库助手类完整源代码
package net.hw.ormlite_demo.dbutil;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import com.j256.ormlite.android.apptools.OrmLiteSqliteOpenHelper;
import com.j256.ormlite.dao.Dao;
import com.j256.ormlite.support.ConnectionSource;
import com.j256.ormlite.table.TableUtils;
import net.hw.ormlite_demo.entity.Teacher;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;
/**
* 功能:数据库助手类
* 作者:华卫
* 日期:2021年01月17日
*/
public class DBHelper extends OrmLiteSqliteOpenHelper {
private static final String DB_NAME = "teaching.db";
private static final int DB_VERSION = 1;
private static DBHelper instance;
private Map<String, Dao> daos = new HashMap<String, Dao>();
/**
* 构造方法
*
* @param context
*/
public DBHelper(Context context) {
super(context, DB_NAME, null, DB_VERSION);
}
/**
* 创建回调方法
*
* @param database
* @param connectionSource
*/
@Override
public void onCreate(SQLiteDatabase database, ConnectionSource connectionSource) {
try {
TableUtils.createTable(connectionSource, Teacher.class);
} catch (SQLException e) {
e.printStackTrace();
}
}
/**
* 升级回调方法
*
* @param database
* @param connectionSource
* @param oldVersion
* @param newVersion
*/
@Override
public void onUpgrade(SQLiteDatabase database, ConnectionSource connectionSource, int oldVersion, int newVersion) {
try {
TableUtils.dropTable(connectionSource, Teacher.class, true);
onCreate(database, connectionSource);
} catch (SQLException e) {
e.printStackTrace();
}
}
/**
* 获取数据库助手类单例
*
* @param context
* @return
*/
public static synchronized DBHelper getHelper(Context context) {
if (instance == null) {
synchronized (DBHelper.class) {
if (instance == null) {
instance = new DBHelper(context);
}
}
}
return instance;
}
/**
* 获取Dao
*
* @param clazz
* @return
* @throws SQLException
*/
public synchronized Dao getDao(Class clazz) {
Dao dao = null;
String className = clazz.getSimpleName();
// 判断Dao池里是否有对应实体类的Dao
if (daos.containsKey(className)) {
dao = daos.get(className);
}
// 从Dao池获取Dao失败
if (dao == null) {
try {
// 获取Dao
dao = super.getDao(clazz);
// 放入Dao池
daos.put(className, dao);
} catch (SQLException e) {
e.printStackTrace();
}
}
return dao;
}
/**
* 释放资源
*/
@Override
public void close() {
super.close();
// 遍历Dao池,释放资源
for (String key : daos.keySet()) {
Dao dao = daos.get(key);
dao = null;
}
}
}
(10)代码说明
- 整个DBHelper使用单例只对外公布出一个对象,保证app中只存在一个SQLite Connection;
- 对每个实体类创建一个XXXDao来处理当前实体类的数据库操作,真正去和数据库打交道的对象,通过上面代码中的getDao(T t)进行获取;
- getDao(T t)为一个泛型方法,会根据传入Class对象进行创建Dao,并且使用一个Map对象 - Dao池 - 来保持所有的Dao对象 ,只有第一次调用时才会去调用底层的getDao()。
5、创建dao子包,在子包里创建教师数据访问对象 - TeacherDao
(1)声明部分
(2)构造方法
(3)创建添加教师方法 - insert(Teacher teacher)
(4)创建按编号查询教师的方法 - findById(int id)
(5)编写查询全部教师的方法 - findAll()
(6)编写更新教师的方法 - update(Teacher teacher)
(7)编写按编号删除教师的方法 - deleteById(int id)
(8)查看教师数据访问对象完整源代码
package net.hw.ormlite_demo.dao;
import android.content.Context;
import android.database.SQLException;
import com.j256.ormlite.dao.Dao;
import net.hw.ormlite_demo.dbutil.DBHelper;
import net.hw.ormlite_demo.entity.Teacher;
import java.util.List;
/**
* 功能:教师数据访问对象
* 作者:华卫
* 日期:2021年01月17日
*/
public class TeacherDao {
private Context context;
private Dao<Teacher, Integer> teacherDao;
private DBHelper helper;
/**
* 构造方法
*
* @param context
*/
public TeacherDao(Context context) {
this.context = context;
try {
// 获取数据库助手实例
helper = DBHelper.getHelper(context);
// 获取教师数据访问对象
teacherDao = helper.getDao(Teacher.class);
} catch (SQLException e) {
e.printStackTrace();
}
}
/**
* 添加教师
*
* @param teacher
* @return 添加记录数
*/
public int insert(Teacher teacher) {
int count = 0;
try {
count = teacherDao.create(teacher);
} catch (java.sql.SQLException e) {
e.printStackTrace();
}
return count;
}
/**
* 按编号获取教师
*
* @param id
* @return 教师对象
*/
public Teacher findById(int id) {
Teacher teacher = null;
try {
teacher = teacherDao.queryForId(id);
} catch (java.sql.SQLException e) {
e.printStackTrace();
}
return teacher;
}
/**
* 查询全部教师
*
* @return 教师列表
*/
public List<Teacher> findAll() {
List<Teacher> teachers = null;
try {
teachers = teacherDao.queryForAll();
} catch (java.sql.SQLException e) {
e.printStackTrace();
}
return teachers;
}
/**
* 更新教师
*
* @param teacher
* @return 更新记录数
*/
public int update(Teacher teacher) {
int count = 0;
try {
count = teacherDao.update(teacher);
} catch (java.sql.SQLException e) {
e.printStackTrace();
}
return count;
}
/**
* 按编号删除教师
*
* @param id
* @return 删除记录数
*/
public int deleteById(int id) {
int count = 0;
try {
count = teacherDao.deleteById(id);
} catch (java.sql.SQLException e) {
e.printStackTrace();
}
return count;
}
}
6、将背景图片拷贝到drawable目录
7、主布局资源文件activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/background"
android:gravity="center"
android:orientation="vertical"
android:padding="10dp"
tools:context=".MainActivity">
<Button
android:id="@+id/btnAddTeacher"
android:layout_width="250dp"
android:layout_height="wrap_content"
android:onClick="doAddTeacher"
android:text="@string/add_teacher"
android:textSize="20sp" />
<Button
android:id="@+id/btnDisplayAllTeachers"
android:layout_width="250dp"
android:layout_height="wrap_content"
android:onClick="doDisplayAllTeachers"
android:text="@string/display_all_teachers"
android:textSize="20sp" />
</LinearLayout>
8、字符串资源文件strings.xml
<resources>
<string name="app_name">OrmLite框架演示</string>
<string name="add_teacher">添加一条教师记录</string>
<string name="display_all_teachers">显示全部教师记录</string>
</resources>
9、主界面类 - MainActivity
(1)声明变量
(2)实例化数据库助手与教师数据访问对象
(3)编写添加一条教师记录按钮单击事件处理方法
(4)编写显示全部教师记录按钮单击事件处理方法
(5)查看主界面类完整源代码
package net.hw.ormlite_demo;
import android.os.Bundle;
import android.view.View;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import net.hw.ormlite_demo.dao.TeacherDao;
import net.hw.ormlite_demo.dbutil.DBHelper;
import net.hw.ormlite_demo.entity.Teacher;
import java.util.List;
/**
* 功能:演示OrmLite框架
* 作者:华卫
* 日期:2021年01月17日
*/
public class MainActivity extends AppCompatActivity {
private DBHelper helper; // 数据库助手
private TeacherDao teacherDao; // 教师数据访问对象
private int id; // 教师编号
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 利用布局资源文件设置用户界面
setContentView(R.layout.activity_main);
// 实例化数据库助手
helper = new DBHelper(this);
// 实例化教师数据访问对象
teacherDao = new TeacherDao(this);
}
/**
* 添加一条教师记录按钮事件处理方法
*
* @param view
*/
public void doAddTeacher(View view) {
Teacher teacher = new Teacher();
id++;
teacher.setName("教师" + id);
String gender = id % 2 == 0 ? "男" : "女";
teacher.setGender(gender);
teacher.setAge((int) (Math.random() * 60));
teacher.setTelephone("158" + (int) (Math.random() * 100000000));
int count = teacherDao.insert(teacher);
if (count > 0) {
Toast.makeText(this, "恭喜,教师记录添加成功!", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this, "遗憾,教师记录添加失败!", Toast.LENGTH_SHORT).show();
}
}
/**
* 显示全部教师记录按钮单击事件处理方法
*
* @param view
*/
public void doDisplayAllTeachers(View view) {
List<Teacher> teachers = teacherDao.findAll();
if (teachers != null) {
StringBuilder builder = new StringBuilder();
builder.append("全部教师记录\n\n");
for (Teacher teacher : teachers) {
String strTeacher = teacher.getId() + " " + teacher.getName() + " " + teacher.getGender()
+ " " + teacher.getAge() + " " + teacher.getTelephone() + "\n";
builder.append(strTeacher);
}
Toast.makeText(this, builder.toString(), Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this, "教师表里没有记录!", Toast.LENGTH_SHORT).show();
}
}
}
10、启动应用,查看效果
四、课后作业
任务1、补充案例演示,增加按编号查询教师、编辑教师和删除教师功能。
任务2、联系人管理
1、继承OrmSqliteOpenHelper创建DBHelper,创建test数据库。
2、创建用户实体类(User)和用户数据访问对象(UserDao)
- 在UserDao里编写增删改查方法
- 创建user表并默认插入两条记录
_id | username | password |
---|---|---|
1 | admin | admin |
2 | howard | 12345 |
3、创建联系人实体类(Contact)和联系人数据访问对象(ContactDao)
- 在ContactDao里编写增删改查方法
- 创建contact表并插入10条记录
_id | name | gender | age | telephone |
---|---|---|---|---|
2020001 | 李小文 | 男 | 18 | 15878786780 |
2020002 | 韩玉玲 | 女 | 20 | 15845678907 |
2020003 | 唐语涵 | 女 | 18 | 13978789089 |
2020004 | 董翔宇 | 男 | 20 | 15823234567 |
2020005 | 郑文佳 | 女 | 18 | 13978781234 |
2020006 | 伍子胥 | 男 | 20 | 15878786780 |
2020007 | 南怀瑾 | 男 | 18 | 13956567862 |
2020008 | 李文华 | 女 | 18 | 15956567845 |
2020009 | 吴文渊 | 男 | 20 | 13978784560 |
2020010 | 陈燕文 | 女 | 18 | 15890903456 |
4、设计登录页面(LoginActivity)并实现功能
(1)设置页面控件属性,标签与按钮的标题,要求所有控件在整个页面居中,效果如下图所示:
(2)在LoginActivity中,通过资源标识获得控件实例
(3)编写【登录】按钮单击事件代码,登录成功则跳转到主窗口(MainActivity见下题),如果登录失败,则弹出错误警告对话框
(4)登录时通过user表取用户名和密码判断
(5)【取消】按钮单击事件处理,退出整个应用程序
(6)【注册】标签单击事件处理,跳转到注册窗口(RegisterActivity,自行设计)
(7)能将注册信息插入到user表
5、实现主窗口(MainActivity)功能
下图是联系人列表,数据是从3题的contact表获取,蓝色和粉色矩形区域显示的是姓名首字母,如果性别为男则为蓝色,如果性别为女则为红色。
(1)页面布局控件的布局正确
(2)能按题意正确显示列表信息
(3)点击里面电话号码能拨号
(4)长按某条记录,弹出上下文菜单
(5)实现上下文菜单的编辑功能
(6)实现上下文菜单的删除功能
(7)点击列表中记录时,显示详情