LitePal 數據庫基本操作和關聯表方式(一對多)(原創)

說明:個人直接項目測試類寫博客,有個別地方刪除,就不特別自個創建項目簡化說明使用,可以僅僅看大概主要實現功能即可。

1、初始化(工程目錄assets下創建litepal.xml文件)

litepal.xml文件內容:

<?xml version="1.0" encoding="utf-8"?>
<litepal>
    <!--
        Define the database name of your application.
        By default each database name should be end with .db.
        If you didn't name your database end with .db,
        LitePal would plus the suffix automaticly for you.
        For example:
        <dbname value="demo" ></dbname>
    數據庫文件名
    -->
    <dbname value="test" />

    <!--
        Define the version of your database. Each time you want
        to upgrade your database, the version tag would helps.
        Modify the models you defined in the mapping tag, and just
        make the version value plus one, the upgrade of database
        will be processed automaticly without concern.
            For example:
        <version value="1" ></version>
        數據庫版本號:注意,修改table表參數或者增加table表都需要在此修改疊加版本號
    -->
    <version value="1" />
    <!--
        Define your models in the list with mapping tag, LitePal will
        create tables for each mapping class. The supported fields
        defined in models will be mapped into columns.
        For example:
        <list>
            <mapping class="com.test.model.Reader"></mapping>
            <mapping class="com.test.model.Magazine"></mapping>
        </list>
        數據庫table表
    -->
    <list>
        <mapping class="com.example.myapplication.dao.WeiTingTable" />
        <mapping class="com.example.myapplication.dao.WeiTingRoadInfo" />
    </list>

    <!--
        Define where the .db file should be. "internal" means the .db file
        will be stored in the database folder of internal storage which no
        one can access. "external" means the .db file will be stored in the
        path to the directory on the primary external storage device where
        the application can place persistent files it owns which everyone
        can access. "internal" will act as default.
        For example:
        <storage value="external"></storage>
        數據庫存放目錄:工程目錄下/database下
    -->
    <storage value="external" />
</litepal>

2、Activity onCreate()初始化LitePal

@Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_dao);
        LitePal.initialize(this);
    }

3、關聯表bean

package com.example.myapplication.dao;

import android.util.Log;

import com.orhanobut.logger.Logger;

import org.litepal.LitePal;
import org.litepal.crud.LitePalSupport;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * 表結構:一對多關係
 */
public class WeiTingRoadInfo extends LitePalSupport {

    private String adCode;
    private String wholeRoadCode;
    private String wholeRoadName;
    private String partRoadCode;
    private String partRoadName;

    /**
     * 提供子表獲取其id
     *
     * @return
     */
    public long getId() {
        return getBaseObjId();
    }

    /**
     * 從數據庫獲取子表,僅供查詢不可用於操作添加更新保存子表功能(操作使用getWeiTingTableList())
     *
     * @return
     */
    public List<WeiTingTable> getWeiTingTablesFromDb() {
        String linkId = this.getClass().getSimpleName().toLowerCase();// 對應子表id爲:weitingtable_id
        return LitePal.where(linkId + "_id=?", String.valueOf(getBaseObjId())).find(WeiTingTable.class);
    }

    /**
     * 用於新增和更新子表
     *
     * @return
     */
    public List<WeiTingTable> getWeiTingTableList() {
        return weiTingTableList;
    }

    private List<WeiTingTable> weiTingTableList = new ArrayList<>();

    public String getAdCode() {
        return adCode == null ? "" : adCode;
    }

    public void setAdCode(String adCode) {
        this.adCode = adCode;
    }

    public String getWholeRoadCode() {
        return wholeRoadCode == null ? "" : wholeRoadCode;
    }

    public void setWholeRoadCode(String wholeRoadCode) {
        this.wholeRoadCode = wholeRoadCode;
    }

    public String getWholeRoadName() {
        return wholeRoadName == null ? "" : wholeRoadName;
    }

    public void setWholeRoadName(String wholeRoadName) {
        this.wholeRoadName = wholeRoadName;
    }

    public String getPartRoadCode() {
        return partRoadCode == null ? "" : partRoadCode;
    }

    public void setPartRoadCode(String partRoadCode) {
        this.partRoadCode = partRoadCode;
    }

    public String getPartRoadName() {
        return partRoadName == null ? "" : partRoadName;
    }

    public void setPartRoadName(String partRoadName) {
        this.partRoadName = partRoadName;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        WeiTingRoadInfo that = (WeiTingRoadInfo) o;
        return adCode.equals(that.adCode) &&
                wholeRoadCode.equals(that.wholeRoadCode) &&
                wholeRoadName.equals(that.wholeRoadName) &&
                partRoadCode.equals(that.partRoadCode) &&
                partRoadName.equals(that.partRoadName);
    }

    @Override
    public int hashCode() {
        return Objects.hash(adCode, wholeRoadCode, wholeRoadName, partRoadCode, partRoadName);
    }

    @Override
    public String toString() {
        return "WeiTingRoadInfo{" +
                "adCode='" + adCode + '\'' +
                ", wholeRoadCode='" + wholeRoadCode + '\'' +
                ", wholeRoadName='" + wholeRoadName + '\'' +
                ", partRoadCode='" + partRoadCode + '\'' +
                ", partRoadName='" + partRoadName + '\'' +
                '}';
    }

    @Override
    public int delete() {
        // 將子表同步刪除
        List<WeiTingTable> weiTingTables = getWeiTingTablesFromDb();
        for (WeiTingTable weiTingTable : weiTingTables) {
            weiTingTable.delete();
        }
        return super.delete();
    }

    public synchronized boolean saveToFirst() {
        if (LitePal.findLast(this.getClass()).equals(this)) {
            Log.e("DaoActivityLog", "已是最新位置的數據,不做刷新緩存處理。");
            Logger.e("已是最新位置的數據,不做刷新緩存處理。");
            return true;
        }
        Log.e("DaoActivityLog", "不是最新位置的數據,需要刷新緩存處理。");
        List<WeiTingTable> weiTingTables = getWeiTingTablesFromDb();
        List<WeiTingTable> newWeiTingTables = copyList(weiTingTables);
        if (newWeiTingTables != null) {// 避免一些拷貝異常情況清理舊的緩存數據
            // 拷貝全部數據正常
            saveStuTables(newWeiTingTables);
        } else {
            Logger.e("拷貝舊數據失敗,不做刷新緩存處理。");
            return false;
        }
        return save();// 重新緩存
    }

    private void saveStuTables(List<WeiTingTable> weiTingTables) {
        delete();// 刪除了子表
        for (WeiTingTable weiTingTable : weiTingTables) {
            weiTingTable.setWeiTingRoadInfo(this);
            weiTingTable.save();// 重新緩存子表
            getWeiTingTableList().add(weiTingTable);// 重新添加子表
        }
    }

    private List<WeiTingTable> copyList(List<WeiTingTable> weiTingTables) {
        List<WeiTingTable> newWeiTingTables = new ArrayList<>();
        for (WeiTingTable weiTingTable : weiTingTables) {
            WeiTingTable clone = (WeiTingTable) copy(weiTingTable);
            if (clone == null) return null;
            clone.setWeiTingRoadInfo(this);
            newWeiTingTables.add(clone);
        }
        return newWeiTingTables;
    }

    /**
     * 深拷貝
     *
     * @param old
     * @return
     */
    private Object copy(Object old) {
        Object clazz;
        try {
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            ObjectOutputStream oos = new ObjectOutputStream(baos);
            oos.writeObject(old);
            ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
            ObjectInputStream ois = new ObjectInputStream(bais);
            clazz = ois.readObject();
        } catch (Exception e) {
            Logger.e(e, "copy fail");
            return null;
        }
        return clazz;
    }

}

子表類:

package com.example.myapplication.dao;

import org.litepal.LitePal;
import org.litepal.annotation.Column;
import org.litepal.crud.LitePalSupport;

import java.io.Serializable;

/**
 * 表結構:多對一
 */
public class WeiTingTable extends LitePalSupport implements Serializable {

    /**
     * 緩存對應的母表id,便於查詢關聯表
     */
    private long road_id;

    private String hphm;
    private String hpzl;
    private WeiTingRoadInfo weiTingRoadInfo;

    public String getHphm() {
        return hphm == null ? "" : hphm;
    }

    public void setHphm(String hphm) {
        this.hphm = hphm;
    }

    public String getHpzl() {
        return hpzl == null ? "" : hpzl;
    }

    public void setHpzl(String hpzl) {
        this.hpzl = hpzl;
    }

    public String getWei_ting_id() {
        return wei_ting_id == null ? "" : wei_ting_id;
    }

    public void setWei_ting_id(String wei_ting_id) {
        this.wei_ting_id = wei_ting_id;
    }

    public void setWeiTingRoadInfo(WeiTingRoadInfo weiTingRoadInfo) {
        if (weiTingRoadInfo != null) {
            weiTingRoadInfo.getWeiTingTableList().add(this);
            weiTingRoadInfo.save();
            road_id = weiTingRoadInfo.getId();// 前提是WeiTingRoadInfo 先save纔有對應id,否則0
            this.weiTingRoadInfo = weiTingRoadInfo;
        }
    }

    /**
     * 關聯表獲取需要查詢對應子表的id獲取
     *
     * @return
     */
    public WeiTingRoadInfo getWeiTingRoadInfo() {
        if (weiTingRoadInfo != null) return weiTingRoadInfo;
        // 通過緩存id獲取對應關聯表
        return LitePal.find(WeiTingRoadInfo.class, road_id);
    }

}

4、DaoActivity具體實現

package com.example.myapplication;

import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;

import com.example.myapplication.dao.WeiTingRoadInfo;
import com.example.myapplication.dao.WeiTingTable;

import org.litepal.LitePal;

import java.util.List;

public class DaoActivity extends AppCompatActivity {

    private static final String TAG = DaoActivity.class.getSimpleName() + "Log";

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_dao);
        LitePal.initialize(this);
    }

    private int mCount;

    public void save(View view) {
        if (mCount < 10) {
            Log.e(TAG, "第一次緩存");
            ++mCount;
            WeiTingRoadInfo weiTingRoadInfo = new WeiTingRoadInfo();
            weiTingRoadInfo.setAdCode("weiTingRoadInfoAdCode" + mCount);
            weiTingRoadInfo.setPartRoadName("weiTingPartRoadName" + mCount);
            weiTingRoadInfo.setPartRoadCode("weiTingRoadInfoPartRoadCode" + mCount);
            weiTingRoadInfo.setWholeRoadCode("weiTingRoadInfoWholeRoadCode" + mCount);
            weiTingRoadInfo.setWholeRoadName("weiTingRoadInfoWholeRoadName" + mCount);
            boolean save = weiTingRoadInfo.save();
            Log.e(TAG, "weiTingRoadInfo1-1: " + save + " - " + weiTingRoadInfo.getAdCode());
            for (int i = mCount - 1; i < mCount + 10; ++i) {
                WeiTingTable weiTingTable = new WeiTingTable();
                weiTingTable.setHphm("weiTingTableHphm" + i);
                weiTingTable.setHpzl("weiTingTableHpzl" + i);
                weiTingTable.setWeiTingRoadInfo(weiTingRoadInfo);
                weiTingTable.save();
//                weiTingRoadInfo.getWeiTingTableList().add(weiTingTable);
            }
//            boolean save = weiTingRoadInfo.save();
//            Log.e(TAG, "weiTingRoadInfo1-2: " + save + " - " + weiTingRoadInfo.getAdCode());
            mCount += 10;
        } else if (mCount < 20) {
            Log.e(TAG, "第二次緩存");
            ++mCount;
            WeiTingRoadInfo weiTingRoadInfo = new WeiTingRoadInfo();
            weiTingRoadInfo.setAdCode("weiTingRoadInfoAdCode" + mCount);
            weiTingRoadInfo.setPartRoadName("weiTingPartRoadName" + mCount);
            weiTingRoadInfo.setPartRoadCode("weiTingRoadInfoPartRoadCode" + mCount);
            weiTingRoadInfo.setWholeRoadCode("weiTingRoadInfoWholeRoadCode" + mCount);
            weiTingRoadInfo.setWholeRoadName("weiTingRoadInfoWholeRoadName" + mCount);
            boolean save = weiTingRoadInfo.save();
//            Log.e(TAG, "weiTingRoadInfo2-1: " + save + " - " + weiTingRoadInfo.getAdCode());
            for (int i = mCount - 1; i < mCount + 10; ++i) {
                WeiTingTable weiTingTable = new WeiTingTable();
                weiTingTable.setHphm("value" + i);
                weiTingTable.setHpzl("value" + i);
                weiTingTable.setWeiTingRoadInfo(weiTingRoadInfo);
                weiTingTable.save();
//                weiTingRoadInfo.getWeiTingTableList().add(weiTingTable);
            }
//            boolean save = weiTingRoadInfo.save();
//            Log.e(TAG, "weiTingRoadInfo2-2: " + save + " - " + weiTingRoadInfo.getAdCode());
            mCount += 10;
        } else {
            Log.e(TAG, "之後緩存");
            ++mCount;
            WeiTingRoadInfo weiTingRoadInfo = new WeiTingRoadInfo();
            weiTingRoadInfo.setAdCode("weiTingRoadInfoAdCode" + mCount);
            weiTingRoadInfo.setPartRoadName("weiTingPartRoadName" + mCount);
            weiTingRoadInfo.setPartRoadCode("weiTingRoadInfoPartRoadCode" + mCount);
            weiTingRoadInfo.setWholeRoadCode("weiTingRoadInfoWholeRoadCode" + mCount);
            weiTingRoadInfo.setWholeRoadName("weiTingRoadInfoWholeRoadName" + mCount);
            boolean save = weiTingRoadInfo.save();
            Log.e(TAG, "weiTingRoadInfo3-1: " + save + " - " + weiTingRoadInfo.getAdCode());
            int count = 0;
            for (int i = mCount - 1; i < mCount + 10; ++i) {
                WeiTingTable weiTingTable = new WeiTingTable();
                weiTingTable.setHphm("value" + i);
                weiTingTable.setHpzl("value" + i);
                if (i % 2 == 0) {
                    weiTingTable.setMidPicPath("valueMidPicPath" + i);
                }
                weiTingTable.setWeiTingRoadInfo(weiTingRoadInfo);
                weiTingTable.save();
//                weiTingRoadInfo.getWeiTingTableList().add(weiTingTable);
                count = i;
            }
//            save = weiTingRoadInfo.save();
//            Log.e(TAG, "weiTingRoadInfo3-2: " + save + " - " + weiTingRoadInfo.getAdCode());
            mCount += count;
        }
        Log.e(TAG, "mCount: " + mCount);
    }

    public void get(View view) {
        List<WeiTingRoadInfo> weiTingRoadInfos = LitePal.findAll(WeiTingRoadInfo.class);
        for (WeiTingRoadInfo weiTingRoadInfo : weiTingRoadInfos) {
            List<WeiTingTable> weiTingTables = weiTingRoadInfo.getWeiTingTablesFromDb();
            for (WeiTingTable weiTingTable : weiTingTables) {
                Log.e(TAG, "weiTingTable: " + weiTingTable.getHphm());
                Log.e(TAG, "weiTingRoadInfo: " + weiTingRoadInfo.getAdCode());
            }
        }

    }

    public void update(View view) {
        WeiTingRoadInfo first;
        if (System.currentTimeMillis() % 2 == 0) {
            first = LitePal.findLast(WeiTingRoadInfo.class);
        } else {
            first = LitePal.findFirst(WeiTingRoadInfo.class);
        }
        Log.e(TAG, "first: " + first.getAdCode());
        first.saveToFirst();
        WeiTingRoadInfo last = LitePal.findLast(WeiTingRoadInfo.class);
        Log.e(TAG, "last: " + last.getAdCode());
        for (WeiTingTable weiTingTable : last.getWeiTingTablesFromDb()) {
            Log.e(TAG, "last weiTingTable: " + weiTingTable.getHphm());
        }
    }

    public void delete(View view) {
        WeiTingRoadInfo weiTingRoadInfo = LitePal.findFirst(WeiTingRoadInfo.class);
        weiTingRoadInfo.delete();
    }

    public void deleteAll(View view) {
        LitePal.deleteAll(WeiTingRoadInfo.class);
    }

    public void add(View view) {
        WeiTingRoadInfo weiTingRoadInfo = LitePal.findFirst(WeiTingRoadInfo.class);
        WeiTingTable weiTingTable = new WeiTingTable();
        weiTingTable.setHphm("000000");
        weiTingTable.setWeiTingRoadInfo(weiTingRoadInfo);
        weiTingTable.save();
    }

    public void updateStu(View view) {
        WeiTingRoadInfo weiTingRoadInfo = LitePal.findFirst(WeiTingRoadInfo.class);
        List<WeiTingTable> weiTingTableList = weiTingRoadInfo.getWeiTingTablesFromDb();
        WeiTingTable weiTingTable = weiTingTableList.get(0);
        weiTingTable.setHphm("update00000");
        weiTingTable.setWeiTingRoadInfo(weiTingRoadInfo);
        weiTingTable.save();
    }

    public void deleteStu(View view) {
//        WeiTingRoadInfo weiTingRoadInfo = LitePal.findFirst(WeiTingRoadInfo.class);
//        List<WeiTingTable> weiTingTableList = weiTingRoadInfo.getWeiTingTablesFromDb();
//        WeiTingTable weiTingTable = weiTingTableList.get(0);
//        weiTingTable.delete();
        deleteWeiTingInvalidData();
    }

    public void getStu(View view) {
        List<WeiTingTable> all = LitePal.findAll(WeiTingTable.class);
        for (WeiTingTable weiTingTable : all) {
            Log.e(TAG, "weiTingTable: " + weiTingTable.getHphm());
        }
    }

    public void getParent(View view) {
        WeiTingTable first = LitePal.findFirst(WeiTingTable.class);
        WeiTingRoadInfo weiTingRoadInfo = first.getWeiTingRoadInfo();
        Log.e(TAG, "weiTingRoadInfo: " + weiTingRoadInfo.getAdCode());
    }

    /**
     * 清除無效緩存
     */
    private void deleteWeiTingInvalidData() {
        List<WeiTingTable> all = LitePal.findAll(WeiTingTable.class);
        int count = 0;
        for (WeiTingTable weiTingTable : all) {
            if (TextUtils.isEmpty(weiTingTable.getMidPicPath())) {
                weiTingTable.delete();
                ++count;
            }
        }
        Log.e(TAG, "count: " + count);
    }
}

不清楚地方可留言,有時間回覆。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章