sqlite簡介
本人最近在寫一個小的安卓專案,開發app程序中用到了安卓自帶的sqlite,本文主要對sqlite圖片操作進行介紹,其他存入文本之類的操作和普通資料庫一樣,眾所周知,sqlite是一款輕型的資料庫,以下先簡單介紹一下sqlite,為后續做鋪墊,有了解的大佬可以跳過此部分:
SQLite是一種輕量級、嵌入式的關系型資料庫管理系統,它以庫的形式提供了一組編程介面,可以在各種作業系統上運行,如Windows、Linux、Mac OS等,被廣泛應用于移動設備和嵌入式系統中,SQLite的資料存盤在單個檔案中,不需要專門的服務器行程或后臺行程,它支持絕大多數的SQL語法,可以處理大部分中小型應用程式的資料存盤和管理需要,
SQLite的優點主要有以下幾個:
簡單易用:SQLite非常易于安裝和使用,只需要引入單個庫檔案,便可以開始使用它提供的API進行開發,
小巧靈活:由于SQLite的設計目標定位為輕量級的資料庫管理系統,因此它的庫檔案非常小巧,適合在嵌入式設備和移動終端中使用,
零配置:SQLite不需要任何專門的配置或安裝程序,用戶只需要將其API引入到程式中即可使用,大大簡化了部署和維護的作業,
兼容性強:SQLite支持大部分標準的SQL語法,同時可以通過插件或擴展使用自定義的函式和AGGREGATE聚合函式,
SQLite的缺點也是比較明顯的:
不適合大規模資料存盤:由于SQLite的資料存盤在單個檔案中,因此不適合處理大規模資料存盤的需求,處理大量資料的查詢和更新操作性能可能較差,
難以擴展:SQLite的特性和限制都固定在庫檔案中,因此很難對其進行重構或擴展,無法滿足高度定制化需求,
總的來說,SQLite是一種非常輕量級的資料庫管理系統,在小型應用開發及移動端開發中十分適合,但在處理大規模資料存盤及高并發操作的應用場景下效果不佳,
插入圖片
進入正題,在使用sqlite的程序中,我遇到了插入圖片失敗的問題,查了不少資料,才知道sqlite不能直接存入.jpg還有.png之類的檔案,需要以二進制的形式存盤在sqlite中,這也是為什么上面說的sqlite不適合大規模資料存盤,是一個輕量級資料庫,我用下面代碼來進一步說明
要用到的方法以及部分名詞說明:
Bitmap是Android系統中的影像處理的最重要類之一,用它可以獲取影像檔案資訊,進行影像剪切、旋轉、縮放等操作,并可以指定格式保存影像檔案,
BitmapFactory.decodeResource(?,?)這個帶兩個引數的方法:第一個引數是包含你要加載的位圖資源檔案的物件(一般寫成 getResources()就ok了);第二個時你需要加載的位圖資源的Id,
位圖介紹:位圖(Bitmap)格式其實并不能說是一種很常見的格式(從我們日常的使用頻率上來講,遠不如 .jpg .png .gif 等),因為其資料沒有經過壓縮,或最多只采用行程長度編碼(RLE,run-length encoding)來進行輕度的無損資料壓縮
這是一個寫好的呼叫陳述句和方法,insertdb()是寫好的方法,可以稍加修改后放入你的Activity頁面或fragment頁面,呼叫陳述句如圖,

//你的圖片在andriod studio中是存在R.drawble中的,并且是int型的 //存入資料庫的id是自己定義資料庫時設計好的,可以參考我的資料庫代碼 insertdb( R.drawable.你的圖片名,存入資料庫的id); //s指你的圖片資源,int型,即R.drawable.你的圖片名 private void insertdb(int s,int id){ //把你的圖片資源轉化成位圖 Bitmap bitmap = BitmapFactory.decodeResource(this.getResources(), s); //Mysql是自己寫的資料庫類,需要自己撰寫,下面兩句話是實體化一個sqlite資料庫物件 Mysql mySqlLite = new Mysql(this); SQLiteDatabase database = mySqlLite.getReadableDatabase(); //設定一個size大小,用來壓縮圖片檔案 int size = bitmap.getWidth() * bitmap.getHeight() * 4; //ByteArrayOutputStream(位元組陣列輸出流)對byte型別資料進行寫入的類,屬于記憶體操作流 ByteArrayOutputStream baos= new ByteArrayOutputStream(size); //壓縮位圖bitmap bitmap.compress(Bitmap.CompressFormat.PNG, 100, baos); //定義一個byte型別的陣列bytedata存盤位圖位元組流轉化成的byte陣列 byte[] bytedata = https://www.cnblogs.com/zhangyiwen03/archive/2023/06/19/baos.toByteArray(); //sql陳述句是根據自己需求寫的,不要照抄 database.execSQL("update 你的表名 set image=? where _id=?",new Object[] {bytedata,id}); }


//MySQL.java
package 你的包名; import android.content.ContentValues; import android.content.Context; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; public class Mysql extends SQLiteOpenHelper { private static final String DB_NAME="INFORM.db"; private static final int DB_VERSION=1; public Mysql(Context context){ super(context,DB_NAME,null,DB_VERSION); } @Override public void onCreate(SQLiteDatabase db) { db.execSQL( "CREATE TABLE INFORMATION(" + "_id INTEGER PRIMARY KEY AUTOINCREMENT," +"NAME TEXT," +"TITLE TEXT," +"image blob," +"TEXTS TEXT);" ); insertTest(db, "程式員", "程式員.exe無回應","祝你有美好的一天"); insertTest(db, "程式員", "已停止運行","下輩子再也不用sqlite了"); @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { } public void insertTest(SQLiteDatabase db,String name,String title,String texts){ ContentValues value=https://www.cnblogs.com/zhangyiwen03/archive/2023/06/19/new ContentValues(); value.put("NAME",name); value.put("TITLE",title); value.put("TEXTS",texts); db.insert("INFORMTION",null,value); } }

讀取圖片
已經往資料庫插入圖片了,現在可以讀取圖片了,這里我用的是游標

package 你的包名; import androidx.appcompat.app.AppCompatActivity; import android.content.Intent; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; import android.os.Bundle; import android.view.View; import android.widget.AdapterView; import android.widget.ListView; import android.widget.SimpleCursorAdapter; import com.example.garden.database.Mydb; public class SearchResult extends AppCompatActivity implements AdapterView.OnItemClickListener { //定義游標 private Cursor cursor; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_search_result); Intent rit = getIntent(); String text = rit.getStringExtra("key"); ListView listview=findViewById(R.id.listview); //幫助器和管理器兩個老朋友了,實體化資料庫物件 SQLiteOpenHelper helper=new Mydb(this); SQLiteDatabase db=helper.getWritableDatabase(); //游標讀取資料庫 cursor=db.rawQuery("select * from KNOW where name like '%"+text+"%'",null); cursor.moveToFirst(); //資料庫的簡單游標配接器,簡單來說就是往模板填充內容的一個橋梁 SimpleCursorAdapter mAdapter=new SimpleCursorAdapter(this,R.layout.item_list, cursor,new String[]{"NAME","image","TITLE"},new int[]{R.id.iv1,R.id.iv2,R.id.iv3},0);//自己的xml組件名R.id.iv1,R.id.iv2,R.id.iv3與資料庫欄位名"NAME","image","TITLE"對應,更多用法自己查 //僅僅是上面的簡單游標配接器是不能讀取圖片的,重點來了,此處用到了ViewBinder SimpleCursorAdapter.ViewBinder binder=new SimpleCursorAdapter.ViewBinder() { @Override public boolean setViewValue(View view, Cursor cursor, int columnIndex) { //判斷是否是ImageView,這個判斷非常關鍵,詳細可以按ctr去查找ViewBinder,就去檔案看,不要找其他資料,如果想真的搞懂一定要看! if (view instanceof ImageView) { ImageView imageView = (ImageView) view; imageView.setImageBitmap(readImageFromDb(cursor.getString(cursor.getColumnIndex("_id"))));//為imageView配置id所對應的圖片 return true; } return false; } }; //配置ViewBinder mAdapter.setViewBinder(binder); //配置配接器 listview.setAdapter(mAdapter); //點擊監聽器 listview.setOnItemClickListener(this); } // @SuppressLint("Range") private Bitmap readImage(String id) { //至于為什么又要實體化,是因為sqlite不能同時使用,術語不專業,總之要重新實體化,不然會報錯 Mysql mySqlLite2 = new Mysql(this); SQLiteDatabase database2 = mySqlLite2.getReadableDatabase(); Bitmap image= null; byte[] bytes; Cursor cursor = database2.rawQuery( "SELECT * FROM INFORMATION WHERE _id = ?", new String[]{id}); if (cursor.moveToFirst()) { if ((bytes = cursor.getBlob(cursor.getColumnIndex("image"))) != null) { image= BitmapFactory.decodeByteArray(bytes, 0, bytes.length); } } cursor.close(); return image; } //listview的點擊事件 @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { //此處寫點擊事件,我用來傳值以及跳轉頁面 Intent it=new Intent(this, Show.class); it.putExtra("ID",(int)id-1); startActivity(it); finish(); } }

可能會出現的問題
此處重點!我遇到的大問題目前只有一個,就是行過大導致無法讀取資料庫,原因是我放入的圖片太大了,大概1MB左右的樣子,我其他的圖片大小一般是200KB到500KB左右,1MB的圖片太大了,導致那個位圖轉化的二進制資料流太大了,資料庫無法一次讀取完,會導致程式直接崩潰,解決辦法就是不存入太大的圖片,畢竟它還只是個”孩砸“啊,sqlite是個輕量級的資料庫,不要存入太大的圖片
總結
寫代碼的程序中遇到了不少問題,感謝互聯網各位大佬發的參考資料,由于參考了許多資料和文獻,也因為當時寫的太快了沒有記住大佬的博客和文章,深表歉意,本專案后續完善后也會發到GitHub上面去,做一個開源小專案給大家參考,本人目前大二計科學生,希望和各位一同成長前進,
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/555639.html
標籤:其他
上一篇:Android程式員成長之路
下一篇:返回列表