1

我的帐户实体中有一个订单列表。出于这个原因,我的订单实体有一个返回其父订单的外键。在先保存其父帐户之前,防止保存订单的最佳方法是什么。我不希望没有帐户的数据库中存在任何订单。为了更好地解释这是我的订单类

@DatabaseTable
public class Order{

    private static final long serialVersionUID = 1L;

    @DatabaseField(id = true)
    private long id;

    @DatabaseField(foreign = true)
    private Account account;

}

这是我的帐户类

@DatabaseTable
public class Account {
    private static final long serialVersionUID = 1L;

    @DatabaseField(id = true)
    private int id;

    @ForeignCollectionField
    private ForeignCollection<Order> orders;

    public ForeignCollection<Order> getOrders() {
        return orders;
    }

    public void setOrders(ForeignCollection<Order> orders) {
        this.orders = orders;
    }
}

问题是我可以在没有设置帐户的情况下保存订单。有没有办法通过在订单的帐户字段中设置一些属性来防止这种情况?我省略了一些代码,但我知道上述关系正常,因为当我在每个订单中设置帐户字段 = A1 时,我可以检索给定帐户 A1 的订单 Or1、Or2、Or3

4

3 回答 3

0

抱歉延迟回复。有几件事可以在这里尝试。

您的account字段Order应该必须canBeNull = false确保该字段已被分配。

@DatabaseField(foreign = true, canBeNull = false)
private Account account;

Order如果您尝试在没有集合的情况下插入您的,这将引发异常Account。但是,您可以使用尚未插入数据库的文件来设置account文件。解决该问题的一种方法是使该字段成为一个对象(与原始对象相反),因此如果尚未设置它就可以了。AccountAccount.idIntegerintnull

// this is an Integer object so it is null if it has not been set
@DatabaseField(id = true)
private Integer id;

然后,如果该Account.id字段尚未设置,如果您创建一个Orderwith that ,它将引发异常Account。顺便说一句,听起来您可能想要@DatabaseField(generatedId = true),但该Integer领域也适用于此。

最后,如果您尝试创建who 的字段是或字段为 0 ,您还可以重写您的orderDao.create(...)方法以引发异常。Orderaccountnullaccount.id

// we have a custom DAO for this class
@DatabaseTable(daoClass = MyOrderDao.class)
public static class Order {
        ...
}

public static class MyOrderDao extends BaseDaoImpl<Order, Integer> {
    public MyOrderDao(ConnectionSource connectionSource) throws SQLException {
        super(connectionSource, Order.class);
    }

    @Override
    public int create(Order order) throws SQLException {
        if (order.account == null) {
            throw new SQLException("Order's account field is null");
        }
        if (order.account.id == 0) {
            throw new SQLException("Order's account field has a 0 id");
        }
        return super.create(order);
    }
}
于 2012-09-26T21:21:16.410 回答
0

我正在粘贴测试数据库应用程序的整个源代码。这应该可以解决您的问题。

我有一个活动类,它将为您提供用于下订单的 UI 和支持的 xml 文件,以及一个用于执行数据库操作的 DbHandler 类。

这是活动代码。

package com.test;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.database.sqlite.SQLiteConstraintException;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;

public class TestActivity extends Activity implements OnClickListener{

    private EditText accountId = null;
    private EditText orderNumber = null;
    private Button submit = null;

    private DBHandler dbHandler = null;


    @Override
    public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        setupUiElementProperties();
        dbHandler = new DBHandler(this);
    }


    private void setupUiElementProperties() {

        accountId = (EditText)findViewById(R.id.accountEditText);
        orderNumber = (EditText)findViewById(R.id.orderNoEditText);
        submit = (Button)findViewById(R.id.submit);
        submit.setOnClickListener(this);
    }


    public void onClick(View v) {

        try {

            dbHandler.placeOrder(Integer.parseInt(accountId.getText().toString().trim()), 
                    Integer.parseInt(orderNumber.getText().toString().trim()));

            showAlert("ORDER PLACED SUCCESSFULLY");
            System.out.println("DONE..");
        }catch (SQLiteConstraintException ex) {

            System.out.println("SQLITE EXCEPTIOn: " + ex.getMessage());

            showAlert("THIS ACCOUNT DOES NOT EXISTS");
        }catch (Exception e) {

            System.out.println("Exceptionn: " + e.getMessage());
        }
    }

    private void showAlert(String message) {

        new AlertDialog.Builder(TestActivity.this)
        .setTitle("Alert")
        .setMessage(message)
        .setPositiveButton("ok", new DialogInterface.OnClickListener(){
            public void onClick(DialogInterface dlg, int sumthin) {}
        })
        .show();
    }
}

这是 main.xml 的 xml 代码

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >


    <EditText
        android:id="@+id/accountEditText"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_alignParentTop="true"
        android:layout_margin="10dp"
        android:layout_toRightOf="@+id/accountNoLabel" android:inputType="number">

        <requestFocus />
    </EditText>

    <TextView
        android:id="@+id/accountNoLabel"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignBaseline="@+id/accountEditText"
        android:layout_alignBottom="@+id/accountEditText"
        android:layout_alignParentLeft="true"
        android:text="Account Id" android:layout_marginLeft="5dp"/>




    <EditText
        android:id="@+id/orderNoEditText"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignLeft="@+id/accountEditText"
        android:layout_alignRight="@+id/accountEditText"
        android:layout_below="@+id/accountEditText" android:inputType="number"/>

    <TextView
        android:id="@+id/orderLabel"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignBaseline="@+id/orderNoEditText"
        android:layout_alignBottom="@+id/orderNoEditText"
        android:layout_alignLeft="@+id/accountNoLabel"
        android:text="Order No" />

    <Button
        android:id="@+id/submit"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_centerHorizontal="true"
        android:text="Submit" />

</RelativeLayout>

最后是 DbHandler 类

package com.test;

import android.content.ContentValues;
import android.content.Context;
import android.database.sqlite.SQLiteConstraintException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

public class DBHandler extends SQLiteOpenHelper {

    private SQLiteDatabase sqliteDatabaseInstance_ = null;

    public DBHandler(Context context){

        super(context, "TESTDATABASE.db", null, 1);
        sqliteDatabaseInstance_ = getWritableDatabase();
        sqliteDatabaseInstance_.execSQL("PRAGMA foreign_keys = ON;");
    }

    @Override
    public void onCreate(SQLiteDatabase db) {

        try {

            db.execSQL("CREATE TABLE ACCOUNT (accountId INTEGER PRIMARY KEY, name TEXT)");
            insertAccount(1234, "xyz", db);
            db.execSQL("CREATE TABLE ORDER_DETAILS (orderNo INTEGER, accountId INTEGER," +
                    "FOREIGN KEY (accountId) REFERENCES ACCOUNT(accountId))");
        }catch (SQLiteConstraintException sqliteConstraintException) {

            System.out.println("sqliteConstraintException: " + sqliteConstraintException.getMessage());
        }catch (Exception e) {

            System.out.println("Exception in DBHandler.onCreate: "+e.getMessage());
        }
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {}

    public void placeOrder(int accountNo, int orderNo) throws SQLiteConstraintException{

        ContentValues cv = new ContentValues();
        cv.put("accountId", accountNo);
        cv.put("orderNo", orderNo);
        sqliteDatabaseInstance_.insertOrThrow("ORDER_DETAILS", null, cv);
    }


    private void insertAccount(int accId, String accountHolderName, SQLiteDatabase db) {

        ContentValues cv = new ContentValues();
        System.out.println("db: " + db);
        System.out.println("accountId: " + accId) ;
        System.out.println("accountHolderName: " + accountHolderName);
        cv.put("accountId", accId);
        cv.put("name", accountHolderName);
        db.insertOrThrow("ACCOUNT", null, cv);
    }
}

实际上,您不会手动添加订单号(ORDER_DETAILS 表)。该字段必须自动递增并输入数据库。

我在 DbHandler 中添加了 insertAccount(),因为“Account”表没有任何条目。使用这种方法,我正在添加一个帐户 ID 为“1234”的帐户。

这应该是你的输出:

方案 1 帐号:1234 订单号:453412

当帐户 ID 1234 存在于 ACCOUNT 表中时,此条目将被插入到数据库中,并显示成功更新警报。

方案 2 帐户 2343 订单号:14523

由于外键约束失败,此条目将不被接受。因此,您会收到“此帐户不存在”的警报。

我的数据库可能与您需要的不同,但我希望这足以帮助您。

使用 SQLITEBROWSER 查看数据。

你的数据库文件应该在.........

转到文件资源管理器 -----> 数据 ------> 数据 ------> com.test -----> TESTDATA.db

于 2012-07-24T07:33:57.217 回答
-1

@user965895:我没有看到你标记了 ormlite。我对此一无所知。我建议的代码是用于 SQLite 的。Android 带有内置的轻量级数据库 SQLite,您可以使用它。

于 2012-07-24T09:55:00.457 回答