Android 面向对象式数据库架构设计2-分库

本文介绍了一种在Android应用中实现多用户登录并通过分库管理每个用户数据的方法。通过UserDao类实现用户登录状态的唯一性,确保同一时间只有一个用户在线。BaseDaoSubFactory类负责创建针对不同用户的数据库实例。

Android 面向对象式数据库架构设计1


在多用户的情况下,我们可以通过分库的方式,让不同的用户持有自己的一个数据库文件,类似QQ。

1 User

QQ中只能有一个用户在线,所以需要一个参数来记录用户的状态。

在改变下User中添加status字段:

@DbTable("tb_user")
public class User {
    @DbField("_id")
    private String id;
    private String name;
    private String password;
    private Integer status;
	
	...
	
}

2 UserDao

public class UserDao extends BaseDao<User> {

    @Override
    public long insert(User entity) {
        //查询tb_user;
        List<User> list = query(new User());//1
        User where = null;
        for (User user : list) {//2
            where = new User();
            where.setId(user.getId());
            user.setStatus(0);
            Log.e("alanLog", "用户" + user.getName() + "更改为未登录状态");
            update(user,where);
        }
        Log.e("alanLog", "用户" + entity.getName() + "登录成功");
        entity.setStatus(1);
        return super.insert(entity);//3
    }

    //得到当前登录的User
    public User getCurrentUser(){
        User user = new User();
        user.setStatus(1);
        List<User> list = query(user);
        if(list != null && list.size() > 0){
            return list.get(0);
        }
        return null;
    }
}

注释1:查询tb_user表返回所有user信息。
注释2:将所有user的status设置为0。
注释3:将当前登录的user的status设置为1,并保存到数据库。

3 BaseDaoSubFactory

public class BaseDaoSubFactory extends BaseDaoFactory {

    private static final BaseDaoSubFactory ourInstance = new BaseDaoSubFactory();
    public static BaseDaoSubFactory getInstance(){
        return ourInstance;
    }

    //定义一个用于实现分库的数据库操作对象
    private SQLiteDatabase sqLiteDatabase;
    
    public <T extends BaseDao<M>, M>T getSubDao(Class<T> daoClass, Class<M> entityClass){
        BaseDao baseDao = null;
        if(map.get(PrivateDataBaseEnums.DATEBASE.getValue()) != null){
            return (T)map.get(PrivateDataBaseEnums.DATEBASE.getValue());
        }
        Log.e("alanLog", "生成数据库文件的位置" + PrivateDataBaseEnums.DATEBASE.getValue());
        sqLiteDatabase = SQLiteDatabase.openOrCreateDatabase(PrivateDataBaseEnums.DATEBASE.getValue(), null );
        try {
            baseDao = daoClass.newInstance();
            baseDao.init(sqLiteDatabase, entityClass);
            map.put(PrivateDataBaseEnums.DATEBASE.getValue(), baseDao);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        }
        return (T)baseDao;
    }

}

4 PrivateDataBaseEnums

先查询出登录的用户,然后根据userId作为文件夹名创建文件夹,使用文件夹路径拼接数据库文件路径。

public enum  PrivateDataBaseEnums {
    DATEBASE("");  //实例对象
    private String value;  //属性
    PrivateDataBaseEnums(String value) {
    }

    //用于产生路径
    public String getValue(){
        UserDao userDao = BaseDaoFactory.getOurInstance().getBaseDao(UserDao.class, User.class);
        if(userDao != null){
            User currentUser = userDao.getCurrentUser();//1
            if(currentUser != null){
//                File file = new File("data/data/com.hongx.database");
//                if(!file.exists()){
//                    file.mkdirs();
//                }
//                //path = data/data/com.hongx.database/N001_login.db
//                return file.getAbsolutePath() + "/" + currentUser.getId() + "_login.db";
                //建议写入SD卡
                File file=new File(Environment.getExternalStorageDirectory(),"update/"+currentUser.getId());
                if(!file.exists())
                {
                    file.mkdirs();
                }
                return file.getAbsolutePath()+"/login.db";
            }
        }
        return null;
    }
}

注释1:获取当前登录的用户信息。


5 UserImg

@DbTable("tb_img")
public class UserImg {
    private String time;
    private String imgPath;

    public String getTime() {
        return time;
    }

    public void setTime(String time) {
        this.time = time;
    }

    public String getImgPath() {
        return imgPath;
    }

    public void setImgPath(String imgPath) {
        this.imgPath = imgPath;
    }

    @Override
    public String toString() {
        return "UserImg{" +
                "time='" + time + '\'' +
                ", imgPath='" + imgPath + '\'' +
                '}';
    }
}

6 PhotoDao

public class PhotoDao extends BaseDao<UserImg>{
}

7 使用

模拟登录操作:

public void login(View view) {
        User user = new User();
        user.setName(et_name.getText().toString());
        user.setPassword(et_pwd.getText().toString());
        user.setId(UUID.randomUUID().toString().substring(24));
        UserDao userDao = BaseDaoFactory.getOurInstance().getBaseDao(UserDao.class, User.class);
        userDao.insert(user);//1
        Toast.makeText(this, "执行成功!", Toast.LENGTH_SHORT).show();

        clickSubInsert();

        Intent intent = new Intent(LoginActivity.this, HxMainActivity.class);
        startActivity(intent);

    }

注释1:插入输入框中的用户信息到数据库,id是随机生成的不重复数。

   public void clickSubInsert() {
        UserImg img = new UserImg();
        img.setTime(new Date().toString());
        img.setImgPath("www.baidu.com/123123123.png");

        PhotoDao subDao = BaseDaoSubFactory.getInstance().getSubDao(PhotoDao.class, UserImg.class);
        subDao.insert(img);//1
        Toast.makeText(this, "执行成功!", Toast.LENGTH_SHORT).show();
    }

注释1:创建子数据库,并保存UserImg信息。

查看sd卡,不同用户的数据库文件都保存在该用户对应userId的文件夹下,如下图所示:

在这里插入图片描述

查询子数据库信息:

public void clickSelect(View view) {
        PhotoDao subDao = BaseDaoSubFactory.getInstance().getSubDao(PhotoDao.class, UserImg.class);
        UserImg where = new UserImg();
        List<UserImg> query = subDao.query(where);
        tv_time.setText(query.get(0).getTime());
        tv_img.setText(query.get(0).getImgPath());
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值