Android数据库的使用
前言
对于Android开发开说数据库应该很熟悉了,但是要从实际操作的角度来说,可能未必能够熟练的使用。当然,不是所有的APP都需要使用数据库,因为这个东西确实比较重。但是如果碰到一些特别大的项目尤其是包含即时通讯,消息,频繁的大数据的存储和操作,基本上都会使用数据库,比如:银行类APP,聊天类APP,大型官网的APP。此类型的项目中需要对数据库进行统一封装:数据库的创建,表格创建,数据库的增,删,改,查,以及更新数据库等操作。话不多说,直接从代码的角度去从头开始撸起来!
一、数据库的创建:
1.创建数据库需要借助SQLiteOpenHelper,代码如下:
public class MySqliteOpenHelper extends SQLiteOpenHelper {private String mName="";//数据库名字
创建数据库表的语句,一般写在会放在对应的数据库中(StudentDao) public static final String TBL_FRIEND_CREATE_SQL ="CREATE TABLE IF NOT EXISTS " + STUDENT_TABLE + " (" +STUDENT_ID + " INT64 PRIMARY KEY," +STUDENT_NAME + " TEXT," +STUDENT_CHINESE + " TEXT," +STUDENT_MATH + " TEXT," +STUDENT_ENGLISH + " TEXT," +STUDENT_AGE + " TEXT" + ");";
public static final String[] INIT_ALL_TABLE={UserDao.TBL_USERDAO_CREATE_SQL,FriendDao.TBL_FRIEND_CREATE_SQL,StudentDao.TBL_FRIEND_CREATE_SQL};public MySqliteOpenHelper(@Nullable Context context, @Nullable String name, int version) {super(context, name, null, version);mName=name;}/***在当第一次执行数据库操作的时候会通过SqliteOpenHelper去创建数据库,对应的走onCreate方法。*如果需要新增一个表格,需要将创建表格的语句在onCreate方法里面去执行,如下所示。这个for循环会将需要的表一次性全部创建完毕 /@Overridepublic void onCreate(SQLiteDatabase db) {if (INIT_ALL_TABLE!=null&&INIT_ALL_TABLE.length>0)for (int i = 0; i <INIT_ALL_TABLE.length ; i++) {db.execSQL(INIT_ALL_TABLE[i]);}}/* *这个方法是当数据库中的某个表格需要升级的时候(比如,新增一些字段) *此时需要将数据库的版本号增加一个,通过获取本地数据库的oldVersion和APP中的数据库版本号进行比较 *如果小于当前的版本号,则会走对应的方法,对应的去执行一些语句,插入一些新的字段。如下: */@Overridepublic void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {if (oldVersion==newVersion){return;}if (oldVersion<4){//数据库升级版本为4,此时有表格结构变动,需要更新对应的表格updateDbVersion4(db);}if (oldVersion<5){//数据库升级版本为5,此时有表格结构变动,需要更新对应的表格updateDbVersion5(db);}
private void updateDbVersion4(SQLiteDatabase db) {ArrayList<String> list = updateDbVersionSqlArray4(db);db.beginTransaction();if (list!=null&&list.size()>0){for (int i = 0; i < list.size(); i++) {String sql = list.get(i);db.execSQL(sql);}}db.setTransactionSuccessful();db.endTransaction(); }/*** 数据库版本4.0,user_info_table 表格新增字段 student_chinese 和 student_math*/ private ArrayList<String> updateDbVersionSqlArray4(SQLiteDatabase db) {ArrayList<String> sqlList = new ArrayList<>();try {Cursor cursor = db.query(String.valueOf("sqlite_master"), null, null, null, null, null, null);try {while (cursor.moveToNext()) {if ("table".equals(cursor.getString(cursor.getColumnIndex("type")))) {String tableName = cursor.getString(cursor.getColumnIndex(String.valueOf("name")));if (tableName.equals(StudentDao.STUDENT_TABLE)) {if (!checkColumnExists(db,StudentDao.STUDENT_TABLE,StudentDao.STUDENT_CHINESE)) {String str1 = "ALTER TABLE " + tableName + " ADD COLUMN " + "student_chinese" + " TEXT;";sqlList.add(str1);}if (!checkColumnExists(db,StudentDao.STUDENT_TABLE,StudentDao.STUDENT_MATH)) {String str2 = "ALTER TABLE " + tableName + " ADD COLUMN " + "student_math" + " TEXT;";sqlList.add(str2);}}}}} finally {cursor.close();}} catch (Exception e) {return new ArrayList<String>();}return sqlList; }}
2.SqliteOpenHelper辅助类写好之后,需要使用ContentProvider来创建数据库。
此类是用来存储数据库信息配置的类:public class DBConstants {/*** 数据库的名字,LK+“用户的账号”+DB 拼接成的,如果切换账号则会生成新的数据库。不同的账号之间的数据绝对隔离,故称之为私库。*/public static final String DB_NAME = "LK%sDB.db";/*** 数据库升级为版本4 StudentDao新增语文Chinese 数学Math字段*/public static final int DB_VERSION=4;}
/*** 1.核心:此类继承ContentProvider,在此类中进行数据库的创建,以及实现数据库的 增,删,改,查,替换,批量操作。* 2.此处实现的数据库表格的 增,删,改,查,批量操作等方法并非直接使用。而是通过contentRelsover去操作,* 内部会进一步的调用此类中对应的方法。* 3."com.example.mydbproject.liukang"是MyContentProvider唯一标识(这个类对应的唯一数据库),不允许重复,并且需要注册才能使用。* <provider* android:authorities="com.example.mydbproject.liukang"* android:name=".help.MyContentProvider"* android:enabled="true"* android:exported="false"/>**/ public class MyContentProvider extends ContentProvider {public static final String AUTHORITY = "content://com.example.mydbproject.liukang/";public static final String AUTHORITY_APPLY = "com.example.mydbproject.liukang";//这个是唯一标识,注册的时候需要使用public static final String URI_RAWQUERY = "content://com.example.mydbproject.liukang/defined/action/rawQuery";public static final String URI_EXECSQL = "content://com.example.mydbproject.liukang/defined/action/execSql";Object mLock = new Object();MySqliteOpenHelper mySqliteOpenHelper;String mUserId = "";@Overridepublic boolean onCreate() {return initHelper();}private boolean initHelper() {synchronized (mLock) {if (mySqliteOpenHelper != null) {mySqliteOpenHelper.close();}mUserId = getUserId();String name = String.format(DBConstants.DB_NAME, mUserId);mySqliteOpenHelper = new MySqliteOpenHelper(getContext(),name,DBConstants.DB_VERSION);return true;}}public SQLiteDatabase getWritableDatabase() {if (mySqliteOpenHelper != null) {if (!mUserId.equals(getUserId())) {initHelper();}SQLiteDatabase writableDatabase = mySqliteOpenHelper.getWritableDatabase();return writableDatabase;}return null;}/*** 查询操作* @param uri 1:URI_RAWQUERY则直接用db执行查询的sql语句 (sql语句已经包含了条件)* 2:AUTHORITY+“table_name”此时直接根据条件查询* @param projection* @param selection* @param selectionArgs* @param sortOrder* @return*/@Nullable@Overridepublic Cursor query(@NonNull Uri uri, @Nullable String[] projection, @Nullable String selection, @Nullable String[] selectionArgs, @Nullable String sortOrder) {String tableName = getTableName(uri);SQLiteDatabase db = getWritableDatabase();if (db == null) {return null;}if (uri.equals(Uri.parse(URI_RAWQUERY))) {//URI_RAWQUERY则直接用db执行查询的sql语句Cursor cursor = db.rawQuery(selection, selectionArgs);return cursor;}if (TextUtils.isEmpty(tableName)) {return null;}//直接根据条件查询Cursor cursor = db.query(tableName, projection, selection, selectionArgs, null, null, sortOrder, null);return cursor;}@Nullable@Overridepublic String getType(@NonNull Uri uri) {return null;}/*** 插入新数据操作* @param uri* @param values* @return*/@Nullable@Overridepublic Uri insert(@NonNull Uri uri, @Nullable ContentValues values) {String tableName = getTableName(uri);SQLiteDatabase db = getWritableDatabase();if (db == null || TextUtils.isEmpty(tableName)) {return null;}long insertId = db.insert(tableName, null, values);if (insertId == -1) {//失败Log.e("TAGS", tableName + ":" + "insert:" + insertId);return null;}//成功是一个大于0的数===size 失败是-1Log.e("TAGS", tableName + ":" + "insert:" + insertId);return ContentUris.withAppendedId(uri, insertId);}/*** 删除一条新数据 1:如果uri为 MyContentProvider.URI_EXECSQL则执行sql语句即可(可以是增,删,改)* 2:如果不是则根据表格以及条件进行某条数据的删除* @param uri* @param selection* @param selectionArgs* @return*/@Overridepublic int delete(@NonNull Uri uri, @Nullable String selection, @Nullable String[] selectionArgs) {SQLiteDatabase db = getWritableDatabase();if (db == null) {return 0;}if (uri.equals(Uri.parse(MyContentProvider.URI_EXECSQL))) {db.execSQL(selection);return 1;} else {String tableName = getTableName(uri);if (TextUtils.isEmpty(tableName)) {return 0;}int delete = db.delete(tableName, selection, selectionArgs);//失败是0 成功是1Log.e("TAGS", tableName + ":" + "delete:" + delete);return delete;}}/*** 更新操作: 1.如果uri是包含replace,对应的操作是 存在则更新,不存在则新增* 2.如果不包含replace,则执行更新操作* @param uri* @param values* @param selection* @param selectionArgs* @return*/@Overridepublic int update(@NonNull Uri uri, @Nullable ContentValues values, @Nullable String selection, @Nullable String[] selectionArgs) {String tableName = getTableName(uri);SQLiteDatabase db = getWritableDatabase();if (db == null || TextUtils.isEmpty(tableName)) {return 0;}//成功是1 失败是0int update = db.update(tableName, values, selection, selectionArgs);if (update == 0) {if (getReplace(uri)) {long insertId = db.insert(tableName, null, values);Log.e("TAGS", tableName + ":" + "update:__insert:" + insertId);return 1;} else {return 0;}}Log.e("TAGS", tableName + ":" + "update:" + update);return update;}/*** 获取当前账号的唯一标识,userId。* @return*/public String getUserId() {String user_id = AccountManager.getAccountId(getContext());return user_id;}/*** 根据uri操作表示来获取表格名称*MyContentProvider.AUTHORITY+ “student_table”* MyContentProvider.AUTHORITY+ “place/student_table” 替换操作* @param uri* @return*/public String getTableName(Uri uri) {List<String> pathSegments = uri.getPathSegments();if (pathSegments != null && pathSegments.size() == 1) {return pathSegments.get(0);} else if (pathSegments != null && pathSegments.size() == 2) {return pathSegments.get(1);} else {return "";}}/*** 判断是不是替换的操作* @param uri* @return*/public boolean getReplace(Uri uri) {List<String> pathSegments = uri.getPathSegments();if (pathSegments != null && pathSegments.size() == 2) {String placeStr = pathSegments.get(0);if (!TextUtils.isEmpty(placeStr) && placeStr.equals("place")) {return true;}return false;} else {return false;}}/*** 批量操作* 如果一次性插入或者查询多条数据可以使用此方法,性能好* @param operations* @return* @throws OperationApplicationException*/@NonNull@Overridepublic ContentProviderResult[] applyBatch(ArrayList<ContentProviderOperation> operations)throws OperationApplicationException {SQLiteDatabase db = getWritableDatabase();if (db == null) {return null;}ContentProviderResult[] results = new ContentProviderResult[operations.size()];db.beginTransaction();try {results = super.applyBatch(operations);db.setTransactionSuccessful();} catch (Exception e) {e.printStackTrace(); //NOSONARresults = null;} finally {db.endTransaction();}return results;} }
二.创建数据表:
1.的基类操作方法
/*** 所有数据库表格的基类,* 1:通过ContentValues,进行增,删,改,查* 2:通过sql语句进行增,删,改,查* 3.当新增某个数据库操作可以继承该类。如果需要执行某个操作,只需要对应的调用对应方法并传入相关参数即可。* (可参考StudentDao)*/ public abstract class BaseDao {/*** 单个插入一条数据* @param tableName 表名称* @param contentValues 将插入的数据封装为ContentValues进行插入(key,value)*/public void insertValue(String tableName, ContentValues contentValues) {MyApplication.getContext().getContentResolver().insert(getUri(tableName), contentValues);}/*** 删除单个数据* @param tableName 表名称* @param selection 查找的条件字段* @param selectionArgs 字段条件字段对应的值*/public void deleteValue(String tableName, String selection, String[] selectionArgs) {MyApplication.getContext().getContentResolver().delete(getUri(tableName), selection, selectionArgs);}/*** 更新一条数据* @param tableName 表名称* @param values 插入的ContentValues* @param selection 查找的条件字段* @param selectionArgs 字段条件字段对应的值*/public void updateValue(String tableName, ContentValues values, String selection, String[] selectionArgs) {MyApplication.getContext().getContentResolver().update(getUri(tableName), values, selection, selectionArgs);}/*** 查询数据* @param tableName 表名称* @param cloum 想要查询的哪个字段 null则是所有* @param selection 查找的条件字段* @param selectionArgs 字段条件字段对应的值* @param sortOrder 排序*/public Cursor queryValue(String tableName, String[] cloum, String selection, String[] selectionArgs, String sortOrder) {return MyApplication.getContext().getContentResolver().query(getUri(tableName), cloum,selection,selectionArgs,sortOrder);}/*** 替换一条数据(有则更新,无则插入)使用的是这个Uri:getReplaceUri(tableName)* getContentResolver().update() ==> MyContentProvider.update() 根据Uri区分:update or replace* @param tableName* @param values* @param selection* @param selectionArgs*/public void replaceValue(String tableName, ContentValues values, String selection, String[] selectionArgs) {MyApplication.getContext().getContentResolver().update(getReplaceUri(tableName), values, selection, selectionArgs);}/*** 批量操作数据(增,删,改)* @param authority* @param operations:此集合中包含ContentProviderOperation类* ContentProviderOperation可以理解为封装的sql语句* 一个集合里面可以是(增 删 改)共同组成的集合* @return*/public ContentProviderResult[] applyBatch(String authority, ArrayList<ContentProviderOperation> operations) {try {return MyApplication.getContext().getContentResolver().applyBatch(authority, operations);} catch (Exception e) {e.printStackTrace(); //NOSONAR}return null;}/*** 直接sql语句执行查询 注意Uri是这个哦:getRawQueryUri()* getContentResolver().query()===>对应的MyContentProvider.query()* ==>对应的MyContentProvider会根据Uri区分是直接执行sql语句,还是使用传过来的条件* @param sql* @param selectionArgs* @return*/public Cursor querySql(String sql,String[] selectionArgs){return MyApplication.getContext().getContentResolver().query(getRawQueryUri(),null,sql,selectionArgs,null);}/*** 直接执行sql语句进行 增 删 改操作 ( 注意使用的是uri:getExecSqlUri())* getContentResolver().delete()===>对应的MyContentProvider.delete()* * ==>对应的MyContentProvider会根据Uri区分是直接执行sql语句(增 删 改)* ,还是使用传过来的条件进行删除操作* @param sql*/public void execSql(String sql){MyApplication.getContext().getContentResolver().delete(getExecSqlUri(),sql,null);}/*** AUTHORITY+表名称,MyContentProvider会使用传过来的条件进行 增 删 改 查 操作* @param tableName* @return*/public Uri getUri(String tableName) {return Uri.parse(MyContentProvider.AUTHORITY + tableName);}/***含有replace: MyContentProvider会使用传过来的条件进行替换操作(无则插入,有则替换)* @param tableName* @return*/public Uri getReplaceUri(String tableName) {return Uri.parse(MyContentProvider.AUTHORITY +"replace/"+ tableName);}/*** 获取getRawQueryUri():直接执行sql查询的Uri表示* @return*/public Uri getRawQueryUri(){return Uri.parse(MyContentProvider.URI_RAWQUERY);}/*** getExecSqlUri():直接执行sql语句的表示:增 删 改* @return*/public Uri getExecSqlUri(){return Uri.parse(MyContentProvider.URI_EXECSQL);}}
2.举个例子:学生表:StudentDao 主键为:student_id(唯一)
/*** 增删改查替换,只要对应的调用方法即可* sql:如果是直接执行相关的sql语句则需要对一些表达式有所了解才行* newInsertMessageOperation:批量插入,删除,替换返回的ContentProviderOperation,实际上就* 是对增 删 改 替的语句的封装,然后组成集合,调用applyBatch()方法开启数据库事务进行遍历操作* 进一步的实际上还是调用 增 删 改*/ public class StudentDao extends BaseDao {StudentBean studentBean = null;private static StudentDao mInstance;public static String STUDENT_TABLE = "student_table";public static String STUDENT_ID = "student_id";public static String STUDENT_NAME = "student_name";public static String STUDENT_AGE = "student_age";public static String STUDENT_CHINESE = "student_chinese";public static String STUDENT_MATH = "student_math";public static String STUDENT_ENGLISH = "student_english";public static final String TBL_FRIEND_CREATE_SQL ="CREATE TABLE IF NOT EXISTS " + STUDENT_TABLE + " (" +STUDENT_ID + " INT64 PRIMARY KEY," +STUDENT_NAME + " TEXT," +STUDENT_CHINESE + " TEXT," +STUDENT_MATH + " TEXT," +STUDENT_ENGLISH + " TEXT," +STUDENT_AGE + " TEXT" + ");";public static StudentDao getInstance() {if (mInstance == null) {mInstance = new StudentDao();}return mInstance;}/*** 插入一条数据*/public void insert(StudentBean student) {ContentValues contentValues = getContentValues(student);super.insertValue(STUDENT_TABLE, contentValues);}/*** 删除一条数据*/public void delete(String studentId) {if (TextUtils.isEmpty(studentId)) {return;}String selection = STUDENT_ID + " = ?";super.deleteValue(STUDENT_TABLE, selection, new String[]{studentId});}/*** 删除一条数据*/public void deleteAll() {super.deleteValue(STUDENT_TABLE, null, null);}/*** 更新一条数据*/public void update(StudentBean studentBean) {ContentValues contentValues = getContentValues(studentBean);String selection = STUDENT_ID + " = ?";super.updateValue(STUDENT_TABLE, contentValues, selection, new String[]{String.valueOf(studentBean.getStudentId())});}/*** 根据studentId查询单条数据** @param studentId* @return*/public StudentBean queryItem(String studentId) {String selection = STUDENT_ID + " = ?";Cursor cursor = super.queryValue(STUDENT_TABLE, null, selection, new String[]{studentId}, null);try {while (cursor != null && cursor.moveToNext()) {StudentBean studentBean = initStudentBean(cursor);return studentBean;}return null;} catch (Exception e) {return null;} finally {cursor.close();}}/*** 更新一条数据*/public void replace(StudentBean studentBean) {ContentValues contentValues = getContentValues(studentBean);String selection = STUDENT_ID + " = ?";super.replaceValue(STUDENT_TABLE, contentValues, selection, new String[]{String.valueOf(studentBean.getStudentId())});}/*** 根据表中所有的学生信息** @param* @return*/public List<StudentBean> queryAll() {List<StudentBean> list = new ArrayList<>();Cursor cursor = super.queryValue(STUDENT_TABLE, null, null, null, null);try {while (cursor != null && cursor.moveToNext()) {StudentBean studentBean = initStudentBean(cursor);list.add(studentBean);}return list;} catch (Exception e) {return null;} finally {cursor.close();}}/*** 统一修改,对于英语成绩超过95分的学生,语文成绩和数学分别扣除1分*/public void updateStudentChinese() {String sql = " update " + STUDENT_TABLE + " set student_chinese = student_chinese -1 , student_math = student_math -1 where " + STUDENT_ENGLISH + " >=95";super.execSql(sql);}/*** 查询* 英语成绩由高到低,查询所有的数据* limit 3:查询前三条数据* limit 2,10 查询从index=2(第三条数据开始的算起,共10条数据:【3,12】)*/public List<StudentBean> querySql1() {String querySql = "select * from " + STUDENT_TABLE + " order by student_english desc limit 3";Cursor cursor = super.querySql(querySql, null);List<StudentBean> list = new ArrayList<>();try {while (cursor != null && cursor.moveToNext()) {StudentBean studentBean = initStudentBean(cursor);list.add(studentBean);}return list;} catch (Exception e) {return null;} finally {cursor.close();}}/*** 插入语句* 创建ContentProviderOperation对象*/public ContentProviderOperation newInsertMessageOperation(StudentBean studentBean) {ContentValues contentValues = getContentValues(studentBean);ContentProviderOperation operation = ContentProviderOperation.newInsert(getUri(STUDENT_TABLE)).withValues(contentValues).build();return operation;}/*** 删除语句* 创建ContentProviderOperation对象*/public ContentProviderOperation newDeleteMessageOperation(String studentId) {String selection = STUDENT_ID + " = ?";String[] selectionValue = new String[]{studentId};ContentProviderOperation operation = ContentProviderOperation.newDelete(getUri(STUDENT_TABLE)).withSelection(selection, selectionValue).build();return operation;}/*** 更新语句* 创建ContentProviderOperation对象*/public ContentProviderOperation newUpdateMessageOperation(String studentId, StudentBean studentBean) {String selection = STUDENT_ID + " = ?";String[] selectionValue = new String[]{studentId};ContentValues contentValues = getContentValues(studentBean);ContentProviderOperation operation = ContentProviderOperation.newUpdate(getUri(STUDENT_TABLE)).withSelection(selection, selectionValue).withValues(contentValues).build();return operation;}/*** 替换语句* 创建ContentProviderOperation对象*/public ContentProviderOperation newReplaceMessageOperation(String studentId, StudentBean studentBean) {String selection = STUDENT_ID + " = ?";String[] selectionValue = new String[]{studentId};ContentValues contentValues = getContentValues(studentBean);ContentProviderOperation operation = ContentProviderOperation.newUpdate(getReplaceUri(STUDENT_TABLE)).withSelection(selection, selectionValue).withValues(contentValues).build();return operation;}private StudentBean initStudentBean(Cursor cursor) {studentBean = new StudentBean();studentBean.setStudentId(cursor.getInt(cursor.getColumnIndex(STUDENT_ID)));studentBean.setName(cursor.getString(cursor.getColumnIndex(STUDENT_NAME)));studentBean.setAge(cursor.getString(cursor.getColumnIndex(STUDENT_AGE)));studentBean.setChinese(cursor.getString(cursor.getColumnIndex(STUDENT_CHINESE)));studentBean.setMath(cursor.getString(cursor.getColumnIndex(STUDENT_MATH)));studentBean.setEnglish(cursor.getString(cursor.getColumnIndex(STUDENT_ENGLISH)));return studentBean;}public ContentValues getContentValues(StudentBean student) {if (student == null) {return null;}ContentValues contentValues = new ContentValues();contentValues.put(STUDENT_ID, student.getStudentId());contentValues.put(STUDENT_NAME, student.getName());contentValues.put(STUDENT_AGE, student.getAge());contentValues.put(STUDENT_CHINESE, student.getChinese());contentValues.put(STUDENT_MATH, student.getMath());contentValues.put(STUDENT_ENGLISH, student.getEnglish());return contentValues;}}
三:Demo使用StudentDao
1.模拟登录账号,主要是创建数据库用到userId
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"tools:context=".MainActivity"><TextViewandroid:layout_width="match_parent"android:layout_height="wrap_content"android:padding="20dp"android:text="登录,请输入账号密码"android:background="#E0EBF0"android:textSize="30sp"/><EditTextandroid:id="@+id/user_name"android:layout_width="match_parent"android:layout_height="wrap_content"android:padding="10dp"android:background="#EBCCD6"android:layout_marginTop="100dp"android:layout_marginLeft="20dp"android:layout_marginRight="20dp"android:textSize="20sp"android:inputType="number"android:hint="请输入账号"/><EditTextandroid:layout_marginTop="30dp"android:id="@+id/user_psw"android:layout_width="match_parent"android:layout_margin="20dp"android:layout_height="wrap_content"android:padding="10dp"android:textSize="20sp"android:background="#EBCCD6"android:hint="请输入密码"/><TextViewandroid:id="@+id/bt_login"android:layout_width="match_parent"android:layout_height="wrap_content"android:padding="10dp"android:text="登录"android:background="#C2F8C4"android:gravity="center"android:layout_marginTop="20dp"android:textSize="22sp"/></LinearLayout>
对应的java:
public class MainActivity extends AppCompatActivity {private EditText et_userName;private EditText et_userPsw;private TextView tv_login;Activity activity;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);activity = this;et_userName = findViewById(R.id.user_name);et_userPsw = findViewById(R.id.user_psw);tv_login = findViewById(R.id.bt_login);tv_login.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {String userName = et_userName.getText().toString().trim();String userPsw = et_userPsw.getText().toString().trim();if (TextUtils.isEmpty(userName) || userName.length() != 11) {MyToast.showToast(activity, "请输入正确的账号");return;}if (TextUtils.isEmpty(userPsw) || !userPsw.equals("1111")) {MyToast.showToast(activity, "请输入正确的密码");return;}AccountManager.setAccountId(activity, userName);activity.startActivity(new Intent(activity, StudentActivity.class));}});}}
2.学生表格的操作
xml布局:
<?xml version="1.0" encoding="utf-8"?> <ScrollView xmlns:android="http://schemas.android.com/apk/res/android"android:orientation="vertical"android:layout_width="match_parent"android:layout_height="match_parent"><LinearLayoutandroid:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"> <TextViewandroid:layout_width="match_parent"android:layout_height="wrap_content"android:padding="10dp"android:text="学生表数据库"android:textSize="22sp"android:textStyle="bold"android:gravity="center"/><EditTextandroid:layout_marginTop="20dp"android:id="@+id/et_student_id"android:layout_width="match_parent"android:layout_height="wrap_content"android:padding="10dp"android:hint="请输入学生编号"android:textSize="20sp"android:background="#F5D1D1"/><EditTextandroid:id="@+id/et_student_name"android:layout_marginTop="20dp"android:layout_width="match_parent"android:layout_height="wrap_content"android:padding="10dp"android:hint="请输入学生姓名"android:textSize="20sp"android:background="#E0ECF5"/><EditTextandroid:id="@+id/et_student_age"android:layout_marginTop="20dp"android:layout_width="match_parent"android:layout_height="wrap_content"android:padding="10dp"android:hint="请输入学生年龄"android:textSize="20sp"android:background="#F0D6CD"/><EditTextandroid:id="@+id/et_student_chinese"android:layout_marginTop="20dp"android:layout_width="match_parent"android:layout_height="wrap_content"android:padding="10dp"android:hint="请输入学生语文成绩"android:textSize="20sp"android:background="#D8ECEE"/><EditTextandroid:id="@+id/et_student_math"android:layout_marginTop="20dp"android:layout_width="match_parent"android:layout_height="wrap_content"android:padding="10dp"android:hint="请输入数学成绩"android:textSize="20sp"android:background="#F5E4EA"/><EditTextandroid:layout_marginTop="20dp"android:id="@+id/et_student_english"android:layout_width="match_parent"android:layout_height="wrap_content"android:padding="10dp"android:hint="请输入英语成绩"android:textSize="20sp"android:background="#F5D1D1"/><TextViewandroid:id="@+id/insert"android:layout_marginTop="10dp"android:layout_width="match_parent"android:layout_height="wrap_content"android:padding="10dp"android:text="新增一条数据"android:textSize="20sp"android:textStyle="bold"android:textColor="#4056D3"android:gravity="center"android:background="#BFD8DB"/><TextViewandroid:id="@+id/delete"android:layout_marginTop="10dp"android:layout_width="match_parent"android:layout_height="wrap_content"android:padding="10dp"android:text="删除一条数据"android:textSize="20sp"android:textStyle="bold"android:textColor="#4056D3"android:gravity="center"android:background="#BFD8DB"/><TextViewandroid:id="@+id/update"android:layout_marginTop="10dp"android:layout_width="match_parent"android:layout_height="wrap_content"android:padding="10dp"android:text="更新一条数据"android:textSize="20sp"android:textStyle="bold"android:textColor="#4056D3"android:gravity="center"android:background="#BFD8DB"/><TextViewandroid:id="@+id/query"android:layout_marginTop="10dp"android:layout_width="match_parent"android:layout_height="wrap_content"android:padding="10dp"android:text="查询一条数据"android:textSize="20sp"android:textStyle="bold"android:textColor="#4056D3"android:gravity="center"android:background="#BFD8DB"/><TextViewandroid:id="@+id/query_all"android:layout_marginTop="10dp"android:layout_width="match_parent"android:layout_height="wrap_content"android:padding="10dp"android:text="查询所有数据"android:textSize="20sp"android:textStyle="bold"android:textColor="#4056D3"android:gravity="center"android:background="#F8D0DE"/><TextViewandroid:id="@+id/replace"android:layout_marginTop="10dp"android:layout_width="match_parent"android:layout_height="wrap_content"android:padding="10dp"android:text="替换一条数据"android:textSize="20sp"android:textStyle="bold"android:textColor="#4056D3"android:gravity="center"android:background="#E7DECF"/><TextViewandroid:id="@+id/apply_replace"android:layout_marginTop="10dp"android:layout_width="match_parent"android:layout_height="wrap_content"android:padding="10dp"android:text="批量替换"android:textSize="20sp"android:textStyle="bold"android:textColor="#4056D3"android:gravity="center"android:background="#E7DECF"/><TextViewandroid:id="@+id/delete_all"android:layout_marginTop="10dp"android:layout_width="match_parent"android:layout_height="wrap_content"android:padding="10dp"android:text="批量删除"android:textSize="20sp"android:textStyle="bold"android:textColor="#4056D3"android:gravity="center"android:background="#E7DECF"/><TextViewandroid:id="@+id/tv_update_sql"android:layout_marginTop="10dp"android:layout_width="match_parent"android:layout_height="wrap_content"android:padding="10dp"android:text="sql语句更新"android:textSize="20sp"android:textStyle="bold"android:textColor="#4056D3"android:gravity="center"android:background="#E7DECF"/><TextViewandroid:id="@+id/tv_query_sql_1"android:layout_marginTop="10dp"android:layout_width="match_parent"android:layout_height="wrap_content"android:padding="10dp"android:text="sql语句查询"android:textSize="20sp"android:textStyle="bold"android:textColor="#4056D3"android:gravity="center"android:background="#E7DECF"/></LinearLayout> </ScrollView>
Java代码:
public class StudentActivity extends Activity {EditText etStudentId;EditText etStudentName;EditText etStudentAge;EditText etStudentChinese;EditText etStudentMath;EditText etStudentEnglish;TextView tvInsert;TextView tvDelete;TextView tvUpdate;TextView tvQuery;TextView tvQueryAll;TextView tvPlace;TextView tvapplyReplace;TextView tvDeleteAll;TextView tvUpdateSql;TextView tvQuerySql1;String studentId;String studentName;String studentAge;String studentChinese;String studentMath;String studentEnglish;Activity activity;@Overrideprotected void onCreate(@Nullable Bundle savedInstanceState) {super.onCreate(savedInstanceState);activity = this;setContentView(R.layout.activity_student);etStudentId = findViewById(R.id.et_student_id);etStudentName = findViewById(R.id.et_student_name);etStudentAge = findViewById(R.id.et_student_age);etStudentChinese = findViewById(R.id.et_student_chinese);etStudentMath = findViewById(R.id.et_student_math);etStudentEnglish = findViewById(R.id.et_student_english);tvInsert = findViewById(R.id.insert);tvDelete = findViewById(R.id.delete);tvUpdate = findViewById(R.id.update);tvQuery = findViewById(R.id.query);tvQueryAll = findViewById(R.id.query_all);tvPlace = findViewById(R.id.replace);tvapplyReplace = findViewById(R.id.apply_replace);tvDeleteAll = findViewById(R.id.delete_all);tvUpdateSql = findViewById(R.id.tv_update_sql);tvQuerySql1 = findViewById(R.id.tv_query_sql_1);/*** 插入一个学生信息*/tvInsert.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {getData();if (CheckId() && CheckStudentName() && CheckStudentAge()) {StudentBean studentBean = new StudentBean();studentBean.setStudentId(Integer.valueOf(studentId));studentBean.setName(studentName);studentBean.setAge(studentAge);studentBean.setChinese(studentChinese);studentBean.setMath(studentMath);studentBean.setEnglish(studentEnglish);StudentDao.getInstance().insert(studentBean);}}});/*** 根据UserId删除一个学生信息*/tvDelete.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {getData();StudentDao.getInstance().delete(studentId);}});/*** 根据UserId修改一条数据信息*/tvUpdate.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {getData();StudentBean studentBean = new StudentBean();studentBean.setStudentId(Integer.valueOf(studentId));studentBean.setName(studentName);studentBean.setAge(studentAge);studentBean.setChinese(studentChinese);studentBean.setMath(studentMath);studentBean.setEnglish(studentEnglish);StudentDao.getInstance().update(studentBean);}});/*** 根据UserId查询一条数据信息*/tvQuery.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {getData();if (CheckId()) {StudentBean studentBean = StudentDao.getInstance().queryItem(studentId);Log.e("TAGS", "query:" + studentId + ":::" + getString(studentBean));} else {MyToast.showToast(activity, "请输入学生证编号");}}});/*** 查询学生表的所有数据*/tvQueryAll.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {getData();List<StudentBean> list = StudentDao.getInstance().queryAll();if (list != null && list.size() > 0) {for (int i = 0; i < list.size(); i++) {StudentBean studentBean = list.get(i);Log.e("TAGS", "query_all:::" + getString(studentBean));}}}});/*** 根据UserId去替换一条数据(如果不存在则直接插入)*/tvPlace.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {getData();StudentBean studentBean = new StudentBean();studentBean.setStudentId(Integer.valueOf(studentId));studentBean.setName(studentName);studentBean.setAge(studentAge);studentBean.setChinese(studentChinese);studentBean.setMath(studentMath);studentBean.setEnglish(studentEnglish);StudentDao.getInstance().replace(studentBean);}});/*** 批量插入* 将newInsertMessageOperation换成newReplaceMessageOperation则是批量替换*/tvapplyReplace.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {Random random = new Random();ArrayList<ContentProviderOperation> operationList = new ArrayList<>();for (int i = 100; i < 110; i++) {StudentBean studentBean = new StudentBean();studentBean.setStudentId(i);studentBean.setName("liukang" + i);studentBean.setAge(random.nextInt(10) + 90 + "");studentBean.setChinese(random.nextInt(10) + 90 + "");studentBean.setMath(random.nextInt(10) + 90 + "");studentBean.setEnglish(random.nextInt(10) + 90 + "");operationList.add(StudentDao.getInstance().newInsertMessageOperation(studentBean));}StudentDao.getInstance().applyBatch(MyContentProvider.AUTHORITY_APPLY, operationList);}});/*** 删除表中所有的数据*/tvDeleteAll.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {StudentDao.getInstance().deleteAll();}});/*** 编写sql语句进行更新操作*/tvUpdateSql.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {StudentDao.getInstance().updateStudentChinese();}});/***编写sql进行查询操作*/tvQuerySql1.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {StudentDao.getInstance().querySql1();List<StudentBean> list = StudentDao.getInstance().querySql1();if (list != null && list.size() > 0) {for (int i = 0; i < list.size(); i++) {StudentBean studentBean = list.get(i);Log.e("TAGS", "query_all:::" + getString(studentBean));}}}});}public void getData() {studentId = etStudentId.getText().toString().trim();studentName = etStudentName.getText().toString().trim();studentAge = etStudentAge.getText().toString().trim();studentChinese = etStudentChinese.getText().toString().trim();studentMath = etStudentMath.getText().toString().trim();studentEnglish = etStudentEnglish.getText().toString().trim();}public boolean CheckId() {if (!TextUtils.isEmpty(studentId)) {return true;}return false;}public boolean CheckStudentName() {if (!TextUtils.isEmpty(studentName)) {return true;}return false;}public boolean CheckStudentAge() {if (!TextUtils.isEmpty(studentAge)) {return true;}return false;}public String getString(StudentBean bean) {Gson gson = new Gson();String s = gson.toJson(bean);return s;} }
public class StudentBean {private int studentId;private String name;private String age;private String Chinese;private String Math;private String English;public String getName() {return name;}public void setName(String name) {this.name = name;}public int getStudentId() {return studentId;}public void setStudentId(int studentId) {this.studentId = studentId;}public String getAge() {return age;}public void setAge(String age) {this.age = age;}public String getChinese() {return Chinese;}public void setChinese(String chinese) {Chinese = chinese;}public String getMath() {return Math;}public void setMath(String math) {Math = math;}public String getEnglish() {return English;}public void setEnglish(String english) {English = english;} }
总结:
1.常用的存储:
sharePrefrence:一般存储简单的数据,比如开关,标识。以xml形式进行存储的,当清除缓存或者卸载时,会相应的清除掉。
数据库:一般存储在data\data\包名\db 目录下,清缓存或者卸载也会被清楚
文件存储:如果是手机内存则同上,如果是SD卡里面则不会跟随清除(Q涉及到沙箱)
网络缓存:上传,下载。
2.数据库知识点: a 数据库的创建,更新 b 基类封装 :增 删 改 查 替换 批量操作 以及sql语句
3,内容太长了,复制下来直接运行,将这个几个操作捋一遍基本OK
Android数据库的使用相关推荐
- 转载-Android数据库高手秘籍(一)——SQLite命令
原文地址: http://blog.csdn.net/guolin_blog/article/details/38461239 Android数据库高手秘籍(一)--SQLite命令 分类: And ...
- Android源码开发笔记 -- Android数据库,屏幕休眠时间
1. Android数据库问题(以下描述引用及参考http://blog.csdn.net/yin1031468524/article/details/71512996) 在Android7.0之后, ...
- Android数据库专家秘籍(七)经验LitePal查询艺术
转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/40153833 经过了多篇文章的学习,我们已经把LitePal中的绝大部分内容都掌握 ...
- Android数据库高手秘籍(三)——使用LitePal升级表
转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/39151617 在上一篇文章中,我们学习了LitePal的基本使用方法,体验了使用框 ...
- Android 数据库基本操作-2
这个例子实现了一个完整的数据库操作示例.首先运行项目,初始化数据库(创建数据库.创建表):然后点击左方向键向表中插入一条数据,按右方向键删除一条数据,按数字键1修改表中指定的一条数据,数字键2可以删除 ...
- Android 数据库框架ormlite 使用精要
Android 数据库框架ormlite 使用精要 前言 本篇博客记录一下笔者在实际开发中使用到的一个数据库框架,这个可以让我们快速实现数据库操作,避免频繁手写sql,提高我们的开发效率,减少出错的机 ...
- Android数据库LitePal的存储操作
本文属于转载,在此声明,出处:http://blog.csdn.net/guolin_blog/article/details/38556989 并且感谢guolin分享了这么精彩的博文.以下正文: ...
- Android数据库高手秘籍(二):创建表和LitePal的基本用法
原文:http://blog.jobbole.com/77157/ 上一篇文章中我们学习了一些Android数据库相关的基础知识,和几个颇为有用的SQLite命令,都是直接在命令行操作的.但是我们都知 ...
- Android数据库高手秘籍(一)——SQLite命令
转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/38461239 要想熟练地操作任何一个数据库,最最基本的要求就是要懂SQL语言,这也 ...
- android litepal可以指定存储目录吗,Android数据库LitePal的基本用法详解
前言 正好项目用了这种数据存储方式,特地写一篇加深印象,在我看来,LitePal是使用最简单,集成最方便的数据库,没有之一. LitePal 简介 LitePal 是一款开源的 Android 数据库 ...
最新文章
- Win7下用IIS发布网站
- 【c++】5.函数传指针与传值特容易混淆的点
- linux cp指令报错:cp: omitting directory ‘xxx‘(需要加-r递归拷贝)
- Codeforces Round #643 (Div. 2)(A, B, C, D, E)
- 企业实战(Jenkins+GitLab+SonarQube)_01_Jenkins下载
- python利用百度云接口实现车牌识别
- Scrapy框架的介绍和基本使用
- python flask request 参数映射_Flask request获取参数问题
- 梅耶尔何时离开雅虎?答案将很快揭晓
- Categorical variable(类别变量)学习笔记(未完)
- uinty 为什么一旋转鼠标镜头就倒了_Unity3D使用鼠标旋转缩放平移视角
- 使用mysql创建表格
- 怎么让鼠标带黄色光圈?
- 【JavaWeb】Request对象详解
- 线条边框简笔画图片大全_每天学一幅简笔画生活小物简笔画图片大全!
- IDE Eval Reset 插件安装使用
- Fiddler简单的使用教程
- 小白也可以看懂的Numpy实操演示教程
- IDC时评:从巴黎圣母院大火看数据中心运维
- HP-UX培训学习笔记
热门文章
- 2022-2028年中国FPGA芯片行业竞争格局分析及市场供需预测报告
- costmap_2d详解3:costmap_2d_ros.cpp
- 麦克斯韦方程组的物理意义是什么
- arp病毒系列——攻击类型
- 从入门到精通 网吧免费上网狙击战(转)
- [PAT A1011]World Cup Betting
- win11打不开文件夹,一直转圈,卡死没反应,黑屏卡死
- 2000套微信微信小程序源码+抖音微信小程序源码附开源代码
- Dataset之图片数据增强:设计自动生成(高级封装之命令行解析实现)汽车车牌图片算法(cv2+PIL+argparse)根据随机指定七个字符自动生成逼真车牌图片数据集(带各种噪声效果)
- LightOJ 1198