zoukankan      html  css  js  c++  java
  • android对象关系映射框架ormlite之一对多(OneToMany)

    前两天,用ormlite对单张表进行了基本的操作,但是,我们知道通常情况对于单张表格进行操作在实际情况中很前两天不现实,那么ormlite能否像Hibenate那样实现多张表之间的一对多,多对多(即OneToMany,ManyToMany)的关系映射呢?带着这个疑问,通过看了官方的文档,发现确实能够实现。先来看看One2Many这种情况的实现。

             我在之前的demo基础上修改了一下,假设用户和部门之间的关系为多对一,即一个部门对应着多个用户,而一个用户只属于一个部门。同样先将运行效果图贴出来。



    在我前面的文章中已经对中间的某些注解及类做了解释这里就不重复了,如有不懂的请先参考: android对象关系映射框架ormlite学习,这里就直接上代码了,说明就放到了代码中了。

    用户类User.java 

    1. <span style="font-size:18px;">@DatabaseTable(tableName = "tb_user")  
    2. public class User {  
    3.     //用户编号  
    4.     @DatabaseField(generatedId=true)  
    5.     private int userId;  
    6.     //用户名  
    7.     @DatabaseField  
    8.     private String userName;  
    9.     //密码  
    10.     @DatabaseField  
    11.     private int age;  
    12.     //入职时间  
    13.     @DatabaseField(format="DATE_STRING")  
    14.     private Date date;  
    15.     //用户所属部门  
    16.     /** 
    17.      * foreign = true:说明这是一个外部引用关系 
    18.      * foreignAutoRefresh = true:当对象被查询时,外部属性自动刷新(暂时我也没看懂其作用) 
    19.      *  
    20.      */  
    21.     @DatabaseField(foreign = true,foreignAutoRefresh = true)  
    22.     private Dept dept;  
    23.       
    24.     public User() {  
    25.         //提供无参构造函数,这样查询的时候可以返回查询出来的对象  
    26.     }  
    27.     public User( int userId,String userName, int age) {  
    28.         this.userId = userId;  
    29.         this.userName = userName;  
    30.         this.age = age;  
    31.     }  
    32.     get/set方法……  
    33. }  
    34. </span>  

    部门类Dept.java 

    1. <span style="font-size:18px;">/** 
    2.  * 部门(这里假设一个用户只对应一个部门,而一个部门对应着多个用户,即一对多的关系) 
    3.  * @author leox 
    4.  * 
    5.  */  
    6. @DatabaseTable(tableName="tb_dept")  
    7. public class Dept {  
    8.     //部门编号  
    9.     @DatabaseField(generatedId=true)  
    10.     private int deptId;  
    11.     //部门名称  
    12.     @DatabaseField  
    13.     private String deptName;  
    14.     //用户信息集合  
    15.     @ForeignCollectionField  
    16.     /** 
    17.      * 这里需要注意的是:属性类型只能是ForeignCollection<T>或者Collection<T> 
    18.      * 如果需要懒加载(延迟加载)可以在@ForeignCollectionField加上参数eager=false 
    19.      * 这个属性也就说明一个部门对应着多个用户 
    20.      */  
    21.     private ForeignCollection<User> users;  
    22.       
    23.     public Dept(){  
    24.           
    25.     }  
    26.       
    27.     public Dept(int deptId,String deptName){  
    28.         this.deptId = deptId;  
    29.         this.deptName = deptName;  
    30.     }  
    31.   
    32.     Get()/set()方法……  
    33. }  
    34. </span>  

    SqlliteOpenHelper类: 

    1. <span style="font-size:18px;">public class DatabaseHelper extends OrmLiteSqliteOpenHelper{  
    2.     // 数据库名称    
    3.     private static final String DATABASE_NAME = "helloAndroid.db";   
    4.     // 数据库version    
    5.     private static final int DATABASE_VERSION = 1;  
    6.       
    7.     /** 
    8.      * 包含两个泛型: 
    9.      * 第一个泛型表DAO操作的类 
    10.      * 第二个表示操作类的主键类型 
    11.      */  
    12.     private Dao<User, Integer> userDao = null;  
    13.     private Dao<Dept,Integer> deptDao = null;  
    14.       
    15.     private RuntimeExceptionDao<User, Integer> simpleRuntimeUserDao = null;  
    16.     private RuntimeExceptionDao<Dept, Integer> simpleRuntimeDeptDao = null;  
    17.       
    18.     public DatabaseHelper(Context context) {  
    19.         super(context, DATABASE_NAME, null, DATABASE_VERSION);  
    20.     }  
    21.       
    22.     @Override  
    23.     public void onCreate(SQLiteDatabase sqliteDatabase, ConnectionSource connectionSource) {  
    24.         try {  
    25.             Log.i(DatabaseHelper.class.getName(), "onCreate");  
    26.             Log.i("test""name = "+DatabaseHelper.class.getName());  
    27.             TableUtils.createTable(connectionSource, Dept.class);  
    28.             TableUtils.createTable(connectionSource, User.class);  
    29.         } catch (SQLException e) {  
    30.             Log.e(DatabaseHelper.class.getName(), "Can't create database", e);  
    31.             throw new RuntimeException(e);  
    32.         }  
    33.           
    34.     }  
    35.     /** 
    36.      * 插入一条用户数据 
    37.      */  
    38.     public void insert(User user){  
    39.         RuntimeExceptionDao<User, Integer> dao = getSimpleDataUserDao();  
    40.         //通过实体对象创建在数据库中创建一条数据,成功返回1,说明插入了一条数据  
    41.         Log.i("test""dao = " + dao+"  user= "+user);  
    42.         int returnValue = dao.create(user);  
    43.         Log.i("test""插入数据后返回值:"+returnValue);  
    44.     }  
    45.     /** 
    46.      * 查询所有的用户信息 
    47.      * @return 
    48.      */  
    49.     public List<User> findAllUser(){  
    50.         RuntimeExceptionDao<User, Integer> dao = getSimpleDataUserDao();  
    51.         return dao.queryForAll();  
    52.     }  
    53.       
    54.     public RuntimeExceptionDao<User, Integer> getSimpleDataUserDao() {  
    55.         if (simpleRuntimeUserDao == null) {  
    56.             simpleRuntimeUserDao = getRuntimeExceptionDao(User.class);  
    57.         }  
    58.         Log.i("test""simpleRuntimeDao ======= "+simpleRuntimeUserDao);  
    59.         return simpleRuntimeUserDao;  
    60.     }  
    61.   
    62.     /** 
    63.      * 这个方法在你的应用升级以及它有一个更高的版本号时调用。所以需要你调整各种数据来适应新的版本 
    64.      */  
    65.     @Override  
    66.     public void onUpgrade(SQLiteDatabase sqliteDatabase, ConnectionSource connectionSource, int oldVersion,  
    67.             int newVersion) {  
    68.         Log.i("test""更新....");  
    69.         try {  
    70.             Log.i(DatabaseHelper.class.getName(), "onUpgrade");  
    71.             //删掉旧版本的数据  
    72.             TableUtils.dropTable(connectionSource, User.classtrue);  
    73.             TableUtils.dropTable(connectionSource, Dept.classtrue);  
    74.             //创建一个新的版本  
    75.             onCreate(sqliteDatabase, connectionSource);  
    76.         } catch (SQLException e) {  
    77.             Log.e(DatabaseHelper.class.getName(), "Can't drop databases", e);  
    78.             throw new RuntimeException(e);  
    79.         }  
    80.     }  
    81.       
    82.     public Dao<User, Integer> getDao() throws SQLException {  
    83.         if (userDao == null) {  
    84.             userDao = getDao(User.class);  
    85.         }  
    86.         return userDao;  
    87.     }  
    88.       
    89.     /***************************************以下为部门操作******************************************/  
    90.       
    91.     public Dao<Dept, Integer> getDeptDao() throws SQLException {  
    92.         if (deptDao == null) {  
    93.             deptDao = getDao(Dept.class);  
    94.         }  
    95.         return deptDao;  
    96.     }  
    97.       
    98.     public RuntimeExceptionDao<Dept, Integer> getSimpleDataDeptDao() {  
    99.         if (simpleRuntimeDeptDao == null) {  
    100.             simpleRuntimeDeptDao = getRuntimeExceptionDao(Dept.class);  
    101.         }  
    102.         Log.i("test""simpleRuntimeDaodeptdept ======= "+simpleRuntimeDeptDao);  
    103.         return simpleRuntimeDeptDao;  
    104.     }  
    105.       
    106.     /** 
    107.      * 插入一条部门数据 
    108.      */  
    109.     public void insertDept(Dept dept){  
    110.         RuntimeExceptionDao<Dept, Integer> dao = getSimpleDataDeptDao();  
    111.         //通过实体对象创建在数据库中创建一条数据,成功返回1,说明插入了一条数据  
    112.         Log.i("test""dao = " + dao+"  dept= "+dept.getDeptName());  
    113.         int returnValue = dao.create(dept);  
    114.         Log.i("test""插入数据后返回值:"+returnValue);  
    115.     }  
    116.       
    117.     /** 
    118.      * 查询所有的部门信息 
    119.      * @return 
    120.      */  
    121.     public List<Dept> findAllDept(){  
    122.         RuntimeExceptionDao<Dept, Integer> dao = getSimpleDataDeptDao();  
    123.         return dao.queryForAll();  
    124.     }  
    125.       
    126.     public Dept findByDeptId(int deptId){  
    127.         RuntimeExceptionDao<Dept, Integer> dao = getSimpleDataDeptDao();  
    128.         return dao.queryForId(deptId);  
    129.     }  
    130.   
    131. }  
    132. </span>  

     

    RegistActivity类:(这个类是模拟了员工录入,输入员工信息和所属部门) 

    1. <span style="font-size:18px;">/** 
    2.  * 员工信息录入 
    3.  * @author leox 
    4.  * 
    5.  */  
    6. public class RegistActivity  extends Activity {  
    7.     EditText userNameEdit;//用户名编辑框  
    8.     EditText ageEdit;//年龄编辑框  
    9.     EditText hiredateEdit;//入职时间编辑框  
    10.     EditText deptEdit;//部门编辑框  
    11.     Button reButton;//提交按钮  
    12.       
    13.     DatabaseHelper helper = new DatabaseHelper(this);  
    14.     @Override  
    15.     protected void onCreate(Bundle savedInstanceState) {  
    16.         super.onCreate(savedInstanceState);  
    17.         setContentView(R.layout.activity_main);  
    18.         userNameEdit = (EditText)this.findViewById(R.id.et_username);  
    19.         ageEdit = (EditText)this.findViewById(R.id.et_age);  
    20.         hiredateEdit = (EditText)this.findViewById(R.id.et_date);  
    21.         deptEdit = (EditText)this.findViewById(R.id.et_dept);  
    22.         reButton = (Button)this.findViewById(R.id.btn_regist);  
    23.         reButton.setOnClickListener(new myClickListener());  
    24.     }  
    25.   
    26.     @Override  
    27.     public boolean onCreateOptionsMenu(Menu menu) {  
    28.         getMenuInflater().inflate(R.menu.main, menu);  
    29.         return true;  
    30.     }  
    31.       
    32.     class myClickListener implements OnClickListener{  
    33.         @Override  
    34.         public void onClick(View v) {  
    35.             //用户名  
    36.             String userName = userNameEdit.getText().toString();  
    37.             //年龄  
    38.             String age = ageEdit.getText().toString();  
    39.             String da = hiredateEdit.getText().toString();  
    40.             //入职时间  
    41.             DateFormat df = new SimpleDateFormat("yyyy-MM-dd");  
    42.             Date hiredate=null;  
    43.             try {  
    44.                 hiredate = df.parse(da);  
    45.             } catch (ParseException e) {  
    46.                 e.printStackTrace();  
    47.             }  
    48.             Log.i("test""date = "+hiredate);  
    49.             //部门信息  
    50.             String deptName = deptEdit.getText().toString();  
    51.             List<Dept> depts = helper.findAllDept();  
    52.             Dept dept = null;  
    53.             //查询出所有的部门信息,如果输入的部门名数据库中不存在那就创建一条新的记录,如果存在则采用原有  
    54.             if(depts.size()>0){  
    55.                 for(Dept d:depts){  
    56.                     if(d.getDeptName().equals(deptName)){  
    57.                         dept = d;  
    58.                     }else{  
    59.                         dept = new Dept();  
    60.                         dept.setDeptName(deptName);  
    61.                         //插入部门信息  
    62.                         helper.insertDept(dept);  
    63.                     }  
    64.                 }  
    65.             }else{  
    66.                 dept = new Dept();  
    67.                 dept.setDeptName(deptName);  
    68.                 //插入部门信息  
    69.                 helper.insertDept(dept);  
    70.             }  
    71.               
    72.             //用户信息  
    73.             User user = new User();  
    74.             user.setUserName(userName);  
    75.             user.setAge(Integer.parseInt(age));  
    76.             user.setDate(hiredate);  
    77.             user.setDept(dept);  
    78.             //插入用户信息  
    79.             helper.insert(user);  
    80.               
    81.             Intent intent = new Intent();  
    82.             intent.setClass(RegistActivity.this, MainActivity.class);  
    83.             startActivity(intent);  
    84.         }  
    85.           
    86.     }  
    87. }  
    88. </span>  

    对应的布局文件:activity_main.xml 

    1. <span style="font-size:18px;"><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
    2.     xmlns:tools="http://schemas.android.com/tools"  
    3.     android:layout_width="match_parent"  
    4.     android:layout_height="match_parent"  
    5.     android:paddingBottom="@dimen/activity_vertical_margin"  
    6.     android:paddingLeft="@dimen/activity_horizontal_margin"  
    7.     android:paddingRight="@dimen/activity_horizontal_margin"  
    8.     android:paddingTop="@dimen/activity_vertical_margin"  
    9.     android:orientation="vertical"  
    10.     android:gravity="center"  
    11.     tools:context=".RegistActivity" >  
    12.   
    13.     <TextView  
    14.         android:layout_width="wrap_content"  
    15.         android:layout_height="wrap_content"  
    16.         android:textSize="20dp"  
    17.         android:text="员工信息录入" />  
    18.       
    19.     <LinearLayout   
    20.         android:layout_width="fill_parent"  
    21.         android:layout_height="wrap_content"  
    22.         android:gravity="center"  
    23.         android:orientation="horizontal">  
    24.         <TextView   
    25.             android:layout_width="wrap_content"  
    26.             android:layout_height="wrap_content"  
    27.             android:text="用户名:"/>  
    28.         <EditText  
    29.             android:id="@+id/et_username"  
    30.             android:layout_width="200px"  
    31.             android:layout_height="wrap_content" />  
    32.     </LinearLayout>  
    33.       
    34.     <LinearLayout   
    35.         android:layout_width="fill_parent"  
    36.         android:layout_height="wrap_content"  
    37.         android:gravity="center"  
    38.         android:orientation="horizontal">  
    39.         <TextView   
    40.             android:layout_width="wrap_content"  
    41.             android:layout_height="wrap_content"  
    42.             android:text="年龄:"/>  
    43.         <EditText  
    44.             android:id="@+id/et_age"  
    45.             android:layout_width="200px"  
    46.             android:layout_height="wrap_content"/>  
    47.     </LinearLayout>  
    48.       
    49.     <LinearLayout   
    50.         android:layout_width="fill_parent"  
    51.         android:layout_height="wrap_content"  
    52.         android:gravity="center"  
    53.         android:orientation="horizontal">  
    54.         <TextView   
    55.             android:layout_width="wrap_content"  
    56.             android:layout_height="wrap_content"  
    57.             android:text="入职时间:"/>  
    58.         <EditText  
    59.             android:id="@+id/et_date"  
    60.             android:layout_width="200px"  
    61.             android:layout_height="wrap_content"/>  
    62.     </LinearLayout>  
    63.       
    64.     <LinearLayout   
    65.         android:layout_width="fill_parent"  
    66.         android:layout_height="wrap_content"  
    67.         android:gravity="center"  
    68.         android:orientation="horizontal">  
    69.         <TextView   
    70.             android:layout_width="wrap_content"  
    71.             android:layout_height="wrap_content"  
    72.             android:text="部门:"/>  
    73.         <EditText  
    74.             android:id="@+id/et_dept"  
    75.             android:layout_width="200px"  
    76.             android:layout_height="wrap_content"/>  
    77.     </LinearLayout>  
    78.       
    79.     <Button   
    80.         android:id="@+id/btn_regist"  
    81.         android:layout_width="wrap_content"  
    82.         android:layout_height="wrap_content"  
    83.         android:text="提交"/>  
    84.   
    85. </LinearLayout>  
    86. </span>  

    MainActivity.java类,这个类用来操作员工信息录入按钮,以及显示员工信息按钮的操作 

    1. <span style="font-size:18px;">public class MainActivity extends Activity {  
    2.   
    3.     Button button1;//员工信息录入按钮  
    4.     Button button2;//员工信息显示按钮  
    5.     TextView textView;//用来显示查询到的用户信息  
    6.     DatabaseHelper helper = new DatabaseHelper(this);  
    7.     @Override  
    8.     protected void onCreate(Bundle savedInstanceState) {  
    9.         super.onCreate(savedInstanceState);  
    10.         setContentView(R.layout.main);  
    11.         button1 = (Button)this.findViewById(R.id.main_btn_inputinfo);  
    12.         button2 = (Button)this.findViewById(R.id.main_btn_show);  
    13.         textView = (TextView)this.findViewById(R.id.main_show_user);  
    14.         //点击注册按钮跳转到注册页面  
    15.         button1.setOnClickListener(new OnClickListener() {  
    16.             @Override  
    17.             public void onClick(View v) {  
    18.                 Intent intent = new Intent();  
    19.                 intent.setClass(MainActivity.this, RegistActivity.class);  
    20.                 startActivity(intent);  
    21.             }  
    22.         });  
    23.         //点击“显示”按钮跳转到用户信息显示页面并将注册用户信息显示出来  
    24.         button2.setOnClickListener(new OnClickListener() {  
    25.             @Override  
    26.             public void onClick(View v) {  
    27.                 List<Dept> list = helper.findAllDept();  
    28.                 Log.i("test""有没有部门?----------------"+list.size());  
    29.                 Dept dept = null;  
    30.                 if(list.size()>0){  
    31.                     dept = helper.findByDeptId(list.get(0).getDeptId());  
    32.                     ForeignCollection<User> orders = dept.getUsers();  
    33.                     CloseableIterator<User> iterator = orders.closeableIterator();  
    34.                     String str = dept.getDeptName()+" 部门下有以下职员:";  
    35.                     try {  
    36.                         while(iterator.hasNext()){  
    37.                             User user = iterator.next();  
    38.                             str+=user.getUserId()+"号:"+user.getUserName()+" 年龄:"+user.getAge()+"  受雇日期: "+user.getDate()+"   ";  
    39.                         }  
    40.                     } finally {  
    41.                         try {  
    42.                             iterator.close();  
    43.                         } catch (SQLException e) {  
    44.                             e.printStackTrace();  
    45.                         }  
    46.                     }  
    47.                     textView.setText(str);  
    48.                 }else{  
    49.                     textView.setText("亲!还没有部门吧!");  
    50.                 }  
    51.             }  
    52.         });  
    53.           
    54.     }  
    55.   
    56.     @Override  
    57.     public boolean onCreateOptionsMenu(Menu menu) {  
    58.         // Inflate the menu; this adds items to the action bar if it is present.  
    59.         getMenuInflater().inflate(R.menu.main, menu);  
    60.         return true;  
    61.     }  
    62.   
    63. }  
    64. </span>  

    对应的布局文件:main.xml 

    1. <span style="font-size:18px;"><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
    2.     xmlns:tools="http://schemas.android.com/tools"  
    3.     android:layout_width="match_parent"  
    4.     android:layout_height="match_parent"  
    5.     android:paddingBottom="@dimen/activity_vertical_margin"  
    6.     android:paddingLeft="@dimen/activity_horizontal_margin"  
    7.     android:paddingRight="@dimen/activity_horizontal_margin"  
    8.     android:paddingTop="@dimen/activity_vertical_margin"  
    9.     android:orientation="vertical"  
    10.     android:gravity="center"  
    11.     tools:context=".MainActivity" >  
    12.   
    13.     <Button   
    14.         android:id="@+id/main_btn_inputinfo"  
    15.         android:layout_width="wrap_content"  
    16.         android:layout_height="wrap_content"  
    17.         android:text="员工信息录入"/>  
    18.       
    19.     <Button   
    20.         android:id="@+id/main_btn_show"  
    21.         android:layout_width="wrap_content"  
    22.         android:layout_height="wrap_content"  
    23.         android:text="员工信息显示"/>  
    24.       
    25.     <!-- <Button   
    26.         android:id="@+id/main_btn_delete"  
    27.         android:layout_width="wrap_content"  
    28.         android:layout_height="wrap_content"  
    29.         android:text="删除"/>  
    30.       
    31.     <Button   
    32.         android:id="@+id/main_btn_deleteAll"  
    33.         android:layout_width="wrap_content"  
    34.         android:layout_height="wrap_content"  
    35.         android:text="批量删除"/> -->  
    36.       
    37.     <TextView   
    38.         android:id="@+id/main_show_user"  
    39.         android:layout_width="wrap_content"  
    40.         android:layout_height="wrap_content"/>  
    41.   
    42. </LinearLayout>  
    43. </span>  


  • 相关阅读:
    当前日志损坏解决一例
    Oracle 1204 RAC failover 测试 (一)
    Logical standby跳过个别SQL不Apply的测试
    Data guard 又出问题了
    CPIO无反应
    回答棉花糖先生关于我说的DB自动增加Index的问题
    SSD硬盘,先不要用在Server上
    ORA00304: requested INSTANCE_NUMBER is busy,终于解决
    .Net运行时的相互关系
    CSS布局探密04
  • 原文地址:https://www.cnblogs.com/android100/p/android-ormlite.html
Copyright © 2011-2022 走看看