前兩天,用ormlite對單張表進行了基本的操作,但是,我們知道通常情況對於單張表格進行操作在實際情況中很前兩天不現實,那麼ormlite能否像Hibenate那樣實現多張表之間的一對多,多對多(即OneToMany,ManyToMany)的關係映射呢?帶着這個疑問,通過看了官方的文檔,發現確實能夠實現。先來看看One2Many這種情況的實現。
我在之前的demo基礎上修改了一下,假設用戶和部門之間的關係爲多對一,即一個部門對應着多個用戶,而一個用戶只屬於一個部門。同樣先將運行效果圖貼出來。
在我前面的文章中已經對中間的某些註解及類做了解釋這裏就不重複了,如有不懂的請先參考: android對象關係映射框架ormlite學習,這裏就直接上代碼了,說明就放到了代碼中了。
用戶類User.java
@DatabaseTable(tableName = "tb_user")
public class User {
//用戶編號
@DatabaseField(generatedId=true)
private int userId;
//用戶名
@DatabaseField
private String userName;
//密碼
@DatabaseField
private int age;
//入職時間
@DatabaseField(format="DATE_STRING")
private Date date;
//用戶所屬部門
/**
* foreign = true:說明這是一個外部引用關係
* foreignAutoRefresh = true:當對象被查詢時,外部屬性自動刷新(暫時我也沒看懂其作用)
*
*/
@DatabaseField(foreign = true,foreignAutoRefresh = true)
private Dept dept;
public User() {
//提供無參構造函數,這樣查詢的時候可以返回查詢出來的對象
}
public User( int userId,String userName, int age) {
this.userId = userId;
this.userName = userName;
this.age = age;
}
get/set方法……
}
部門類Dept.java
/**
* 部門(這裏假設一個用戶只對應一個部門,而一個部門對應着多個用戶,即一對多的關係)
* @author leox
*
*/
@DatabaseTable(tableName="tb_dept")
public class Dept {
//部門編號
@DatabaseField(generatedId=true)
private int deptId;
//部門名稱
@DatabaseField
private String deptName;
//用戶信息集合
@ForeignCollectionField
/**
* 這裏需要注意的是:屬性類型只能是ForeignCollection<T>或者Collection<T>
* 如果需要懶加載(延遲加載)可以在@ForeignCollectionField加上參數eager=false
* 這個屬性也就說明一個部門對應着多個用戶
*/
private ForeignCollection<User> users;
public Dept(){
}
public Dept(int deptId,String deptName){
this.deptId = deptId;
this.deptName = deptName;
}
Get()/set()方法……
}
SqlliteOpenHelper類:
public class DatabaseHelper extends OrmLiteSqliteOpenHelper{
// 數據庫名稱
private static final String DATABASE_NAME = "helloAndroid.db";
// 數據庫version
private static final int DATABASE_VERSION = 1;
/**
* 包含兩個泛型:
* 第一個泛型表DAO操作的類
* 第二個表示操作類的主鍵類型
*/
private Dao<User, Integer> userDao = null;
private Dao<Dept,Integer> deptDao = null;
private RuntimeExceptionDao<User, Integer> simpleRuntimeUserDao = null;
private RuntimeExceptionDao<Dept, Integer> simpleRuntimeDeptDao = null;
public DatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase sqliteDatabase, ConnectionSource connectionSource) {
try {
Log.i(DatabaseHelper.class.getName(), "onCreate");
Log.i("test", "name = "+DatabaseHelper.class.getName());
TableUtils.createTable(connectionSource, Dept.class);
TableUtils.createTable(connectionSource, User.class);
} catch (SQLException e) {
Log.e(DatabaseHelper.class.getName(), "Can't create database", e);
throw new RuntimeException(e);
}
}
/**
* 插入一條用戶數據
*/
public void insert(User user){
RuntimeExceptionDao<User, Integer> dao = getSimpleDataUserDao();
//通過實體對象創建在數據庫中創建一條數據,成功返回1,說明插入了一條數據
Log.i("test", "dao = " + dao+" user= "+user);
int returnValue = dao.create(user);
Log.i("test", "插入數據後返回值:"+returnValue);
}
/**
* 查詢所有的用戶信息
* @return
*/
public List<User> findAllUser(){
RuntimeExceptionDao<User, Integer> dao = getSimpleDataUserDao();
return dao.queryForAll();
}
public RuntimeExceptionDao<User, Integer> getSimpleDataUserDao() {
if (simpleRuntimeUserDao == null) {
simpleRuntimeUserDao = getRuntimeExceptionDao(User.class);
}
Log.i("test", "simpleRuntimeDao ======= "+simpleRuntimeUserDao);
return simpleRuntimeUserDao;
}
/**
* 這個方法在你的應用升級以及它有一個更高的版本號時調用。所以需要你調整各種數據來適應新的版本
*/
@Override
public void onUpgrade(SQLiteDatabase sqliteDatabase, ConnectionSource connectionSource, int oldVersion,
int newVersion) {
Log.i("test", "更新....");
try {
Log.i(DatabaseHelper.class.getName(), "onUpgrade");
//刪掉舊版本的數據
TableUtils.dropTable(connectionSource, User.class, true);
TableUtils.dropTable(connectionSource, Dept.class, true);
//創建一個新的版本
onCreate(sqliteDatabase, connectionSource);
} catch (SQLException e) {
Log.e(DatabaseHelper.class.getName(), "Can't drop databases", e);
throw new RuntimeException(e);
}
}
public Dao<User, Integer> getDao() throws SQLException {
if (userDao == null) {
userDao = getDao(User.class);
}
return userDao;
}
/***************************************以下爲部門操作******************************************/
public Dao<Dept, Integer> getDeptDao() throws SQLException {
if (deptDao == null) {
deptDao = getDao(Dept.class);
}
return deptDao;
}
public RuntimeExceptionDao<Dept, Integer> getSimpleDataDeptDao() {
if (simpleRuntimeDeptDao == null) {
simpleRuntimeDeptDao = getRuntimeExceptionDao(Dept.class);
}
Log.i("test", "simpleRuntimeDaodeptdept ======= "+simpleRuntimeDeptDao);
return simpleRuntimeDeptDao;
}
/**
* 插入一條部門數據
*/
public void insertDept(Dept dept){
RuntimeExceptionDao<Dept, Integer> dao = getSimpleDataDeptDao();
//通過實體對象創建在數據庫中創建一條數據,成功返回1,說明插入了一條數據
Log.i("test", "dao = " + dao+" dept= "+dept.getDeptName());
int returnValue = dao.create(dept);
Log.i("test", "插入數據後返回值:"+returnValue);
}
/**
* 查詢所有的部門信息
* @return
*/
public List<Dept> findAllDept(){
RuntimeExceptionDao<Dept, Integer> dao = getSimpleDataDeptDao();
return dao.queryForAll();
}
public Dept findByDeptId(int deptId){
RuntimeExceptionDao<Dept, Integer> dao = getSimpleDataDeptDao();
return dao.queryForId(deptId);
}
}
RegistActivity類:(這個類是模擬了員工錄入,輸入員工信息和所屬部門)
/**
* 員工信息錄入
* @author leox
*
*/
public class RegistActivity extends Activity {
EditText userNameEdit;//用戶名編輯框
EditText ageEdit;//年齡編輯框
EditText hiredateEdit;//入職時間編輯框
EditText deptEdit;//部門編輯框
Button reButton;//提交按鈕
DatabaseHelper helper = new DatabaseHelper(this);
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
userNameEdit = (EditText)this.findViewById(R.id.et_username);
ageEdit = (EditText)this.findViewById(R.id.et_age);
hiredateEdit = (EditText)this.findViewById(R.id.et_date);
deptEdit = (EditText)this.findViewById(R.id.et_dept);
reButton = (Button)this.findViewById(R.id.btn_regist);
reButton.setOnClickListener(new myClickListener());
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
class myClickListener implements OnClickListener{
@Override
public void onClick(View v) {
//用戶名
String userName = userNameEdit.getText().toString();
//年齡
String age = ageEdit.getText().toString();
String da = hiredateEdit.getText().toString();
//入職時間
DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
Date hiredate=null;
try {
hiredate = df.parse(da);
} catch (ParseException e) {
e.printStackTrace();
}
Log.i("test", "date = "+hiredate);
//部門信息
String deptName = deptEdit.getText().toString();
List<Dept> depts = helper.findAllDept();
Dept dept = null;
//查詢出所有的部門信息,如果輸入的部門名數據庫中不存在那就創建一條新的記錄,如果存在則採用原有
if(depts.size()>0){
for(Dept d:depts){
if(d.getDeptName().equals(deptName)){
dept = d;
}else{
dept = new Dept();
dept.setDeptName(deptName);
//插入部門信息
helper.insertDept(dept);
}
}
}else{
dept = new Dept();
dept.setDeptName(deptName);
//插入部門信息
helper.insertDept(dept);
}
//用戶信息
User user = new User();
user.setUserName(userName);
user.setAge(Integer.parseInt(age));
user.setDate(hiredate);
user.setDept(dept);
//插入用戶信息
helper.insert(user);
Intent intent = new Intent();
intent.setClass(RegistActivity.this, MainActivity.class);
startActivity(intent);
}
}
}
對應的佈局文件:activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:orientation="vertical"
android:gravity="center"
tools:context=".RegistActivity" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="20dp"
android:text="員工信息錄入" />
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="用戶名:"/>
<EditText
android:id="@+id/et_username"
android:layout_width="200px"
android:layout_height="wrap_content" />
</LinearLayout>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="年齡:"/>
<EditText
android:id="@+id/et_age"
android:layout_width="200px"
android:layout_height="wrap_content"/>
</LinearLayout>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="入職時間:"/>
<EditText
android:id="@+id/et_date"
android:layout_width="200px"
android:layout_height="wrap_content"/>
</LinearLayout>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="部門:"/>
<EditText
android:id="@+id/et_dept"
android:layout_width="200px"
android:layout_height="wrap_content"/>
</LinearLayout>
<Button
android:id="@+id/btn_regist"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="提交"/>
</LinearLayout>
MainActivity.java類,這個類用來操作員工信息錄入按鈕,以及顯示員工信息按鈕的操作
public class MainActivity extends Activity {
Button button1;//員工信息錄入按鈕
Button button2;//員工信息顯示按鈕
TextView textView;//用來顯示查詢到的用戶信息
DatabaseHelper helper = new DatabaseHelper(this);
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
button1 = (Button)this.findViewById(R.id.main_btn_inputinfo);
button2 = (Button)this.findViewById(R.id.main_btn_show);
textView = (TextView)this.findViewById(R.id.main_show_user);
//點擊註冊按鈕跳轉到註冊頁面
button1.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent();
intent.setClass(MainActivity.this, RegistActivity.class);
startActivity(intent);
}
});
//點擊“顯示”按鈕跳轉到用戶信息顯示頁面並將註冊用戶信息顯示出來
button2.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
List<Dept> list = helper.findAllDept();
Log.i("test", "有沒有部門?----------------"+list.size());
Dept dept = null;
if(list.size()>0){
dept = helper.findByDeptId(list.get(0).getDeptId());
ForeignCollection<User> orders = dept.getUsers();
CloseableIterator<User> iterator = orders.closeableIterator();
String str = dept.getDeptName()+" 部門下有以下職員:";
try {
while(iterator.hasNext()){
User user = iterator.next();
str+=user.getUserId()+"號:"+user.getUserName()+" 年齡:"+user.getAge()+" 受僱日期: "+user.getDate()+" ";
}
} finally {
try {
iterator.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
textView.setText(str);
}else{
textView.setText("親!還沒有部門吧!");
}
}
});
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
對應的佈局文件:main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:orientation="vertical"
android:gravity="center"
tools:context=".MainActivity" >
<Button
android:id="@+id/main_btn_inputinfo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="員工信息錄入"/>
<Button
android:id="@+id/main_btn_show"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="員工信息顯示"/>
<!-- <Button
android:id="@+id/main_btn_delete"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="刪除"/>
<Button
android:id="@+id/main_btn_deleteAll"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="批量刪除"/> -->
<TextView
android:id="@+id/main_show_user"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>