一、创建DataBase
//使用 Singleton 避免產生多個實例(instance),要注意 thread safe 這邊使用雙重鎖定(Double-checked locking) 使用 TableUtils 類別建立及刪除表格 //第一步继承 OrmLiteSqliteOpenHelper public class DatabaseHelper extends OrmLiteSqliteOpenHelper { //版本号 private static final int DATABASE_VERSION = 1; //版本名 private static final String DATABASE_NAME = "Demo"; //单例 private static DatabaseHelper instance; private DatabaseHelper(Context context) { super(context, DATABASE_NAME, null, DATABASE_VERSION); } //运用单例,加上双层线程锁,避免多创建DataBase public static synchronized DatabaseHelper getHelper(Context context) { context = context.getApplicationContext(); if (instance == null) { synchronized (DatabaseHelper.class) { if (instance == null) instance = new DatabaseHelper(context); } } return instance; } //删除并重新创建 @Override public void onUpgrade(SQLiteDatabase database, ConnectionSource connectionSource, int oldVersion, int newVersion) { try { TableUtils.dropTable(connectionSource, User.class, true); TableUtils.dropTable(connectionSource, Group.class, true); onCreate(database, connectionSource); } catch (SQLException e) { e.printStackTrace(); } } //创建 表格 @Override public void onCreate(SQLiteDatabase database, ConnectionSource connectionSource) { try { TableUtils.createTable(connectionSource, User.class); TableUtils.createTable(connectionSource, Group.class); } catch (SQLException e) { e.printStackTrace(); } } }
二、创建相应的JavaBean
public class User { //注意事项:一定要加上@DatabaseField 说明这是表中的字段,这语句就是sql语句中设定主键,外键之类的。。。 @DatabaseField(generatedId = true) private int id; @DatabaseField private String name; @DatabaseField private String psd; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getPsd() { return psd; } public void setPsd(String psd) { this.psd = psd; } }
三、创建对DataBase的操作(这里创建操作的泛型,就是所有Dao类型都能使用)
//承接DatBaseHelper .... //参数是Class类型 private HashMap<String,RuntimeExceptionDao> mRuntimeDaos = new HashMap<>(); public RuntimeExceptionDao getRuntimeDao(Class bean){ RuntimeExceptionDao dao = null; String className = bean.getSimpleName(); //防止重新创建Dao if (mRuntimeDaos.containsKey(className)){ dao = mRuntimeDaos.get(className); } else { //重要的地方,如何创建Dao dao = super.getRuntimeExceptionDao(bean); } return dao; }
四、创建对应的Dao(处理JavaBean与DataBase之间的操作)
public class UserDao { private RuntimeExceptionDao mRuntimeDao; //构造方法中获取Dao,用来操作数据库 public UserDao(Context context) { DataBaseHelper dataBaseHelper = DataBaseHelper.getHelper(context); mRuntimeDao = dataBaseHelper.getRuntimeDao(User.class); } //添加一个User到数据库 public void createUser(User user){ mRuntimeDao.createOrUpdate(user); } //从数据库中检索id为?的user public List<User> queryUser(int id){ List<User> user = null; try { user = mRuntimeDao.queryBuilder().where().eq("id",id).query(); } catch (SQLException e) { e.printStackTrace(); } return user; } //清除数据库 public void clear(){ mRuntimeDao.delete(mRuntimeDao.queryForAll()); } }
五、ORMLite外键引用
创建一个Article类,需要知道这个Article所属的User,那么该怎么办。一般的方法,就是放入这个User的id,但是OrmLite可以放入整个User,这才是正确的面向对象程序。
所以要这么写:
public class Article { @DatabaseField(generatedId = true) private int id; @DatabaseField private String title; @DatabaseField private String content; //声明这列为外键,不同于常规的数据库 外键设置的是User的id,这里直接将User设定为外键 @DatabaseField(canBeNull = true,foreign = true,columnName = "user_id") private User user; public String getContent() { return content; } public void setContent(String content) { this.content = content; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public User getUser() { return user; } public void setUser(User user) { this.user = user; } }
public class ArticleDao { private RuntimeExceptionDao mRuntimeDao; private DataBaseHelper mDataBaseHelper; //构造方法中获取Dao,用来操作数据库 public ArticleDao(Context context) { mDataBaseHelper = DataBaseHelper.getHelper(context); mRuntimeDao = mDataBaseHelper.getRuntimeDao(Article.class); } //添加一个Article到数据库 public void createUser(Article article){ mRuntimeDao.createOrUpdate(article); } //从数据库中检索id为?的Article,经过测试发现 只能获取到User的id,其他内容都是无法获取的 public Article queryArticle(int id){ Article article = null; article = (Article) mRuntimeDao.queryForId(id); return article; } //所以需要用该方法 public Article getArticleWithUser(int id){ Article article = queryArticle(id); //获取到的article并没有User这个对象的内容,需要经过这一层赋值。 mDataBaseHelper.getRuntimeDao(User.class).refresh(article.getUser()); return article; } //根据user对象获取全部的Article public List<Article> getArticles(int userId){ List<Article> articles = null; try { //发现userId的赋值跟int赋值一样 articles = mRuntimeDao.queryBuilder().where().eq("user_id",userId).query(); } catch (SQLException e) { e.printStackTrace(); } return articles; } //清除数据库 public void clear(){ mRuntimeDao.delete(mRuntimeDao.queryForAll()); }
2、在user属性的注解上:@DatabaseField(canBeNull = true, foreign = true, columnName = "user_id", foreignAutoRefresh = true)
添加foreignAutoRefresh =true,这样;当调用queryForId时,拿到Article对象则直接携带了user;
六:关联一个集合
每个User关联一个或多个Article,如果我在User中声明一个Collection<Article> articles,我能否在查询User的时候,一并能够获取到articles的值呢?
在User中添加如下属性,且注解如下:
@ForeignCollectionField
private Collection<Article> articles;
测试代码
User user = new UserDao(getContext()).get(1); L.e(user.getName()); if (user.getArticles() != null) for (Article article : user.getArticles()) { L.e(article.toString()); }
注:id的自增是从1开始的 0 0