android从放弃到坚持放弃第六课(下)

使用LitePal操作数据库

  • 使用LitePal操作数据库
    • 使用LitePal简介
    • 创建和升级数据库
    • 添加数据
    • 更新数据
    • 删除数据
    • 查询数据
  • 总结
  • 问题

使用LitePal简介

这是我学习的第一个开源库——LitePal。LitePal是一款开源的Android数据库框架,它采用对象关系映射(ORM)的模式,并将我们平时开发的最常用的一些数据库功能进行了封装.GitHub:Click me

他在readme.md文件中写了Quick setup。不妨看看。

首先在闭包中添加

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
        exclude group: 'com.android.support', module: 'support-annotations'
    })
    compile 'com.android.support:appcompat-v7:25.3.1'
    testCompile 'junit:junit:4.12'
    compile 'org.litepal.android:core:1.5.1'
}

配置litepal.xml文件。右键app/src/main目录→New→Directory,创建一个assets目录,然后在assets目录下新建一个litepal.xml文件

new一个File→litepal.xml的文件


<litepal>
    
    <dbname value="Bookstore2" />

    
    <version value="1" />

    
    <list>
    list>

    

litepal>

This is the only configuration file, and the properties are simple.

  • dbname configure the database name of project.
  • version configure the version of database. Each time you want to upgrade database, plus the value here.
  • list configure the mapping classes.
  • storage configure where the database file should be stored. internal and external are the only valid options.

显而易见:标签用于指定数据库名,标签用于指定数据库版本号,标签用于指定所有的映射模型。

配置LitePalApplication,修改AndroidMainfest.xml:

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

配置好了。


创建和升级数据库

先创建一个类继承SQLiteOpenHelper,然后在onCreate()方法来编写建表语句来实现,而使用LitePal就方便多了。

我们使用的编程语言是面向对象编程语言,而使用的数据库则是关系型数据库,那么将面向对象的语言和面向关系的数据库之间建立一种映射关系,这就是对象关系映射。

我们可以用面向对象的四维来操作数据库。

新建Book2类

package com.example.wrjjrw.litepaltest;

import org.litepal.crud.DataSupport;

/**
 * Created by wrjjrw on 2017/4/12.
 */

public class Book extends DataSupport{

    private int id;

    private String author;

    private double price;

    private int pages ;

    private String name;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getAuthor() {
        return author;
    }

    public void setAuthor(String author) {
        this.author = author;
    }

    public double getPrice() {
        return price;
    }

    public void setPrice(double price) {
        this.price = price;
    }

    public int getPages() {
        return pages;
    }

    public void setPages(int pages) {
        this.pages = pages;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

Tips:可以alt+insert快速补全

添加litepal.xml:



<litepal>
    <dbname value = "Bookstore"> dbname>

    <version value = '1'>version>

    <list>
        <mapping class = "com.example.wrjjrw.litepaltest.Book">mapping>
    list>

litepal>

标签来声明我们要配置的映射模型类,注意一定要使用完整的类名。

xml不再贴代码了:

        Button createLitepalDatabase = (Button) findViewById(R.id.create_litepal);
        createLitepalDatabase.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Connector.getDatabase();
            }
        });

调用Connector.getDatabase()方法就是一次最简单的数据库操作,只要点击一下,就可以创建了.

若你想添加一个列(比如press),就可以直接修改Book里的代码,记得要generate他的getter和setter()函数。

如果你还想添加一张表,只需要新建一个类即可。

比如Category:

public class Category extends DataSupport{

    private int id;

    private String categoryName;

    private int categoryCode;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getCategoryName() {
        return categoryName;
    }

    public void setCategoryName(String categoryName) {
        this.categoryName = categoryName;
    }

    public int getCategoryCode() {
        return categoryCode;
    }

    public void setCategoryCode(int categoryCode) {
        this.categoryCode = categoryCode;
    }
}

然后在litepal.xml中添加一个mapping就可以了(别忘记了版本号。)



<litepal>
    <dbname value = "Bookstore"> dbname>

    <version value = '2'>version>

    <list>
        <mapping class = "com.example.wrjjrw.litepaltest.Book">mapping>
        <mapping class="com.example.wrjjrw.litepaltest.Category" />
    list>

litepal>

添加数据

在MainActivity:

java
Button addData = (Button) findViewById(R.id.Lite_add_database);
addData.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Book book = new Book();
book.setName("The Da Vinci Code");
book.setAuthor("Dan Brown");
book.setPages(454);
book.setPrice(16.96);
book.setPress("Unknow");
book.save();
}
});

可以看到这样的存储数据更简单。


更新数据

        Button updateData = (Button) findViewById(R.id.Lite_update_database);
        updateData.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Book book = new Book();
                book.setAuthor("The Lost Symbol");
                book.setPages(510);
                book.setPress("Unknow");
                book.save();
                book.setPrice(19.95);
                book.save();
            }
        });

对,没错,就这样。。。。

另外一种方式:

        Button updateData = (Button) findViewById(R.id.Lite_update_database);
        updateData.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Book book = new Book();
                book.setAuthor("The Lost Symbol");
                book.setPages(510);
                book.setPress("Unknow");
                book.save();
                book.setPrice(19.95);
                book.save();

                Book book2 = new Book();
                book2.setPrice(14.95);
                book2.setPress("Anchor");
                book2.updateAll("name = ? and author = ?", "The Lost Symbol", "Dan Brown");
            }
        });

我们调用了updateAll()的方法执行更新操作。(where参数更加简洁了,但是如果不指定条件语句的话,就是默认所有数据了)

可以看看他的源码:

    /**
     * Updates all records with details given if they match a set of conditions
     * supplied. This method constructs a single SQL UPDATE statement and sends
     * it to the database.
     * 
     * 
     * Person person = new Person();
     * person.setName("Jim");
     * person.updateAll("name = ?", "Tom");
     * 
* * This means that all the records which name is Tom will be updated into * Jim.
* * Note: 1. If you set a default value to a field, the corresponding * column won't be updated. Use {@link #setToDefault(String)} to update * columns into default value. 2. This method couldn't update foreign key in * database. So do not use setXxx to set associations between models. * * @param conditions * A string array representing the WHERE part of an SQL * statement. First parameter is the WHERE clause to apply when * updating. The way of specifying place holders is to insert one * or more question marks in the SQL. The first question mark is * replaced by the second element of the array, the next question * mark by the third, and so on. Passing empty string will update * all rows. * @return The number of rows affected. */
public synchronized int updateAll(String... conditions) { try { UpdateHandler updateHandler = new UpdateHandler(Connector.getDatabase()); int rowsAffected = updateHandler.onUpdateAll(this, conditions); getFieldsToSetToDefault().clear(); return rowsAffected; } catch (Exception e) { throw new DataSupportException(e.getMessage(), e); } }
* Note:  1. If you set a default value to a field, the corresponding
* column won't be updated. Use {@link #setToDefault(String)} to update
* columns into default value. 2. This method couldn't update foreign key in
* database. So do not use setXxx to set associations between models.

有没有看到上面这句话,如果我们想把值改成默认值的话,就需要使用

                book.setToDefault("pages");
                book.updateAll();

上面这句话,我们更新了所有的书的页数,都是0了。


删除数据

        Button deleteButton = (Button) findViewById(R.id.Lite_delete_database);
        deleteButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                DataSupport.deleteAll(Book.class, "price < ?", "15");
            }
        });

删除和跟新差不多是一个道理


查询数据

讲道理,这里应该是最复杂的。在这里,问题就不大了。

这里只要用泛型就可以了findAll了,炒鸡方便

        Button queryBotton = (Button) findViewById(R.id.Lite_query_database);
        queryBotton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                List books = DataSupport.findAll(Book.class);
                for(Book book:books){
                    Log.d(Tag, "Book name is " + book.getName());
                    Log.d(Tag, "Book author is " + book.getAuthor());
                    Log.d(Tag, "Book pages is " + book.getPages());
                    Log.d(Tag, "Book price is " + book.getPrice());
                    Log.d(Tag, "Book press is " + book.getPress());
                    Toast.makeText(MainActivity.this, book.getName()+"costs"+book.getPrice(),
                            Toast.LENGTH_LONG).show();
                }

            }
        });

除此之外还有以下语句:

Book firstBook = DataSupport.findFirst(Book.class);
Book lastBook = DataSupport.findLast(Book.class);
//只查询几列的数据
List books2 = DataSupport.select("name", "author").find(Book.class);
//指定查询的约束条件
List books3 = DataSupport.where("pages > ?", "400").find(Book.class);
//指定结果的排序 desc降序, asc或者默认即升序
List books4 = DataSupport.order("price desc").find(Book.class);
//指定查询结果的数量
List books5 = DataSupport.limit(3).find(Book.class);
// 指定结果的偏移量,比如要查询表中的第2,3,4条数据
List books6 = DataSupport.limit(3).offset(1).find(Book.class);
//将以上方法组合
List books7 = DataSupport.select("name", "author", "pages")
.where("pages > ?", "400")
.order("pages")
.limit(3)
.offset(1)
.find(Book.class);
//LitePal也同样支持原生的SQL来查询
Cursor c = DataSupport.findBySQL("select * from Book where pages > " +
"? and price < ?","400","20");

//但原生的查询也需要原生的读取,因为上面的是Cursor对象。


总结

数据库基础知识不扎实,需要好好巩固一下。

总共有三部分知识,文件储存,IO编程不熟练

SharedPreferences存储以及数据库知识,需要勤加练习呐。。


问题:

  1. Error:Execution failed for task ‘:app:transformClassesWithDexForDebug’.

    com.android.build.api.transform.TransformException: com.android.ide.common.process.ProcessException: java.util.concurrent.ExecutionException: com.android.dex.DexException: Multiple dex files define Lorg/litepal/LitePal;

答:依赖包重复了。

  1. 有没有文档可供查询:

答:Click me

你可能感兴趣的:(从入门到giveup)