Android Studio 第四十九期 - Sqlite数据库四种写法
最近在看撸撸代码,他自己创了一种,网上有三种,分别是OpenDroid,greenDao,sugar,Sqlite原生写法,感觉都差不多,个人使用最优的是greenDao,下面开始介绍:
1.OpenDroid:优点是简单易懂,缺点是没有联合查询,DeleteAll细节操作:
assets:
<?xml version="1.0" encoding="utf-8"?>
DemoApplication:
package com.example.p033_sqlite.applications;import android.app.Application;import android.content.Context;import com.example.opendroidlibrary.db.OpenDroidUtil;import com.example.opendroidyuanlibrary.db.OpenDroidYuanUtil;/** * Created by shining on 2016/11/10 0010. */public class DemoApplication extends Application { private static final String TAG = "SFNationApplication"; private static DemoApplication sInstance = null; public static Context mContext; public static DemoApplication get() { if (sInstance == null) { sInstance = new DemoApplication(); } return sInstance; } @Override public void onCreate() { super.onCreate(); sInstance = this; mContext = getApplicationContext(); OpenDroidUtil.setup(mContext); OpenDroidYuanUtil.setup(mContext); }}
DemoUseBean:
package com.example.p033_sqlite.domain;import com.example.opendroidlibrary.db.OpenDroid;/** * Created by geek on 2016/2/25. */public class DemoUseBean extends OpenDroid { private int text_id; private String text_content; public DemoUseBean() { } public DemoUseBean(int text_id, String text_content) { this.text_id = text_id; this.text_content = text_content; } public int getText_id() { return text_id; } public void setText_id(int text_id) { this.text_id = text_id; } public String getText_content() { return text_content; } public void setText_content(String text_content) { this.text_content = text_content; }}
MainActivityUse:
package com.example.p033_sqlite.activity;import android.content.ContentValues;import android.os.Bundle;import android.support.v7.app.AppCompatActivity;import android.view.View;import android.widget.TextView;import com.example.opendroidlibrary.db.OpenDroid;import com.example.p033_sqlite.R;import com.example.p033_sqlite.domain.DemoUseBean;import java.util.List;public class MainActivityUse extends AppCompatActivity implements View.OnClickListener { private TextView tv1; private TextView tv00; private TextView tv0; private TextView tv2; private TextView tv3; private TextView tv4; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_mainuser); tv1 = (TextView) findViewById(R.id.tv1); tv00 = (TextView) findViewById(R.id.tv00); tv0 = (TextView) findViewById(R.id.tv0); tv2 = (TextView) findViewById(R.id.tv2); tv3 = (TextView) findViewById(R.id.tv3); tv4 = (TextView) findViewById(R.id.tv4); tv00.setOnClickListener(this); tv0.setOnClickListener(this); tv2.setOnClickListener(this); tv3.setOnClickListener(this); tv4.setOnClickListener(this); } private void get_data() { String a = ""; Listresult1 = OpenDroid.query.find(DemoUseBean.class); for (DemoUseBean res : result1) { System.out.println(res.getText_content()); a = a + res.getText_content() + "\n\n"; } tv1.setText(a); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.tv00: delete_all_data(); for (int i = 0; i < 10; i++) { DemoUseBean stu = new DemoUseBean(); stu.setText_id(i); stu.setText_content("opendroid" + i); stu.save(); } get_data(); break; case R.id.tv0: select_data1(); get_data(); break; case R.id.tv2: insert_data(); get_data(); break; case R.id.tv3: update_data();// update_data_contentvalue(); get_data(); break; case R.id.tv4:// delete_data(); delete_which_data(); get_data(); break; default: break; } } private void update_data_contentvalue() { /** * step 6 : 使用ContentValues更新 */ ContentValues cv = new ContentValues(); cv.put("9", "geekcontentvalue"); OpenDroid.update(DemoUseBean.class, cv, "_id=?", "9"); DemoUseBean result = OpenDroid.query.find(DemoUseBean.class, 9);// System.out.println(result.getText_content()); } private void insert_data() { /** * step 1 : 插入一条数据, 查询一条数据 */ DemoUseBean stu = new DemoUseBean(); stu.setText_content("geek100"); stu.setText_id(100); stu.save(); List result = OpenDroid.query.where("text_id=?", "100").limit(1).find(DemoUseBean.class); System.out.println();//result.getText_content() } private void update_data() { /** * step 5 : 更新数据 */ DemoUseBean stu = new DemoUseBean(); stu.setText_content("geek9"); stu.setText_id(9); stu.update("text_id=?", "9"); List result = OpenDroid.query.find(DemoUseBean.class); for (DemoUseBean res : result) { System.out.println(res.getText_content()); } } private void select_data1() { /** * step 2 : 查询所有记录 */ List result = OpenDroid.query.find(DemoUseBean.class); for (DemoUseBean res : result) { System.out.println(res.getText_content()); } } private void select_datas() { /** * step 3 : 查询多条记录 */ List result = OpenDroid.query.find(DemoUseBean.class, 1, 5, 10); for (DemoUseBean res : result) { System.out.println(res.getId() + " : " + res.getText_content()); } } private void select_which_data() { /** * step 4 : 条件查询 */ List result = OpenDroid.query.columns("stuName", "stuAge") .where("_id>?", "5").order("_id DESC").limit(3) .find(DemoUseBean.class); for (DemoUseBean res : result) { System.out.println(res.getText_content() + " : " + res.getText_id()); } } private void delete_data() { /** * step 7 : 特定删除 */ int length = OpenDroid.delete(DemoUseBean.class, 9);// int length = OpenDroid.delete(DemoUseBean.class, 1, 2, 3); System.out.println(length); } private void delete_which_data() { /** * step 8 : 使用条件删除 */ int length = OpenDroid.delete(DemoUseBean.class, "text_id=?", "9");// int length = OpenDroid.delete(DemoUseBean.class, "_id>?", "2"); System.out.println(length); } private void delete_all_data() { /** * step 8 : 使用条件删除 */ int length = OpenDroid.delete(DemoUseBean.class, "_id>?", "-1"); System.out.println(length); }}
总结:这种方式用起来还是很舒服的,源码后面会给出来,你可以外连library,也可以打成aar,都行。
2.greenDao:优点网上大部分都使用,很叼,缺点是每次改变字段,都需要重新自动生成新的greenDao麻蛋真是费劲~
DemoApplication:
package com.example.p034_greendao_sqlite.application;import android.app.Application;import android.content.Context;import android.database.sqlite.SQLiteDatabase;import com.example.p034_greendao_sqlite.common.DBHelper;import com.example.p034_greendao_sqlite.greendao.DaoMaster;import com.example.p034_greendao_sqlite.greendao.DaoSession;/** * Created by shining on 2017/8/29. */public class DemoApplication extends Application { private static final String TAG = "DemoApplication"; private static DemoApplication sInstance = null; public static Context mContext; private DaoMaster.DevOpenHelper mHelper; private SQLiteDatabase db; private DaoMaster mDaoMaster; private DaoSession mDaoSession; public static DemoApplication get() { if (sInstance == null) { sInstance = new DemoApplication(); } return sInstance; } @Override public void onCreate() { super.onCreate(); sInstance = this; mContext = getApplicationContext(); setDatabase(); } /** * 设置greenDao */ private void setDatabase() { DBHelper devOpenHelper = new DBHelper(this); mDaoMaster = new DaoMaster(devOpenHelper.getWritableDb()); mDaoSession = mDaoMaster.newSession();// userDao = daoSession.getUserDao(); // 通过DaoMaster 的内部类 DevOpenHelper,你可以得到一个便利的SQLiteOpenHelper 对象。 // 可能你已经注意到了,你并不需要去编写「CREATE TABLE」这样的 SQL 语句,因为greenDAO 已经帮你做了。 // 注意:默认的DaoMaster.DevOpenHelper 会在数据库升级时,删除所有的表,意味着这将导致数据的丢失。 // 所以,在正式的项目中,你还应该做一层封装,来实现数据库的安全升级。// mHelper = new DaoMaster.DevOpenHelper(this, "notes-db", null);// db = mHelper.getWritableDatabase();// // 注意:该数据库连接属于DaoMaster,所以多个 Session 指的是相同的数据库连接。// mDaoMaster = new DaoMaster(db);// mDaoSession = mDaoMaster.newSession(); } public DaoSession getDaoSession() { return mDaoSession; } public SQLiteDatabase getDb() { return db; }}
DBHelper:
package com.example.p034_greendao_sqlite.common;import android.content.Context;import android.database.sqlite.SQLiteDatabase;import com.example.p034_greendao_sqlite.greendao.DaoMaster;import java.io.IOException;public class DBHelper extends DaoMaster.OpenHelper { public static final String DBNAME = "geek2017829133810.db"; public DBHelper(Context context) { super(context, DBNAME, null); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { super.onUpgrade(db, oldVersion, newVersion);// if (oldVersion > newVersion) {//TODO 存在BUG,卸载后进入ROM自带数据库的时候会出现数据库版本回退 会走这段逻辑 会出现崩溃// runCMD("pm clear com.example.p034_greendao_sqlite");//// db.setVersion(oldVersion);//// MyLogUtil.d("DBOpenHelper--->onUpgrade-----oldVersion > newVersion");// this.onCreate(db);// return;// }// if (newVersion == 6) {//版本2相对于版本1更改了FridgeStatus表,增加了sterilization_mode字段 5taginfo增加字段foodStatus//// db.execSQL("drop table if exists FridgeStatus");//// db.execSQL("drop table if exists RFIDDataStatus");//// db.execSQL("drop table if exists taginfo");// }//// this.onCreate(db); } public static String runCMD(String cmd) { String result = null; try { String[] cmdx = {"/system/bin/sh", "-c", cmd}; // file must int ret = ShellExeUtil.execCommand(cmdx); result = String.valueOf(ret); } catch (IOException e) { result = "ERR.JE"; } catch (OutOfMemoryError e) { System.gc(); System.runFinalization(); result = "ERR.JE"; } return result; }}
MainActivity:
package com.example.p034_greendao_sqlite;import android.os.Bundle;import android.support.v7.app.AppCompatActivity;import android.view.View;import android.widget.TextView;import android.widget.Toast;import com.example.p034_greendao_sqlite.application.DemoApplication;import com.example.p034_greendao_sqlite.domain.User;import com.example.p034_greendao_sqlite.greendao.UserDao;import java.util.List;public class MainActivity extends AppCompatActivity implements View.OnClickListener { private TextView tv0; private TextView tv_setting; private TextView tv1; private TextView tv2; private TextView tv3; private TextView tv4; private UserDao mUserDao; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); tv0 = (TextView) findViewById(R.id.tv0); tv_setting = (TextView) findViewById(R.id.tv_setting); tv1 = (TextView) findViewById(R.id.tv1); tv2 = (TextView) findViewById(R.id.tv2); tv3 = (TextView) findViewById(R.id.tv3); tv4 = (TextView) findViewById(R.id.tv4); tv_setting.setOnClickListener(this); tv1.setOnClickListener(this); tv2.setOnClickListener(this); tv3.setOnClickListener(this); tv4.setOnClickListener(this); mUserDao = DemoApplication.get().getDaoSession().getUserDao(); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.tv_setting: //重置 deleteAllData(); for (int i = 0; i < 10; i++) { User stu = new User(); stu.setId((long) i); stu.setName("greendao" + i); stu.setAge(i + ""); stu.setSex("男" + i); stu.setSalary(i + "" + i); mUserDao.insert(stu); } queryData(); break; case R.id.tv1: //查询 queryData(); break; case R.id.tv2: //添加 insertData(1001); queryData(); break; case R.id.tv3: //更新 updateData(1001); queryData(); break; case R.id.tv4: //删除 deleteData(1001); queryData(); break; default: break; } } //查 private void queryData() { Listusers = mUserDao.loadAll(); String userName = ""; for (int i = 0; i < users.size(); i++) { userName += users.get(i).getName() + "\n\n"; } tv0.setText(userName);// Toast.makeText(this, "查询全部数据==>" + userName, Toast.LENGTH_SHORT).show(); } //增 private void insertData(int i) { User insertData = new User(null, i + "", "geek", "100", "男", "100"); mUserDao.insert(insertData); } //改 private void updateData(int i) {// User updateData = new User(null, i + "", "geek1", "101", "女", "101");// User updateData = new User((long) i, "geek1", "101", "女", "101");// mUserDao.update(updateData); User user = mUserDao.queryBuilder() .where(UserDao.Properties.Userid.eq(i + "")/*, UserDao.Properties.Name.like("%90%")*/).build().unique(); if (user == null) { Toast.makeText(MainActivity.this, "用户不存在!", Toast.LENGTH_SHORT).show(); } else { user.setUserid(i + ""); user.setName("geek1"); user.setAge("101"); user.setSex("女"); user.setSalary("101"); mUserDao.update(user); } } //删 private void deleteData(int id) { User user = mUserDao.queryBuilder().where(UserDao.Properties.Userid.eq(id + "")).build().unique(); if (user == null) { Toast.makeText(MainActivity.this, "用户不存在", Toast.LENGTH_SHORT).show(); } else { mUserDao.deleteByKey(user.getId()); }// User updateData = new User((long) i, "geek1", "101", "女", "101");// mUserDao.deleteByKey((long) id); } //删全部 private void deleteAllData() { mUserDao.deleteAll(); }}
总结:这种用的很普遍,还是不错的,推荐四颗星~
3.sugar:优点是轻量级,缺点是Bean的格式转化后要对应规范:
DemoBean:
package com.example.p035_sugar_sqlite.domain;import com.google.gson.annotations.Expose;import com.orm.SugarRecord;import java.io.Serializable;/** * Created by geek on 2017年8月29日20:44:05. ** Bean的属性名所采用驼峰命名法,那么大写的字母会在创建的表中字段转换成下划线。 * 比如spuId这个属性对应的表中的字段名为spu_id * 之所以实现Serializable是因为这个Bean在代码中不仅仅为SugarORM创建表而服务, * 同时也是为了能在Android组件中传递(比如Handler中的message.obj)而用,所以这里和官网的直接继承自SugarRecord
不同,推荐大家用我这种方式 * * @Column(name = "textID", unique = true) 这个注解意思是说你想强制按照你的规定的名字来创建表中对应的字段名字,所以这里的skuId在Goods表中的字段名就不是默认的sku_id了,而是你自己给的sku_ID * @Expoes 是来自于Gson的的一个注解,后面会说到 * @Ignore 这个注解强调这个属性在表中不要创建对应的字段 * @SerializedName("id") 采用@SerializedName注解,重新指定id的名称 */public class DemoBean extends SugarRecord implements Serializable { @Expose private int textid; @Expose private String textcontent1; @Expose private String textcontent2; public DemoBean() { } public DemoBean(int textid, String textcontent1, String textcontent2) { this.textid = textid; this.textcontent1 = textcontent1; this.textcontent2 = textcontent2; } public int getTextid() { return textid; } public void setTextid(int textid) { this.textid = textid; } public String getTextcontent1() { return textcontent1; } public void setTextcontent1(String textcontent1) { this.textcontent1 = textcontent1; } public String getTextcontent2() { return textcontent2; } public void setTextcontent2(String textcontent2) { this.textcontent2 = textcontent2; }}
DemoApplication:
package com.example.p035_sugar_sqlite.application;import android.app.Application;import android.content.Context;import com.orm.SugarContext;/** * Created by shining on 2017/8/29. */public class DemoApplication extends Application { private static final String TAG = "DemoApplication"; private static DemoApplication sInstance = null; public static Context mContext; public static DemoApplication get() { if (sInstance == null) { sInstance = new DemoApplication(); } return sInstance; } @Override public void onCreate() { super.onCreate(); sInstance = this; mContext = getApplicationContext(); SugarContext.init(mContext); } @Override public void onTerminate() { super.onTerminate(); SugarContext.terminate(); }}
MainActivity:
package com.example.p035_sugar_sqlite;import android.os.Bundle;import android.support.v7.app.AppCompatActivity;import android.view.View;import android.widget.TextView;import com.example.p035_sugar_sqlite.domain.DemoBean;import java.util.List;public class MainActivity extends AppCompatActivity implements View.OnClickListener { private TextView tv0; private TextView tv_setting; private TextView tv1; private TextView tv2; private TextView tv3; private TextView tv4; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); tv0 = (TextView) findViewById(R.id.tv0); tv_setting = (TextView) findViewById(R.id.tv_setting); tv1 = (TextView) findViewById(R.id.tv1); tv2 = (TextView) findViewById(R.id.tv2); tv3 = (TextView) findViewById(R.id.tv3); tv4 = (TextView) findViewById(R.id.tv4); tv_setting.setOnClickListener(this); tv1.setOnClickListener(this); tv2.setOnClickListener(this); tv3.setOnClickListener(this); tv4.setOnClickListener(this);// //find// Listbooklist=Book.find(Book.class, "number=?", "510110");// Log.i("sugertest","booklist"+booklist.size());// //findWithQuery// List books=Book.findWithQuery(Book.class,"Select * from Book where number=?","java");// Log.i("sugertest","books"+books.size()); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.tv_setting: //重置 deleteAllData(); for (int i = 0; i < 10; i++) { DemoBean stu = new DemoBean();// stu.text_id = i;// stu.text_content1 = "sugar" + i;// stu.text_content2 = "sugars" + i; stu.setTextid(i); stu.setTextcontent1("sugar" + i); stu.setTextcontent2("sugars" + i); stu.save(stu); } select_data(); break; case R.id.tv1: //查询 select_data(); break; case R.id.tv2: //添加 add_data(); select_data(); break; case R.id.tv3: //更新 update_data(); select_data(); break; case R.id.tv4: //删除 delete_data(); select_data(); break; default: break; } } private void select_data() { //查询一条数据// List users = DemoBean.find(DemoBean.class,"text_id>?","-1"); List users = DemoBean.listAll(DemoBean.class); String userName = ""; for (int i = 0; i < users.size(); i++) { userName += users.get(i).getId() + " " + users.get(i).getTextid() + " " + users.get(i).getTextcontent1() + " " + users.get(i).getTextcontent2() + "\n\n"; } tv0.setText(userName);// DemoBean queryBook = DemoBean.findById(DemoBean.class, 1);// Log.i("sugertest", "queryBook" + queryBook.toString()); } private void add_data() { //增加一条数据 DemoBean book = new DemoBean(); book.setTextid(101); book.setTextcontent1("geek100"); book.setTextcontent2("geek200"); long rec = book.save();// Log.i("sugertest", "rec" + String.valueOf(rec)); //rec=2 } private void update_data() { //更新一条数据// List book1 = DemoBean.find(DemoBean.class, "text_id=?", "101"); List book1=DemoBean.findWithQuery(DemoBean.class,"Select * from Demo_Bean where textid=?","9"); book1.get(0).setTextid(9); book1.get(0).setTextcontent1("geek109"); book1.get(0).setTextcontent2("geek109"); book1.get(0).save(); } private void delete_data() { //删除一条数据// DemoBean book2 = DemoBean.findById(DemoBean.class, 101); List book2 = DemoBean.find(DemoBean.class, "textid=?", "101"); book2.get(0).delete(); } //删全部 private void deleteAllData() { DemoBean.deleteAll(DemoBean.class); }}
总结:还有一种就是直接写SQLite,这里就不做介绍了,大家都写了n遍了吧,不过后面的代码我会附上~relax~
地址:https://github.com/geeklx/MyApplication
p033_sqlite :OpenDroid
p034_greendao_sqlite :greenDao
p035_sugar_sqlite : sugar
另附图:
更多相关文章
- Android 遇坑【2】 - ScrollView 嵌套 ListView 时ListView数据
- Android中SQLite数据库操作(2)——SQLiteOpenHelper类
- 解决Android横竖屏切换数据丢失问题
- Android studio cmd命令行操作数据库文件导出,导入
- Fiddler 跟踪 Android 数据包
- 理解 Android 本地数据存储 API
- Android Activity间数据传输
- Android学习-----如何使用sqlite进行后台数据交互,sqlite入门使用
- android listview 数据加载错乱、错位、重复