第六章《第一行代码》4.使用Litepal操作数据库

我博客的相关说明

这部分算是对3.数据库储存的补充升级,介绍如何通过LitePal来进行CRUD操作。

4. 使用LitePal操作数据库

4.1 LitePal简介

LitePal是一款开源的Android数据库框架,它采用了对象关系映射(ORM)的模式,将平时开发最常用的一些数据库功能进行了封装,使得不用编辑一条SQL语句就能完成CRUD的工作。LitePal使用文档

4.2 LitePal配置

app/build.gradle文件中声明该开源库的引用就可以了。

  • 4.2.1 在dependencies闭包中添加:compile 'org.litepal.android:core:1.4.1'
    AS 3.X的版本要把compile换成implementation哦
dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'androidx.appcompat:appcompat:1.0.2'
    implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'androidx.test.ext:junit:1.1.0'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'
    implementation 'org.litepal.android:core:1.4.1'
}
  • 4.2.2 配置litepal.xml文件
    右击app/src/main目录点击new→Directory,创建一个assets目录。在这里插入图片描述
<?xml version="1.0" encoding="utf-8" ?>
<litepal>
    <dbname value="BookStore1"></dbname>
    <version value="1"></version>
    <list>
    </list>
</litepal>

其中<dbname>标签用来指定数据库名,<version>用于指定数据库版本号,用于指定所有的映射类型。

  • 4.2.3 配置AndroidManifest.xml文件
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.ifinder.mydaily4">

    <application
        android:name="org.litepal.LitePalApplication">
        ···
    </application>

</manifest>

4.3 创建与升级数据库

LitePal采取对象关系映射(ORM)的模式,将Java的面向对象的语言和SQL的结构化查询语言建立对应关系。之后就可以通过面向对象的思想操作数据库。

①.建立对应的类

与SQLiteOpenHelper不同,使用LitePal建表时,我们可以先建立一个Book类,而类的属性就是之前表中的内容。然后通过Java bean来操作类中的各个属性。

public class Book1 extends DataSupport {
    private int id;
    private String name;
    private String author;
    private double price;
    private int pages;

    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;
    }
   ···
}

生成setter和getter方法的快捷键(AS 3.5):定义好各个属性之后,选中,按alt+shift+insert在弹出菜单中选择Getter and Setter
Book类对应数据库中的Book表,类中的每一个字段对应了数据库表中的每一列。

②.将建立的类添加到映射模型中

修改litepal.xml中的代码

<?xml version="1.0" encoding="utf-8" ?>
<litepal>
    ···
    <list>
        <mapping class = "com.ifinder.mydaily4.Book1"></mapping>
    </list>
</litepal>

<mapping>标签来声明配置的映射模型类。只要建立映射在<list>标签下配置就可以。

③.在主程序中修改代码
public class LitePal_test extends AppCompatActivity {
    private Button BTN_create,BTN_delate,BTN_query,BTN_update;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.lite_pal_test);
        BTN_create = findViewById(R.id.Btn_create);
        BTN_create.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                LitePal.getDatabase();
            }
        });
    }
}

运行程序,点击Create按钮。使用adb shell查看数据库。
到这里如果报错的话可以去看这一篇文章哦!
在这里插入图片描述在这里插入图片描述

可以看到BookStore1数据库和Book1表已经建立好了。
可以通过.schema命令来查看建表语句:
在这里插入图片描述
LitePal还有一个很重要的功能就是能够在升级数据库的同时保存我们先前的数据。
让我们在Book1表里加入一列press(出版社),并且再建立一张Category1表:

  • 建立Category1类
public class Category1 {
   private int id;
   private String categoryName;
   private int categoryCode;

   public int getId() {
       return id;
   }

   public void setId(int id) {
       this.id = id;
   }
  ···
}
  • 向Book1中添加press
public class Book1 {
    ···
    private String press;

    public String getPress() {
        return press;
    }

    public void setPress(String press) {
        this.press = press;
    }
    ···
}
  • 在litepal.xml文件中配置映射类型
<litepal>
    <dbname value="BookStore1"></dbname>
    <version value="2"></version>
    <list>
        <mapping class="com.ifinder.mydaily4.Book1"></mapping>
        <mapping class="com.ifinder.mydaily4.Category1"></mapping>
    </list>
</litepal>

运行程序,点击Create按钮。用adb shell查看数据库。
在这里插入图片描述
可以看见,更新版本后,press列和Category表都操作成功了。

4.4 LitePal添加数据

使用LitePal储存数据,只要实例化之前创建的表模型,再将所有数据都用setter()方法设置,最后调用save()方法就可以了!
修改主程序文件:

public class LitePal_test extends AppCompatActivity {
    private Button BTN_create,BTN_adddata,BTN_delate,BTN_query,BTN_update;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.lite_pal_test);
        ···
        BTN_adddata.findViewById(R.id.Btn_adddata);
        BTN_adddata.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Book1 book1 = new Book1();
                book1.setName("The Da Vinci Code");
                book1.setAuthor("Dan Browm");
                book1.setPages(355);
                book1.setPrice(36.7);
                book1.setPress("Unknown");
                book1.save();
            }
        });
    }
}

点击Add按钮,使用adb shell工具查看数据库:
在这里插入图片描述
可以看到我们的各个信息已经添加到了数据库里!

4.5 LitePal更新数据

①.save()方法更新对象

更新LitePal数据最简单的方法是将已储存的对象重新赋值,然后调用save()方法。

已储存对象:
对于LitePalestine,已储存的对象是根据调用model.isSaved()方法的结果来判断的,true为已储存,false为未储存。
调用model.save()方法添加数据、model对象是通过API查询出来的结果,二者都会使model.save()方法的返回值为true

修改主程序代码,添加新的书籍信息:

public class LitePal_test extends AppCompatActivity {
    private Button BTN_create,BTN_adddata,BTN_delate,BTN_query,BTN_update;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.lite_pal_test);
        ···
        BTN_update = findViewById(R.id.Btn_update);
        BTN_update.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Book1 book1 = new Book1();
                book1.setName("The Lost Symbol");
                book1.setAuthor("Dan Brown");
                book1.setPages(430);
                book1.setPrice(39.8);
                book1.setPress("Unknown");
                book1.save();
                book1.setPrice(42.9);
                book1.save();
            }
        });
    }
}

这里添加数据后,book1调用了save()方法,而更改价格后再一次调用save()方法回让LitePal认为数据是已经储存的,所以不会向表中添加新数据,而是会直接更新当前数据。运行程序,点击update按钮,查看数据库内文件。
在这里插入图片描述
可以看到,第二条数据成功添加,并且price也已经更新为相应的42.9了。

②.updateAll()方法更新对象

修改主程序代码:

public class LitePal_test extends AppCompatActivity {
    private Button BTN_create,BTN_adddata,BTN_delate,BTN_query,BTN_update;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ···
        BTN_update = findViewById(R.id.Btn_update);
        BTN_update.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Book1 book1 = new Book1();
                book1.setPrice(29.8);
                book1.setPress("Anchor");
                book1.updateAll("name = ? and Author = ?","The Lost Symbol","Dan Brown");
            }
        });
    }
}

可以看到,updateAll()方法制定了一个约束条件,这里指定书名为The Lost Symbol作者为Dan Brown的书籍价格更新为29.8。让我们运行程序查看结果。
在这里插入图片描述
可以看到,数据更新成功了。

LitePal更新默认值时,时不能调用set方法的,这时候更新就可以这么写:

Book1 book1 = new Book1();
book1.setToDefault("price");
book1.updateAll("name = ? and Author = ?","The Lost Symbol","Dan Brown");

4.6 LitePal删除数据

①.delete()方法删除数据

该方法和更新数据时的save()方法很像,当对象被识别为已储存对象时,该方法才会被执行。

public void onClick(View v) {
                Book1 book1 = new Book1();
                book1.setName("海边的卡夫卡");
                book1.setAuthor("村上村树");
                book1.setPages(430);
                book1.setPrice(39.8);
                book1.setPress("Unknown");
                book1.save();
                book1.delete();
            }

点击按钮执行这个方法后可以看到数据库内容没有什么变化,因为该条信息添加成功后立即被delete()方法删除了。

②.deleteAll()方法删除数据

修改主程序代码:

public class LitePal_test extends AppCompatActivity {
    private Button BTN_create,BTN_adddata,BTN_delate,BTN_query,BTN_update;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ···
        BTN_delate = findViewById(R.id.Btn_delate);
        BTN_delate.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                DataSupport.deleteAll(Book1.class,"price > ?","30");
            }
        });
    }
}

这里我们希望删除价格大于40的书籍信息。运行程序点击delete按钮,查看数据库。
在这里插入图片描述
可以看到price大于30的数据已经被我们成功删除了。

  • deleteAll()updateAll()一样,如果不指定约束条件的话,会删除/更新所有数据。

4.7 LitePal查询数据

①.findAll()方法查询数据

List<Book1> books = DataSupport.findAll(Book.class);
findAll()方法返回的是一个Book类型的List集合。LitePal会自动帮我们完成赋值操作。
修改主程序代码:

public class LitePal_test extends AppCompatActivity {
    private Button BTN_create,BTN_adddata,BTN_delate,BTN_query,BTN_update;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ···
        BTN_query = findViewById(R.id.Btn_query);
        BTN_query.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                List<Book1> books = DataSupport.findAll(Book1.class);
                StringBuilder sb = new StringBuilder();
                for(Book1 book1: books){
                    sb.append(book1.getName()+"\n");
                    sb.append(book1.getAuthor()+"\n");
                    sb.append(book1.getPages()+"\n");
                    sb.append(book1.getPrice()+"\n");
                    sb.append(book1.getPress()+"\n");
                }
                Toast.makeText(getApplicationContext(),sb,Toast.LENGTH_SHORT).show();
            }
        });
    }
}

在for循环里遍历Book1对象,然后使用StringBuilder拼接得到的查询数据。点击query按钮:
在这里插入图片描述
可以看到,查询的数据已经成功打印了!

②.连缀提高查询精度
  • 查询最后一条数据findLast()
    Book1 lastBook = DataSupport.findLast(Book1.class);
  • 查询第一条数据findFirst()
    Book1 firstBook = DataSupport.findFirst(Book1.class);
  • 查询哪几列数据select()
    List<Book1> books = DataSupport.select("name").find(Book1.class);
  • 指定查询约束条件where()
    List<Book1> books = DataSupport.where("pages > ?","400").find(Book1.class);
  • 指定查询结果排序方式order()
    ``List books = DataSupport.order(“price desc”).find(Book1.class);```
    desc表示降序排列,asc或不写表示升序排列
  • 指定查询结果数量limit()
    List<book1> books = DataSupport.limit(3).find(Book1.class);
  • 指定查询结果偏移量offset()
    List<Book1> books = DataSupport.limit(3).offset(3).find(Book1.class);
    将连缀组合使用的话,可以执行更复杂的查询操作;
List<Book1> books = DataSupport.select("name","author","pages")
							   .where("pages > ?","400")
							   .order("pages")
							   .limit(10)
							   .offset(10)
							   .find(Book1.class);

这段代码就表示,查询Book1表中第11~12条满足页数大于400这个条件的name、author、pages这三列数据,并且将查询结果按pages升序排列。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值