前言
对于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循环会将需要的表一次性全部创建完毕 / @Override public 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中的数据库版本号进行比较 *如果小于当前的版本号,则会走对应的方法,对应的去执行一些语句,插入一些新的字段。如下: */ @Override public 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 = ""; @Override public 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 @Override public 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 @Override public String getType(@NonNull Uri uri) { return null; } /** * 插入新数据操作 * @param uri * @param values * @return */ @Nullable @Override public 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 失败是-1 Log.e("TAGS", tableName + ":" + "insert:" + insertId); return ContentUris.withAppendedId(uri, insertId); } /** * 删除一条新数据 1:如果uri为 MyContentProvider.URI_EXECSQL则执行sql语句即可(可以是增,删,改) * 2:如果不是则根据表格以及条件进行某条数据的删除 * @param uri * @param selection * @param selectionArgs * @return */ @Override public 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 成功是1 Log.e("TAGS", tableName + ":" + "delete:" + delete); return delete; } } /** * 更新操作: 1.如果uri是包含replace,对应的操作是 存在则更新,不存在则新增 * 2.如果不包含replace,则执行更新操作 * @param uri * @param values * @param selection * @param selectionArgs * @return */ @Override public 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 失败是0 int 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 @Override public 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(); //NOSONAR results = 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"> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:padding="20dp" android:text="登录,请输入账号密码" android:background="#E0EBF0" android:textSize="30sp" /> <EditText android: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="请输入账号" /> <EditText android: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="请输入密码" /> <TextView android: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; @Override protected 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() { @Override public 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"> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:padding="10dp" android:text="学生表数据库" android:textSize="22sp" android:textStyle="bold" android:gravity="center" /> <EditText android: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" /> <EditText android: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" /> <EditText android: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" /> <EditText android: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" /> <EditText android: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" /> <EditText android: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" /> <TextView android: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" /> <TextView android: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" /> <TextView android: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" /> <TextView android: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" /> <TextView android: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" /> <TextView android: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" /> <TextView android: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" /> <TextView android: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" /> <TextView android: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" /> <TextView android: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; @Override protected 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() { @Override public 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() { @Override public void onClick(View v) { getData(); StudentDao.getInstance().delete(studentId); } }); /** * 根据UserId修改一条数据信息 */ tvUpdate.setOnClickListener(new View.OnClickListener() { @Override public 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() { @Override public 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() { @Override public 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() { @Override public 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() { @Override public 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() { @Override public void onClick(View v) { StudentDao.getInstance().deleteAll(); } }); /** * 编写sql语句进行更新操作 */ tvUpdateSql.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { StudentDao.getInstance().updateStudentChinese(); } }); /** *编写sql进行查询操作 */ tvQuerySql1.setOnClickListener(new View.OnClickListener() { @Override public 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