解读郭神LitePal源码-litepal.xml的解析

在开始使用LitePal时,要求在项目的assets目录下新建一个litepal.xml文件:

<?xml version="1.0" encoding="utf-8"?>
<litepal>
    <dbname value="Questionnaire"/>

    <version value="1"></version>

    <list>
        <mapping class="com.aliao.parser.entity.UserInfo"></mapping>
        <mapping class="com.aliao.parser.entity.SurveyInfo"></mapping>
    </list>

</litepal>

该配置文件用来设定数据库的名字、版本号以及所有的对象关系映射模型。

什么是对象关系映射模型?

因为sqlite数据库是关系型数据库,而编程是面向对象的,为了使用面向对象的方式来操作数据库,所以在关系数据库和实体对象之间做了一个映射,这样在进行数据库操作的时候,我们只需要操作实体对象即可,不需要直接处理sql语句。

在litepal.xml文件的<list>标签里来设置需要进行映射的对象,数据库里的每一张的表都对应一个实体对象类。

一个litepal.xml文件让我们在进行数据库基本信息配置上变得异常方便,那程序是怎么来获取到我们配置后的信息呢?

首先需要通过解析xml文件来获取到数据库名,版本信息,以及需要映射的对象。在Litepal里使用SAXParser来解析xml,那解析后的信息放在哪里呢,是由LitePalAttr该实体类来接收从litepal.xml里读取到的所有属性值。

本来想直接贴源码的,还是立足源码自己手动实现一下好了,勤奋宝宝在咬我,biaji biaji biaji~~~

创建一个LitePalAttr实体类,对应litepal.xml的属性及其set/get方法:

package com.aliao.parser.entity;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by aliao on 2015/6/4.
 */
public class LitePalAttr {

    private static LitePalAttr litePalAttr;

    //数据库版本号
    private int version;
    //数据库名
    private String dbName;
    //所有在数据库中想要有映射关系的实体类
    private List<String> classNames;

    public int getVersion() {
        return version;
    }

    public void setVersion(int version) {
        this.version = version;
    }

    public String getDbName() {
        return dbName;
    }

    public void setDbName(String dbName) {
        this.dbName = dbName;
    }

    /**
     * 在sqlite里table_schema表示自动生成的,这里一定要手动添加进去
     * table_schema用来查看数据库的元数据,这里的元数据包括表名及表类型
     * @return
     */
    public List<String> getClassNames() {
        if (classNames == null){
            classNames = new ArrayList<>();
            classNames.add("com.aliao.parser.entity.Table_Schema");
        }else if (classNames.isEmpty()){
            classNames.add("com.aliao.parser.entity.Table_Schema");
        }
        return classNames;
    }

    public void addClassName(String className){
        getClassNames().add(className);
    }

    /**
     * 这里用双重检测来实现单例模式
     * 整个程序创建一个唯一的litePalAttr对象,可以通过这个对象拿到数据库的基本信息
     * @return
     */
    public static LitePalAttr getIntance(){
        if (litePalAttr == null){
            synchronized (LitePalAttr.class){
                if (litePalAttr == null){
                    litePalAttr = new LitePalAttr();
                }
            }
        }
        return litePalAttr;
    }

    @Override
    public String toString() {
        return "数据库名称:"+dbName+" ,数据库版本"+version;
    }
}

接下来就是如何解析litepal.xml的问题了,源码里郭神使用SAXParser来解析,如何使用SAXParser来解析一个xml文件的知识会单独写篇blog总结一下,这里就不啰嗦直接上吧。

解析litepal.xml需要创建两个类:

LitePalParser:这个类主要的操作就是创建解析器,然后解析文档

LitePalContentHandler(继承DefaultHandler):解析文档的具体实现,开始对文档进行扫描分析,将xml里的属性值保存到LitePalAttr的对应属性里。

创建解析器:

package com.aliao.parser.entity;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by aliao on 2015/6/4.
 */
public class LitePalAttr {

    private static LitePalAttr litePalAttr;

    //数据库版本号
    private int version;
    //数据库名
    private String dbName;
    //所有在数据库中想要有映射关系的实体类
    private List<String> classNames;

    public int getVersion() {
        return version;
    }

    public void setVersion(int version) {
        this.version = version;
    }

    public String getDbName() {
        return dbName;
    }

    public void setDbName(String dbName) {
        this.dbName = dbName;
    }

    /**
     * 在sqlite里table_schema表示自动生成的,这里一定要手动添加进去
     * table_schema用来查看数据库的元数据,这里的元数据包括表名及表类型
     * @return
     */
    public List<String> getClassNames() {
        if (classNames == null){
            classNames = new ArrayList<>();
            classNames.add("com.aliao.parser.entity.Table_Schema");
        }else if (classNames.isEmpty()){
            classNames.add("com.aliao.parser.entity.Table_Schema");
        }
        return classNames;
    }

    public void addClassName(String className){
        getClassNames().add(className);
    }

    /**
     * 这里用双重检测来实现单例模式
     * 整个程序创建一个唯一的litePalAttr对象,可以通过这个对象拿到数据库的基本信息
     * @return
     */
    public static LitePalAttr getIntance(){
        if (litePalAttr == null){
            synchronized (LitePalAttr.class){
                if (litePalAttr == null){
                    litePalAttr = new LitePalAttr();
                }
            }
        }
        return litePalAttr;
    }

    @Override
    public String toString() {
        return "数据库名称:"+dbName+"\n数据库版本:"+version+"\n\n数据库映射对象类名:";
    }
}

将xml的属性值保存到实体类对应属性里:

package com.aliao.parser.saxparser;

import com.aliao.parser.entity.LitePalAttr;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

/**
 * Created by aliao on 2015/6/4.
 */
public class LitePalContentHandler extends DefaultHandler{

    private LitePalAttr litePalAttr;

    @Override
    public void startDocument() throws SAXException {
        litePalAttr = LitePalAttr.getIntance();
        litePalAttr.getClassNames().clear();//因为litePalAttr是静态的,所以如果再次进行解析要清空之前的数据
    }

    @Override
    public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
        if ("dbname".equalsIgnoreCase(localName)){
            for (int i = 0; i<attributes.getLength(); i++){
                if ("value".equalsIgnoreCase(attributes.getLocalName(i))){
                    litePalAttr.setDbName(attributes.getValue(i).trim());
                }
            }
        }else if ("version".equalsIgnoreCase(localName)){
            for (int i = 0; i<attributes.getLength();i++){
                if ("value".equalsIgnoreCase(attributes.getLocalName(i))){
                    litePalAttr.setVersion(Integer.parseInt(attributes.getValue(i).trim()));
                }
            }
        }else if ("mapping".equalsIgnoreCase(localName)){
            for (int i = 0; i<attributes.getLength();i++){
                if ("class".equalsIgnoreCase(attributes.getLocalName(i))){
                    litePalAttr.addClassName(attributes.getValue(i).trim());
                }
            }
        }
    }

    @Override
    public void endElement(String uri, String localName, String qName) throws SAXException {
        super.endElement(uri, localName, qName);
    }

    @Override
    public void endDocument() throws SAXException {
        super.endDocument();
    }

    @Override
    public void characters(char[] ch, int start, int length) throws SAXException {
        super.characters(ch, start, length);
    }
}

在主程序里启动解析:

package com.aliao.parser.saxparser;

import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;

import com.aliao.parser.R;
import com.aliao.parser.entity.LitePalAttr;

/**
 * Created by aliao on 2015/6/4.
 */
public class LitePalParserFragment extends Fragment implements View.OnClickListener {
    public static final String TAG = LitePalParserFragment.class.getSimpleName();
    private TextView mTvResult;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment_saxparser_litepal, container, false);
    }

    @Override
    public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        Button btnParse = (Button) view.findViewById(R.id.btn_parse_litepal);
        btnParse.setOnClickListener(this);
        mTvResult = (TextView) view.findViewById(R.id.tvSaxParserResult);
    }

    @Override
    public void onClick(View v) {
        LitePalParser.parseLitePalConfiguration();
        showResult();
    }

    private void showResult() {
        mTvResult.setVisibility(View.VISIBLE);
        LitePalAttr mLitePalAttr = LitePalAttr.getIntance();
        StringBuffer sb = new StringBuffer(mLitePalAttr.toString());
        for (String className:mLitePalAttr.getClassNames()){
            sb.append("\n\n"+className);
        }
        mTvResult.setText("SAXParser解析litepal.xml结果:\n\n"+sb.toString());
    }
}

运行结果:

先到这吧

时间: 2024-10-28 15:37:06

解读郭神LitePal源码-litepal.xml的解析的相关文章

[Apache Spark源码阅读]天堂之门——SparkContext解析

稍微了解Spark源码的人应该都知道SparkContext,作为整个Project的程序入口,其重要性不言而喻,许多大牛也在源码分析的文章中对其做了很多相关的深入分析和解读.这里,结合自己前段时间的阅读体会,与大家共同讨论学习一下Spark的入口对象—天堂之门—SparkContex. SparkContex位于项目的源码路径\spark-master\core\src\main\scala\org\apache\spark\SparkContext.scala中,源文件包含Classs Sp

CountDownLatch &amp; CyclicBarrier源码Android版实现解析

CountDownLatch CountDownLatch允许一条或者多条线程等待直至其它线程完成以系列的操作的辅助同步器. 用一个指定的count值对CountDownLatch进行初始化.await方法会阻塞,直至因为调用countDown方法把当前的count降为0,在这以后,所有的等待线程会被释放,并且在这以后的await调用将会立即返回.这是一个一次性行为--count不能被重置.如果你需要一个可以重置count的版本,考虑使用CyclicBarrier. 其实本类实现非常简单,和Re

nginx源码分析--nginx模块解析

nginx的模块非常之多,可以认为所有代码都是以模块的形式组织,这包括核心模块和功能模块,针对不同的应用场合,并非所有的功能模块都要被用到,附录A给出的是默认configure(即简单的http服务器应用)下被连接的模块,这里虽说是模块连接,但nginx不会像apache或lighttpd那样在编译时生成so动态库而在程序执行时再进行动态加载,nginx模块源文件会在生成nginx时就直接被编译到其二进制执行文件中,所以如果要选用不同的功能模块,必须对nginx做重新配置和编译.对于功能模块的选

Javac源码简单分析之解析和填充符号表

一.说明 符号表是由一组符号地址和符号信息构成的表格.符号表中所登记的信息在编译的不同阶段都要用到,在语义分析(后面的步骤)中,符号表所登记的内容将用于语义检查和产生中间代码,在目标代码生成阶段,党对符号名进行地址分配时,符号表是地址分配的依据. 二.主要的类与方法 解析和填充符号表这个过程主要由com.sun.tools.javac.comp.Entry及com.sun.tools.javac.comp.MemberEnter两个类来实现的. com.sun.tools.javac.comp.

第66讲:Scala并发编程实战初体验及其在Spark源码中的应用解析

王家林亲授<DT大数据梦工厂>大数据实战视频“Scala深入浅出实战经典”视频.音频和PPT下载!第66讲:Scala并发编程实战初体验及其在Spark源码中的应用解析百度云:http://pan.baidu.com/s/1pJ5jzHx腾讯微云:http://url.cn/aSawrm360云盘:http://yunpan.cn/cctL3QYACaVNa  访问密码 c0fb 信息来源于 DT大数据梦工厂微信公众账号:DT_Spark

区块链教程btcpool矿池源码分析StratumServer模块解析

兄弟连区块链教程btcpool矿池源码分析StratumServer模块解析 核心机制总结 接收的job延迟超过60秒将丢弃 如果job中prevHash与本地job中prevHash不同,即为已产生新块,job中isClean状态将置为true????* true即要求矿机立即切换job 三种情况下将向矿机下发新job:???? 收到新高度的job???? 过去一个job为新高度且为空块job,且最新job为非空块job????* 达到预定的时间间隔30秒 最近一次下发job的时间将写入文件(

解读郭神LitePal源代码-litepal.xml的解析

在開始使用LitePal时,要求在项目的assets文件夹下新建一个litepal.xml文件: <?xml version="1.0" encoding="utf-8"? > <litepal> <dbname value="Questionnaire"/> <version value="1"></version> <list> <mapping

Android学习——涉及意识形态的LitePal源码分析

原创技术博客,请认准Azzssss的原文http://www.cnblogs.com/Azzssss/p/4147704.html. 这两天项目终于上线了,松了一口气,虽然还是很不稳定,见一步走一步吧.反正总算能抽出时间来写博客了.在项目中用到了LitePal,LitePal是什么鬼东西呢?它的Github主页是什么介绍的:“LitePal是一个开源的android库,允许开发者极其方便地去使用sqlite数据库.通过它,你甚至可以不写一行SQL语句来完成大部分的数据库操作,包括创建和更新表,c

dubbo源码之一——xml schema扩展

dubbo源码版本:2.5.4 dubbo-parent |----dubbo-config |----dubbo-config-api |----com.alibaba.dubbo.config.* |----dubbo-config-spring |----com.alibaba.dubbo.config.spring.schema.DubboNamespaceHandler.java |----com.alibaba.dubbo.config.spring.schema.DubboBean