美文网首页1-Android开发知识Android开发经验谈Android开发
LitePal学习(四)——表关联及相关查询

LitePal学习(四)——表关联及相关查询

作者: 奔跑的佩恩 | 来源:发表于2017-11-29 15:58 被阅读641次

    前言

    之前都是讲的单表查询,今天讲下类中包含类对象的情况,即表关联相关的知识
    参考文章:
    Android数据库高手秘籍(四)——使用LitePal建立表关联
    Android数据库高手秘籍(七)——体验LitePal的查询艺术
    官网

    今天讲的内容是结合之前的文章
    LitePal学习(三)——增删改查
    进行讲解的。
    这章涉及内容主要有

    • 表中含集合数据的查询
    • 表中含对象数据的查询

    下面一步步讲解

    一.熟悉下基本表建立后的结构

    先抛出一个基本的Person表代码出来:

    package com.android.model;
    
    /**
     * Title:
     * Description:
     * <p>
     * Created by pei
     * Date: 2017/11/23
     */
    public class Person extends DataBaseModel{
    
        private String name;
        private String sex;
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public String getSex() {
            return sex;
        }
    
        public void setSex(String sex) {
            this.sex = sex;
        }
    }
    

    很基础的model代码,然后是在litepal.xml中注册person表:

    <?xml version="1.0" encoding="utf-8"?>
    <litepal>
        <!--数据库文件名-->
        <dbname value="demo" ></dbname>
        <!--数据库版本号-->
        <version value="1" ></version>
        <!--表名-->
        <list> <mapping class="com.android.model.Person"></mapping>  </list>
    </litepal>
    

    在mainActivity中执行存储代码:

                   //存储
                    Person person = new Person();
                    person.setName("花花");
                    person.setSex("女");
                    person.save();
    

    ok,接下来看看person表中的数据,litePal数据库的默认存储路径和sqlite的是一样的,按路径步骤找到数据库,打开person表如下:


    2.png

    看上图这里需要注意的是person表会自动生成key名为id的自增主键

    二.需要存储的对象结构

    现在我们的需求变成是Person类中含一个User对象,类似下面代码:

    package com.android.model;
    
    /**
     * Title:
     * Description:
     * <p>
     * Created by pei
     * Date: 2017/11/23
     */
    public class Person extends DataBaseModel{
    
        private String name;
        private String sex;
        private User user;
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public String getSex() {
            return sex;
        }
    
        public void setSex(String sex) {
            this.sex = sex;
        }
    
        public User getUser() {
            return user;
        }
    
        public void setUser(User user) {
            this.user = user;
        }
    }
    

    User为一个不同于Person的对象,当然也要用一个单独的表存,需要在litepal.xml中注册User表:

    <?xml version="1.0" encoding="utf-8"?>
    <litepal>
        <!--数据库文件名-->
        <dbname value="demo" ></dbname>
        <!--数据库版本号-->
        <version value="1" ></version>
        <!--表名-->
        <list> <mapping class="com.android.model.Person"></mapping>  </list>
        <list> <mapping class="com.android.model.User"></mapping>  </list>
    </litepal>
    

    然后是User类代码:

    package com.android.model;
    
    /**
     * Title:
     * Description:
     * <p>
     * Created by pei
     * Date: 2017/11/23
     */
    public class User extends DataBaseModel{
    
        private String name;
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
    }
    
    

    因为Person和User为两张不同的表,他们的关系类似于Peron为主表,User为子表,当操作Person对象的时候,里面的User对象也要一起操作。也就是当person存储的时候,user也要存储,person查询的时候,user也要查询等等。
    所以Person在执行setUser(User user)方法的时候,要进行User的存储,
    Person在执行getUser()方法的时候要进行User的查询。
    根据以上逻辑,先改造Person类:

    package com.android.model;
    
    import com.android.util.CollectionUtil;
    
    import org.litepal.crud.DataSupport;
    
    import java.util.List;
    
    /**
     * Title:
     * Description:
     * <p>
     * Created by pei
     * Date: 2017/11/23
     */
    public class Person extends DataBaseModel{
    
        //person表中自动生成列名为id的自增key,此处拿出来是为了方便子表查询
        private long id;
    
        private String name;
        private String sex;
        private User user;
    
        public long getId() {
            return id;
        }
    
        public void setId(long id) {
            this.id = id;
        }
    
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public String getSex() {
            return sex;
        }
    
        public void setSex(String sex) {
            this.sex = sex;
        }
    
    
        public User getUser() {
            //子表中会生成一个关联父表的id供父表查询,且字表中id生成符合规则:"父表类名小写_id"
            //若父表为Person类(父表中会自动生成一个id自增列),子表为User类,则字表中会自动生成字段person_id对应父表中id,以供查询
            String linkId=this.getClass().getSimpleName().toLowerCase();
            List<User>list= DataSupport.where(linkId+"_id=?",String.valueOf(id)).find(User.class);
            if(CollectionUtil.isEmpty(list)){
                user= null;
            }else{
                user=list.get(0);
            }
            return user;
        }
    
        public void setUser(User user) {
            //set的时候存储子表数据
            user.save();
            this.user = user;
        }
    }
    

    这里先注重看setUser(User user)方法:

       public void setUser(User user) {
            //set的时候存储子表数据
            user.save();
            this.user = user;
        }
    

    person在setUser的同时,user执行了存储代码。

    然后我们在MainActivity中执行存储:

                     //存储
                    Person person=new Person();
                    person.setName("花花");
                    person.setSex("女");
                    User user=new User();
                    user.setName("打雷");
                    person.setUser(user);
    
                    Person person2=new Person();
                    person2.setName("小鸣");
                    person2.setSex("男");
                    User user2=new User();
                    user2.setName("打虎");
                    person2.setUser(user2);
                    List<Person> personList=new ArrayList<>();
    
                    personList.add(person);
                    personList.add(person2);
                    //批量存储
                    DataSupport.saveAll(personList);
    

    此处我批量插入两条person数据,然后看看person表中数据:


    3.png

    user表中数据:


    4.png
    看到没,user表中首先具备自增主键id,同时还产生了一个person_id,而person即为主表Person类的类名小写加上下划线id
    在litePal中这种主子表的联结中uer表中的person_id和person表中的id一一对应。

    ok,下面再来解释改造的person类中几个疑点:
    1.person表中为什么要多写一个id属性,如下:

    private long id;
    

    long属性的命名可以随便写么?如 long pramaryId 等?

    答案是不行,id这个列是person建表时自动生成(见前面解释),包括它的名称只能是id,至于为什么要把这个id拿出来,是为了根据perosn表中id与user表中person_id的关系方便查询user表中的数据

    2.Person类中的getUser()方法为什么要那么写?

       public User getUser() {
            //子表中会生成一个关联父表的id供父表查询,且字表中id生成符合规则:"父表类名小写_id"
            //若父表为Person类(父表中会自动生成一个id自增列),子表为User类,则字表中会自动生成字段person_id对应父表中id,以供查询
            String linkId=this.getClass().getSimpleName().toLowerCase();
            List<User>list= DataSupport.where(linkId+"_id=?",String.valueOf(id)).find(User.class);
            if(CollectionUtil.isEmpty(list)){
                user= null;
            }else{
                user=list.get(0);
            }
            return user;
        }
    

    关键在于以下这段代码:

    List<User>list= DataSupport.where(linkId+"_id=?",String.valueOf(id)).find(User.class);
    

    其实质是根据user表中的pseron_id来查询user数据,鉴于person表中id与user表中person_id的关系,所以做以上查询

    以上是Pseron类中只含User对象的情况,下面讲Person表中含user的list的情况:

    三.表中含集合数据的查询

    修改下Peron类即可:

    package com.android.model;
    
    import com.android.util.CollectionUtil;
    
    import org.litepal.crud.DataSupport;
    
    import java.util.ArrayList;
    import java.util.List;
    
    /**
     * Title:
     * Description:
     * <p>
     * Created by pei
     * Date: 2017/11/23
     */
    public class Person extends DataBaseModel{
    
        //person表中自动生成列名为id的自增key,此处拿出来是为了方便子表查询
        private long id;
    
        private String name;
        private String sex;
        private List<User>userList;
    
        public long getId() {
            return id;
        }
    
        public void setId(long id) {
            this.id = id;
        }
    
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public String getSex() {
            return sex;
        }
    
        public void setSex(String sex) {
            this.sex = sex;
        }
    
    
        public List<User> getUserList() {
            //子表中会生成一个关联父表的id供父表查询,且字表中id生成符合规则:"父表类名小写_id"
            //若父表为Person类(父表中会自动生成一个id自增列),子表为User类,则字表中会自动生成字段person_id对应父表中id,以供查询
            String linkId=this.getClass().getSimpleName().toLowerCase();
            List<User>list= DataSupport.where(linkId+"_id=?",String.valueOf(id)).find(User.class);
            if(list==null){
                list=new ArrayList<>();
            }
            return list;
        }
    
        public void setUserList(List<User> userList) {
            //批量存储userList
            if(!CollectionUtil.isEmpty(userList)){
                DataSupport.saveAll(userList);
            }
            this.userList = userList;
        }
    }
    
    

    MainActivity中代码这里就不做多的说明了。

    ok,今天关于litepal外链的讲解就到这里了,谢谢大家。

    相关文章

      网友评论

        本文标题:LitePal学习(四)——表关联及相关查询

        本文链接:https://www.haomeiwen.com/subject/ufmsbxtx.html