安卓学习笔记45:初探开源框架OrmLite

文章目录

一、OrmLite框架

(一)OrmLite框架概述

安卓采用SQLite作为数据库存储。由于SQLite代码写起来烦琐且容易出错,因此,开源社区逐渐出现了各种ORM(Object Relational Mapping)库。ORM是通过使用描述对象和数据库之间映射(对应关系,如类与表就是类的成员变量和表的列一 一对应,对象与表的行一 一对应)的元数据,将面向对象语言程序中的对象自动持久化到关系数据库中。本质就是将数据从一种形式转换到另一种形式。这些开源ORM 库都是为了方便 Sqlite 的使用而出现的,包括数据库的创建、升级、增/删/改/查等操作。常见的ORM库有 ORMLite(简单)、GreenDAO(高效)等。ORM主要是在Sqlite上提供了一层封装。
在这里插入图片描述

(二)OrmLite框架官网

二、案例演示 - 操作教师表

(一)运行效果

在这里插入图片描述

(二)涉及知识点

  1. 线性布局(LinearLayout)
  2. 按钮(Button)
  3. 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)代码说明

  1. 整个DBHelper使用单例只对外公布出一个对象,保证app中只存在一个SQLite Connection;
  2. 对每个实体类创建一个XXXDao来处理当前实体类的数据库操作,真正去和数据库打交道的对象,通过上面代码中的getDao(T t)进行获取;
  3. 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)点击列表中记录时,显示详情
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/howard2005/article/details/112727981