使用LitePal时出现的问题

更新为默认值时出现问题

问题描述

定义一个Student表。

public class Student extends LitePalSupport {
    
    
    //主键
    public long id;
    //姓名
    public String name;
    //是否是男生,且设置默认值为false
    public boolean isMale = false;
    //学号
    public String sno;

    @Override
    public String toString() {
    
    
        return "Student{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", isMale=" + isMale +
                ", sno='" + sno + '\'' +
                '}';
    }
}

保存一条学生记录。

        Student student = new Student();
        student.name = "张三";
        student.isMale = true;
        student.sno = "0001";
        student.save();

执行如下代码,更新isMale字段

        Student student = LitePal.where("name = ?", "张三")
                .findFirst(Student.class);
        Logger.d("原student: "+student);
        student.isMale = false;//更新isMale字段为false
        boolean isUpdateSucc = student.update(student.id) > 0;
        Logger.d("更新isMale是否成功:"+isUpdateSucc);
        student = LitePal.where("name = ?", "张三")
                .findFirst(Student.class);
        Logger.d("新student: "+student);

输出日志如下:

原student: Student{
    
    name='张三', isMale=true, sno='0001'}
更新isMale是否成功:true
新student: Student{
    
    name='张三', isMale=true, sno='0001'}

从日志可以看出,isMale字段没有更新成功。
原因是LitePal的update方法仅当字段值不为默认值时才会更新该字段。

解决办法

方法一:使用setToDefault方法

        Student student = LitePal.where("name = ?", "张三")
                .findFirst(Student.class);
        Logger.d("原student: "+student);
//        student.isMale = false;//更新isMale字段为false
        student.setToDefault("isMale");//更新isMale字段为false
        boolean isUpdateSucc = student.update(student.id) > 0;
        Logger.d("更新isMale是否成功:"+isUpdateSucc);
        student = LitePal.where("name = ?", "张三")
                .findFirst(Student.class);
        Logger.d("新student: "+student);

输出日志如下:

原student: Student{
    
    name='张三', isMale=true, sno='0001'}
更新isMale是否成功:true
新student: Student{
    
    name='张三', isMale=false, sno='0001'}

方法二:改用save()方法保存数据

        Student student = LitePal.where("name = ?", "张三")
                .findFirst(Student.class);
        Logger.d("原student: "+student);
        student.isMale = false;//更新isMale字段为false
        boolean isUpdateSucc = student.save();//改成用save()保存字段
        Logger.d("更新isMale是否成功:"+isUpdateSucc);
        student = LitePal.where("name = ?", "张三")
                .findFirst(Student.class);
        Logger.d("新student: "+student);

输出日志如下:

原student: Student{
    
    name='张三', isMale=true, sno='0001'}
更新isMale是否成功:true
新student: Student{
    
    name='张三', isMale=false, sno='0001'}

save()方法是将各字段直接覆盖,不论当前字段值是否为默认值。
但是要注意的是,如果表存在与之关联的另一张表时,不建议用这种方法,因为会将关联表的外键清空。

参考办法:
Update data:不能从其他类型更新到0

更新关联表时出现问题

问题描述

Student和Book是一对多的关系。

public class Student extends LitePalSupport {
    
    
    //主键
    public long id;
    //姓名
    public String name;
    //是否是男生,且设置默认值为false
    public boolean isMale = false;
    //学号
    public String sno;

    public List<Book> books = new ArrayList<>();

    @Override
    public String toString() {
    
    
        return "Student{" +
                "name='" + name + '\'' +
                ", isMale=" + isMale +
                ", sno='" + sno + '\'' +
                ", books=" + books +
                '}';
    }
}

public class Book extends LitePalSupport {
    
    
    //主键
    public long id;
    //书名
    public String name;

    public Student student;

    @Override
    public String toString() {
    
    
        return "Book{" +
                "name='" + name + '\'' +
                '}';
    }
}

为“张三”增加2本书

        Student student = LitePal.where("name = ?", "张三").findFirst(Student.class);

        Book chineseBook = new Book();
        chineseBook.name = "语文";
        chineseBook.student = student;
        chineseBook.save();

        Book mathBook = new Book();
        mathBook.name = "数学";
        mathBook.student = student;
        mathBook.save();

这时Student表和Book表如下
在这里插入图片描述
在这里插入图片描述
接下来,更新张三的学号,并为张三再加一本书

        Student student = LitePal.where("name = ?", "张三").findFirst(Student.class);
        Logger.d("查询到的student: "+student);
        student.sno = "0002";
        student.save();

        Book englishBook = new Book();
        englishBook.name = "英语";
        englishBook.student = student;
        englishBook.save();

执行上面代码后,输出日志如下

查询到的student: Student{
    
    name='张三', isMale=true, sno='0001', books=[]}

这时Student表和Book表如下

在这里插入图片描述
在这里插入图片描述
从图中可以看出原本的语文书和数学书的外键被置空了。因为LitePal默认的模式就是懒查询。所以查询出张三时,张三的books为空集合。这时候直接调用save()方法,LitePal会认为你想清除关联关系,所以把语文书和数学书的外键都置空了。

解决办法

方法一:改用update()更新

        Student student = LitePal.where("name = ?", "张三").findFirst(Student.class);
        Logger.d("查询到的student: "+student);
        student.sno = "0002";
        student.update(student.id);

        Book englishBook = new Book();
        englishBook.name = "英语";
        englishBook.student = student;
        englishBook.save();

执行上面的代码,输出日志如下

查询到的student: Student{
    
    name='张三', isMale=true, sno='0001', books=[]}

这时Student表和Book表如下
在这里插入图片描述
在这里插入图片描述

方法二:改用激进查询

        Student student = LitePal.where("name = ?", "张三").findFirst(Student.class, true);//此处改用激进查询
        Logger.d("查询到的student: "+student);
        student.sno = "0002";
        student.save();

        Book englishBook = new Book();
        englishBook.name = "英语";
        englishBook.student = student;
        englishBook.save();

执行上面的代码后,输出如下日志

查询到的student: Student{
    
    name='张三', isMale=true, sno='0001', books=[Book{
    
    name='语文'}, Book{
    
    name='数学'}]}

Student表和Book表的结果和方法一相同。

参考办法:
数据表中的数据更新 使用save 不使用update 随后会导致用该表的id作为外键的表数据查询不到

拼接where查询语句时出现的问题

问题描述

拼接字段值为汉字时抛出异常

    String whereName = "name = 张三";
    Student student = LitePal.where(whereName).findFirst(Student.class);
    Logger.d("查询到的student: "+student);

执行上面的代码会抛出如下异常
LitePalSupportException: no such column: 张三 (code 1): , while compiling: SELECT * FROM student WHERE name = 张三 LIMIT 1

拼接字段值为第一个数字为0的数字字符串时查询不出记录

   String whereSno = "sno = 0001";
   Student student = LitePal.where(whereSno).findFirst(Student.class);
   Logger.d("查询到的student: "+student);

执行上面代码,输出日志如下

查询到的student: null

解决办法

方法一:拼接时字段值用单引号括起来

//  String whereName = "name = 张三";
    String whereName = "name = '张三'";
    Student student = LitePal.where(whereName).findFirst(Student.class);
    Logger.d("查询到的student: "+student);

//  String whereSno = "sno = 0001";
    String whereSno = "sno = '0001'";
    Student student = LitePal.where(whereSno).findFirst(Student.class);
    Logger.d("查询到的student: "+student);

执行上面代码后,输出日志如下

查询到的student: Student{
    
    name='张三', isMale=true, sno='0001'}
查询到的student: Student{
    
    name='张三', isMale=true, sno='0001'}

方法二:使用LitePal的占位符(?)

    Student student = LitePal.where("name = ?", "张三").findFirst(Student.class);
    Logger.d("查询到的student: "+student);

    student = LitePal.where("sno = ?", "0001").findFirst(Student.class);
    Logger.d("查询到的student: "+student);

执行上面代码后,输出日志如下

查询到的student: Student{
    
    name='张三', isMale=true, sno='0001'}
查询到的student: Student{
    
    name='张三', isMale=true, sno='0001'}

猜你喜欢

转载自blog.csdn.net/jiejingguo/article/details/124496642