ORMLite快速入門操作
大家在做安卓專案時肯定都會碰到資料庫儲存,原生的效率上會比較低,為了提高開發效率,大多公司會用一些框架,目前市面上比較流行的框架有ormlite、greenDao、SQLBrite、Realm等,其中ormlite是JDBC(Java資料庫連線)和Android的輕量級ORM java包,而GreenDao則是一種輕快地將物件對映到SQLite資料庫的ORM解決方案。
下面讓我們快速的學習一下ormlite的簡單使用
下載ORMLite Jar包
首先去ormlite官網下載所需的jar包,現在最新版本已經更新到5.0,分別為:ormlite-android-5.0.jar 和 ormlite-core-5.0.jar
定義Bean類
這裡我們定義兩個類,父母和孩子的關係
父母類
package com.liuw.ormlite.bean;
import com.j256.ormlite.field.DatabaseField;
import com.j256.ormlite.table.DatabaseTable;
/**
* 父母
*/
//定義表名
@DatabaseTable(tableName = "tab_parent")
public class Parents {
//generatedId定義主鍵自增長,columnName定義該欄位在資料庫中的列名
@DatabaseField (useGetSet=true,generatedId=true,columnName="id")
private int id;
@DatabaseField(useGetSet=true, columnName = "f_id")
private String fid;//父母編號
@DatabaseField(useGetSet=true, columnName = "f_name")
private String fname;//父親姓名
@DatabaseField(useGetSet=true, columnName = "m_name" )
private String mname;//母親姓名
public Parents() {
}
public Parents(String fid, String fname, String mname) {
this.fid = fid;
this.fname = fname;
this.mname = mname;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getFid() {
return fid;
}
public void setFid(String fid) {
this.fid = fid;
}
public String getFname() {
return fname;
}
public void setFname(String fname) {
this.fname = fname;
}
public String getMname() {
return mname;
}
public void setMname(String mname) {
this.mname = mname;
}
@Override
public String toString() {
return "Parents{" +
"id=" + id +
", fid='" + fid + '\'' +
", fname='" + fname + '\'' +
", mname='" + mname + '\'' +
'}';
}
}
child類,孩子是屬於某個父母,那肯定是需要parent類的主鍵才能找到關係,有的人可能會直接在child類裡宣告一個parent類裡的fid屬性,當做普通屬性來處理,但這樣就違背了面向物件思想
所以這裡我們採用面向物件思想應該是這樣,child屬於某個parent,在child類裡宣告外來鍵parent類來處理,這樣的話在獲取孩子資訊的同時也能獲取到對應父母的資訊
package com.liuw.ormlite.bean;
import com.j256.ormlite.field.DatabaseField;
import com.j256.ormlite.table.DatabaseTable;
/**
* 孩子
*/
@DatabaseTable(tableName = "tab_child")
public class Childs {
@DatabaseField(useGetSet=true,generatedId=true,columnName="id")
private int id;
@DatabaseField(useGetSet=true, columnName = "s_name")
private String sname;//姓名
@DatabaseField(useGetSet=true, columnName = "s_gender")
private String sgender;//性別
@DatabaseField(useGetSet=true, columnName = "s_age")
private String sage;//年齡
@DatabaseField(useGetSet=true, columnName = "s_phone")
private String sphone;//聯絡方式
//引入外來鍵(columnName值預設儲存父類中的主鍵對應的值,也可以換成foreignColumnName指定父類欄位,格式為foreignColumnName = "父表裡的欄位"
//如foreignColumnName = "f_name",此時將會儲存父表裡對應的欄位內容)
@DatabaseField(useGetSet=true, canBeNull = true, foreign = true, columnName = "s_parent")
private Parents parents;//父母資訊
public Childs() {
}
public Childs(String sname, String sgender, String sage) {
this.sname = sname;
this.sgender = sgender;
this.sage = sage;
}
public String getSphone() {
return sphone;
}
public void setSphone(String sphone) {
this.sphone = sphone;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getSname() {
return sname;
}
public void setSname(String sname) {
this.sname = sname;
}
public String getSgender() {
return sgender;
}
public void setSgender(String sgender) {
this.sgender = sgender;
}
public String getSage() {
return sage;
}
public void setSage(String sage) {
this.sage = sage;
}
public Parents getParents() {
return parents;
}
public void setParents(Parents parents) {
this.parents = parents;
}
@Override
public String toString() {
return "Childs{" +
"id=" + id +
", sname='" + sname + '\'' +
", sgender='" + sgender + '\'' +
", sage='" + sage + '\'' +
", parents=" + parents +
'}';
}
}
SQLiteOpenHelper類
原生的資料庫操作,都需要繼承SQLiteOpenHelper,而ormlite我們則需要繼承OrmLiteSqliteOpenHelper
package com.liuw.ormlite.dao;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.os.Environment;
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 com.liuw.ormlite.bean.Childs;
import com.liuw.ormlite.bean.Courses;
import com.liuw.ormlite.bean.Parents;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;
public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
private static final String TABLE_NAME = "ormlite_test.db";//預設是在data/data/包名/databases/路徑下
public static final String DATABASE_PATH = Environment.getExternalStorageDirectory() + "/liuw/" + TABLE_NAME;//指定路徑
private static final int DB_VERSION = 3;
private Map<String, Dao> daos = new HashMap<String, Dao>();
private DatabaseHelper(Context context) {
super(context, DATABASE_PATH, null, DB_VERSION);
}
@Override
public void onCreate(SQLiteDatabase database,
ConnectionSource connectionSource) {
try {
TableUtils.createTableIfNotExists(connectionSource, Childs.class);
TableUtils.createTableIfNotExists(connectionSource, Courses.class);
TableUtils.createTableIfNotExists(connectionSource, Parents.class);
} catch (SQLException e) {
e.printStackTrace();
}
}
@Override
public void onUpgrade(SQLiteDatabase database,
ConnectionSource connectionSource, int oldVersion, int newVersion) {
//整表刪除建立
// try {
// TableUtils.dropTable(connectionSource, Childs.class, true);
// TableUtils.dropTable(connectionSource, Courses.class, true);
// TableUtils.dropTable(connectionSource, Parents.class, true);
// onCreate(database, connectionSource);
// } catch (SQLException e) {
// e.printStackTrace();
// }
//更新資料庫時只需新增新增欄位
if (newVersion == 3) {
//資料庫、表名、列名、型別
DatabaseUtil.updateColumn(database, "tab_child", "s_phone", "VARCHAR", null);
}
}
private static DatabaseHelper instance;
/**
* 單例獲取該Helper
*
* @param context
* @return
*/
public static synchronized DatabaseHelper getHelper(Context context) {
context = context.getApplicationContext();
if (instance == null) {
synchronized (DatabaseHelper.class) {
if (instance == null)
instance = new DatabaseHelper(context);
}
}
return instance;
}
public synchronized Dao getDao(Class clazz) throws SQLException {
Dao dao = null;
String className = clazz.getSimpleName();
if (daos.containsKey(className)) {
dao = daos.get(className);
}
if (dao == null) {
dao = super.getDao(clazz);
daos.put(className, dao);
}
return dao;
}
/**
* 釋放資源
*/
@Override
public void close() {
super.close();
for (String key : daos.keySet()) {
Dao dao = daos.get(key);
dao = null;
}
}
}
這裡詳細就不做介紹了,onCreate建立表,onUpgrade更新表,網上教程大多都是採用刪除再建立的方式更新,這裡我們可以通過自定義的DatabaseUtil類來實現表結構的更新,其實內部就是一個新增列的原生SQL語句,程式碼如下:
package com.liuw.ormlite.dao;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
public class DatabaseUtil {
public static void updateColumn(SQLiteDatabase db, String tableName,
String columnName, String columnType, Object defaultField) {
try {
if (db != null) {
Cursor c = db.rawQuery("SELECT * from " + tableName
+ " limit 1 ", null);
boolean flag = false;
if (c != null) {
for (int i = 0; i < c.getColumnCount(); i++) {
if (columnName.equalsIgnoreCase(c.getColumnName(i))) {
flag = true;
break;
}
}
if (flag == false) {
String sql = "alter table " + tableName + " add "
+ columnName + " " + columnType + " default "
+ defaultField;
db.execSQL(sql);
}
c.close();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
public static void deleteRecordsWithoutForeignKey(SQLiteDatabase db, String tableName){
if (db != null) {
String sql = "DELETE from " + tableName;
db.execSQL(sql);
}
}
}
這樣做的好處是不用再整表刪除、建立,從而提高了工作效率
編寫Dao類
我們可以將需要的增、刪、改、查等方法都放在Dao裡,便於操作使用
父類Dao
package com.liuw.ormlite.dao;
import android.content.Context;
import com.j256.ormlite.dao.Dao;
import com.liuw.ormlite.bean.Parents;
import java.sql.SQLException;
public class ParentDao {
private Dao<Parents, Integer> parentDao;
private DatabaseHelper helper;
public ParentDao(Context contex) {
try {
helper = DatabaseHelper.getHelper(contex);
parentDao = helper.getDao(Parents.class);
if (parentDao == null) {
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 增
* @param parent
*/
public void addParent(Parents parent) {
try {
parentDao.create(parent);
} catch (SQLException e) {
e.printStackTrace();
}
}
}
孩子類Dao
package com.liuw.ormlite.dao;
import android.content.Context;
import com.j256.ormlite.dao.Dao;
import com.liuw.ormlite.bean.Childs;
import com.liuw.ormlite.bean.Parents;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
public class ChildDao {
private Dao<Childs, Integer> childDao;
private DatabaseHelper helper;
public ChildDao(Context contex) {
try {
helper = DatabaseHelper.getHelper(contex);
childDao = helper.getDao(Childs.class);
if (childDao == null) {
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 增
* @param child
*/
public void addChild(Childs child) {
try {
childDao.create(child);
} catch (SQLException e) {
e.printStackTrace();
}
}
/**
* 刪(通過實體)
* @param child
*/
public void delChild(Childs child) {
try {
childDao.delete(child);
} catch (SQLException e) {
e.printStackTrace();
}
}
/**
* 刪(通過id)
* @param id
*/
public void delChildById(Integer id) {
try {
childDao.deleteById(id);
} catch (SQLException e) {
e.printStackTrace();
}
}
/**
* 改
* @param child
*/
public void updateChild(Childs child) {
try {
childDao.update(child);
} catch (SQLException e) {
e.printStackTrace();
}
}
/**
* 查
* @return
*/
public List<Childs> queryAllChild() {
ArrayList<Childs> childs = null;
try {
childs = (ArrayList<Childs>) childDao.queryForAll();
} catch (SQLException e) {
e.printStackTrace();
}
return childs;
}
/**
* 獲取user
* @param id child編號
* @return
*/
public Childs getChild(Integer id) {
try {
//父母資訊為空
return childDao.queryForId(id);
} catch (SQLException e) {
e.printStackTrace();
return null;
}
}
/**
* 獲取user
* @param id child編號
* @return
*/
public Childs getChildAndParent(Integer id) {
try {
//父母資訊有值,此處的refresh也可通過在資料中新增foreignAutoRefresh = true來實現
Childs child = childDao.queryForId(id);
helper.getDao(Parents.class).refresh(child.getParents());
return child;
} catch (SQLException e) {
e.printStackTrace();
return null;
}
}
/**
* 獲取user
* @param name child姓名
* @return
*/
public List<Childs> getChildByName(String name) {
try {
List<Childs> childs = childDao.queryBuilder().where().eq("s_name", name).query();
return childs;
} catch (SQLException e) {
e.printStackTrace();
return null;
}
}
}
測試
測試之前不要忘了加讀寫許可權
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
package com.liuw.ormlite;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import com.liuw.ormlite.bean.Childs;
import com.liuw.ormlite.bean.Parents;
import com.liuw.ormlite.dao.ParentDao;
import com.liuw.ormlite.dao.ChildDao;
import java.util.List;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initData();
}
private void initData() {
ParentDao parentDao = new ParentDao(getApplicationContext());
ChildDao childDao = new ChildDao(getApplicationContext());
Parents p1 = new Parents("001", "曹建華", "於曉紅");
parentDao.addParent(p1);
Childs s1 = new Childs("豬小明", "男", "15");
s1.setParents(p1);
childDao.addChild(s1);
Parents p2 = new Parents("002", "餘正華", "謀女郎");
parentDao.addParent(p2);
Childs s2 = new Childs("閏土", "男", "20");
s2.setParents(p2);
childDao.addChild(s2);
//id自增長預設從1開始
Childs student1 = childDao.getChild(1);
if (student1 != null) {
//結果:Childs{id=1, sname='豬小明', sgender='男', sage='15', parents=Parents{id=1,fid='null' fname='null', mname='null'}}
Log.i("liuw", student1.toString());
}
Childs student2 = childDao.getChildAndParent(2);
if (student2 != null) {
//結果:Childs{id=2, sname='閏土', sgender='男', sage='20', parents=Parents{id=2,fid='002' fname='餘正華', mname='謀女郎'}}
Log.i("liuw", student2.toString());
}
List<Childs> students = childDao.getChildByName("閏土");
if (students != null && students.size() > 0) {
Log.i("liuw", "資料大小為:"+students.size());
}
}
}
注意上面的兩個結果的區別,具體可以看下兩個方法,可以手動重新整理,也可以直接在資料庫的表裡新增foreignAutoRefresh = true來實現;
本來是準備寫一篇多表、多條件之間查詢的,不過模擬資料新增起來有點麻煩,這裡先介紹兩篇文章做參考吧
複雜條件查詢
ormlite引數及方法介紹