Android之数据库—— 一个可配置的简易框架
database,sqlist,xml,配置2016-07-05
Android自带的Sqlite数据库是日常开发中必用的。这里介绍一种用xml形式配置数据库的简易框架(库)。
为什么要用这个框架?
(1)因为XML格式的配置方式,层次明显,一目了然;
(2)在扩展,对增减数据库中的表或者列,更加容易且不容易出错;
(3)将配置统一在XML中,对以后的维护,会显得十分方便;
(4)最后,是这个框架很简单。
(1)最外层节点
数据库名要有;
数据库版本要有;
(2)次外层节点
表名要有;
(3)内层节点
列名要有;
主键要有;
根据以上的必要元素,我们做了一个XML文件:
<?xml version="1.0" encoding="utf-8"?> <!-- 数据库定义 --> <Database name="databaseMe.db" version="1" > <!-- 交易数据保存 --> <table name="Mydata" primaryKey="id" > <field name="id" /> <!-- 主键,只能自增长的integer --> <field name="name" /> <field name="adress" /> </table> </Database>根据这些元素,我们应该能够生成一个名为databaseMe.db的数据库,库中含有表Mydata,表中有三列,分别为id,name,adress,其中id是主键。
要实现以上描述的功能,我们还需要写一些代码。
(1)首先要解析xml文件;
(2)看这个xml文件,它只有三个节点,Database、table、field,分别是数据库、表、列,其他的都是xml的属性值。
(3)我们用代码解析xml内容,并根据内容,创建出数据库以及它的表、列。
根据这上面的代码设计,打算用javaBean方式,一层一层的把代码写好。
根据xml文件,我们写出三个Model。
数据库:
package com.database.lib; import java.util.List; public class DataBaseModel { //数据库名称 private String dataBaseName; //数据库版本 private int dataBaseVersion; //数据库中表集合 private List<DataBaseTableModel> tables; public List<DataBaseTableModel> getTables() { return tables; } public void setTables(List<DataBaseTableModel> tables) { this.tables = tables; } public String getDataBaseName() { return dataBaseName; } public void setDataBaseName(String dataBaseName) { this.dataBaseName = dataBaseName; } public int getDataBaseVersion() { return dataBaseVersion; } public void setDataBaseVersion(int dataBaseVersion) { this.dataBaseVersion = dataBaseVersion; } }
package com.database.lib; import java.util.List; public class DataBaseTableModel { //表名 private String tableName; //主键 private String primaryKey; //表结构 private List<DataBaseFieldModel> fields; public List<DataBaseFieldModel> getFields() { return fields; } public void setFields(List<DataBaseFieldModel> fields) { this.fields = fields; } public String getTableName() { return tableName; } public void setTableName(String tableName) { this.tableName = tableName; } public String getPrimaryKey() { return primaryKey; } public void setPrimaryKey(String primaryKey) { this.primaryKey = primaryKey; } }
package com.database.lib; public class DataBaseFieldModel { //列名 private String name; //列其他属性,暂忽略,有需要可添加... public String getFieldName() { return name; } public void setFieldName(String name) { this.name = name; } }
/** * 将XML文件解析为DataBaseModle * @param xmlFile * @return * @throws ParserConfigurationException * @throws SAXException * @throws IOException */ private DataBaseModel getDataBase(String xmlFile) throws ParserConfigurationException, SAXException, IOException{ //读取xml文件 InputStream in=context.getResources().getAssets().open(xmlFile); //SAX解析 SAXParserFactory factory=SAXParserFactory.newInstance(); SAXParser parser= factory.newSAXParser(); XMLReader reader = parser.getXMLReader(); //DefaultHandler配合SAX解析xml内容 DataBaseHandler mHandler=new DataBaseHandler(); reader.setContentHandler(mHandler); reader.parse(new InputSource(new InputStreamReader(in, "UTF-8"))); //将解析得到的内容导致到model中 DataBaseModel model=new DataBaseModel(); model.setDataBaseName(mHandler.getDataBaseName()); model.setDataBaseVersion(mHandler.getDataBaseVersion()); model.setTables(mHandler.getTables()); return model; }
package com.database.lib; import java.util.ArrayList; import java.util.List; import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler; public class DataBaseHandler extends DefaultHandler{ private String dataBaseName; private int dataBaseVersion; private List<DataBaseTableModel> tables; private DataBaseTableModel table; private List<DataBaseFieldModel> fields; @Override public void startDocument() throws SAXException { tables=new ArrayList<DataBaseTableModel>(); fields=new ArrayList<DataBaseFieldModel>(); } @Override public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { if (DataBaseManager.DATABASE.equals(qName)) { dataBaseName = attributes.getValue(DataBaseManager.DATABASE_NAME); dataBaseVersion = Integer.parseInt(attributes.getValue(DataBaseManager.DATABASE_VERSION)); } else if (DataBaseManager.TABLE.equals(qName)) { table =new DataBaseTableModel(); String name=attributes.getValue(DataBaseManager.TABLE_NAME); String primarykey = attributes.getValue(DataBaseManager.TABLE_PRIMARYKEY); table.setTableName(name); table.setPrimaryKey(primarykey); } else if (DataBaseManager.FIELD.equals(qName)) { try { String filed = attributes.getValue(DataBaseManager.FIELD_NAME); DataBaseFieldModel fieldModel=new DataBaseFieldModel(); fieldModel.setFieldName(filed); fields.add(fieldModel); table.setFields(fields); } catch (NumberFormatException e) { e.printStackTrace(); } } } @Override public void endElement(String uri, String localName, String qName) throws SAXException { if (DataBaseManager.TABLE.equals(qName)) { tables.add(table); } } public String getDataBaseName() { return dataBaseName; } public void setDataBaseName(String dataBaseName) { this.dataBaseName = dataBaseName; } public int getDataBaseVersion() { return dataBaseVersion; } public void setDataBaseVersion(int dataBaseVersion) { this.dataBaseVersion = dataBaseVersion; } public List<DataBaseTableModel> getTables() { return tables; } public void setTables(List<DataBaseTableModel> tables) { this.tables = tables; } }
package com.database.lib; import java.util.List; import android.content.Context; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteDatabase.CursorFactory; import android.database.sqlite.SQLiteOpenHelper; public class DataBaseHelper extends SQLiteOpenHelper{ private DataBaseModel model; public DataBaseHelper(Context context, String name, CursorFactory factory, int version) { super(context, name, factory, version); // TODO Auto-generated constructor stub } public DataBaseHelper(Context context, DataBaseModel model) { super(context, model.getDataBaseName(), null, model.getDataBaseVersion()); this.model=model; } @Override public void onCreate(SQLiteDatabase db) { // TODO Auto-generated method stub if(model.getTables().size()>0){ for(DataBaseTableModel tableModel:model.getTables()){ createTable(db,tableModel); } } } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { // TODO Auto-generated method stub } private void createTable(SQLiteDatabase db, DataBaseTableModel table) { StringBuilder sql = new StringBuilder(" create table if not exists "); String tableName = table.getTableName(); String primaryKey = table.getPrimaryKey(); List<DataBaseFieldModel> fileds = table.getFields(); sql.append(tableName); sql.append("("); int i = 0; for (i = 0; i < fileds.size(); i++) { if (i == fileds.size() - 1) { if (fileds.get(i).getFieldName().equals(primaryKey)) { sql.append(fileds.get(i).getFieldName() + " integer primary key autoincrement"); } else{ sql.append(fileds.get(i).getFieldName() + " TEXT)"); } } else { if (fileds.get(i).getFieldName().equals(primaryKey)) { sql.append(fileds.get(i).getFieldName() + " integer primary key autoincrement,"); } else{ sql.append(fileds.get(i).getFieldName() + " TEXT,"); } } } db.execSQL(sql.toString()); } }
package com.database.lib; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import org.xml.sax.InputSource; import org.xml.sax.SAXException; import org.xml.sax.XMLReader; import android.content.ContentValues; import android.content.Context; import android.database.sqlite.SQLiteDatabase; public class DataBaseManager { private Context context; private DataBaseHelper mHelper; private SQLiteDatabase db; public static final String DATABASE="Database"; public static final String TABLE="table"; public static final String FIELD="field"; public static final String DATABASE_NAME="name"; public static final String DATABASE_VERSION="version"; public static final String TABLE_NAME="name"; public static final String TABLE_PRIMARYKEY="primaryKey"; public static final String FIELD_NAME="name"; private DataBaseManager(){} private volatile static DataBaseManager instance; public static DataBaseManager getInstance(){ if(instance==null){ synchronized (DataBaseManager.class) { instance=new DataBaseManager(); } } return instance; } public void init(Context context){ this.context=context; try { DataBaseModel dataBaseModel=getDataBase("database.xml"); mHelper=new DataBaseHelper(context, dataBaseModel); db=mHelper.getWritableDatabase(); } catch (ParserConfigurationException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (SAXException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } /** * 将XML文件解析为DataBaseModle * @param xmlFile * @return * @throws ParserConfigurationException * @throws SAXException * @throws IOException */ private DataBaseModel getDataBase(String xmlFile) throws ParserConfigurationException, SAXException, IOException{ //读取xml文件 InputStream in=context.getResources().getAssets().open(xmlFile); //SAX解析 SAXParserFactory factory=SAXParserFactory.newInstance(); SAXParser parser= factory.newSAXParser(); XMLReader reader = parser.getXMLReader(); //DefaultHandler配合SAX解析xml内容 DataBaseHandler mHandler=new DataBaseHandler(); reader.setContentHandler(mHandler); reader.parse(new InputSource(new InputStreamReader(in, "UTF-8"))); //将解析得到的内容导致到model中 DataBaseModel model=new DataBaseModel(); model.setDataBaseName(mHandler.getDataBaseName()); model.setDataBaseVersion(mHandler.getDataBaseVersion()); model.setTables(mHandler.getTables()); return model; } /** * 增 * @param table * @param values * @return */ public long insertData(String table,ContentValues values){ return 0; } /** * 查 * @param sql */ public void selectData(String sql){ } /** * 改 * @param sql */ public void modifyData(String sql){ } /** * 删 * @param sql */ public void deleteData(String sql){ } }
DataBaseManager.getInstance().init(this);你就完成了数据库、表、列的创建,后续的扩展也很方便。
这个简易框架,对于简单的数据库而言,还是很方便和节省时间的。
另外,说一下不足的地方:因为这是个很简单的框架,并没有对列的属性做扩展,目前只有Text一个属性。如果需要扩展,可能框架就变的较为复杂。有需要的可以在Field中写上你需要的属性,比如长度限制等,在DataBaseHandler中解析出来就好(当然,别忘了在DataBaseFieldModel中加上你定义的属性名称)。
github上源码(AndroidStudio版本):https://github.com/yangzhaomuma/DataBaseManager
csdn上源码(eclipse 版本):http://download.csdn.net/detail/yangzhaomuma/9568138