`

SQLite3 在应用启动时初始化数据

 
阅读更多

今天想实现一个功能,即在应用安装初始化时,创建本地数据库,同时为数据库添加数据,之后再从数据库中读取数据。

1 首先需要写一个类实现android中的SQLiteOpenHelper类。代码如下:

 

public class DatabaseHelper extends SQLiteOpenHelper {
	/**
	 *DatabaseHelper作为一个访问SQLite的助手类,提供两个方面的功能
	 *第一,getReadableDatabase(),getWritableDAtabase()可以获得SQLiteDatabase对象,通过该对象可以对数据库进行操作
	 *第二,提供了onCreate()和onUpgrade()两个回调函数,允许我们在创建和升级数据库时,进行自己的操作
	 */
	private static final int VERSION=1;// 数据库版本
	private static final String NAME="oil.db";//数据库名
	
	public DatabaseHelper(Context context, String name, CursorFactory factory,
			int version) {
		
		super(context, name, factory, version);
	}

	public DatabaseHelper(Context context, String name, int version) {
		
		this(context, name, null, version);
	}

	public DatabaseHelper(Context context) {
		
		this(context, NAME, VERSION);
	}
	
	
	String sql = "CREATE TABLE IF NOT EXISTS car ( _id VARCHAR(50) primary key ,"
			+ "company_name VARCHAR(50) , "
			+ "type VARCHAR(50) , "
			+ " general_name VARCHAR(50) ,"
			+ "transmission VARCHAR(50) , "
			+ " emission VARCHAR(50),"
			+ "city_consume VARCHAR(50)  , "
			+ "suburban_consume VARCHAR(50) ,"
			+ "total_consume VARCHAR(50),"
			+ "factor VARCHAR(50)) ;";

	//该函数是在第一次创建数据库的时候执行,实际上是在第一次得到SQLiteDatabase对象的时候,
	//才会调用这个方法
	@Override
	public void onCreate(SQLiteDatabase db) {
		//创建表
		db.execSQL(sql) ;
		System.out.println("create a database");
	}
	@Override
	public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
		System.out.println("update a database");
	}

}

 2.判断数据库表中是否有数据,这个可以区分出是否已经对表进行填充了。这个是在CarService中实现的。

 CarService中的构造方法:

 private DatabaseHelper openHelper;
	 private SQLiteDatabase sqliteDatabase;
	 
	 private Context mcontext;

     public CarService(Context context) {
    	 //传递上下文对象
    	 mcontext=context;
               this.openHelper = new DatabaseHelper(context);
               //得到只读的对象
              //  sqliteDatabase = openHelper.getReadableDatabase();  
                
		if (isExist()) {// 若表中数据为空,则执行插入。
			try {
				initInsert();// 插入初始化数据
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
     }

 

之后是实现方法:

 

//判断数据库表中是否有数据
	public boolean isExist(){
		 boolean result = true;

		String sql = "select count(*) count from car";
		//sqliteDatabase = sqliteDatabase.openOrCreateDatabase(sql, null);
		sqliteDatabase = openHelper.getReadableDatabase();
	
		Cursor cursor = sqliteDatabase.rawQuery(sql, null);
		
		//System.out.println(cursor.get);
		if (cursor.moveToNext() ) {
			int count = cursor.getInt(0);
			if(count>0){//存在数据
				 result = false;
			}
			cursor.close();
			sqliteDatabase.close();
		} 
		return result;
		 
	}

 3 开始往空表中填充数据。这个实现思路是直接把一个文件中的数据(大概1k条左右)写进数据库,因为数据量稍微多点,所以使用事务进行添加。同时这个数据文件car.sql是放在res/raw/文件夹下。我试过跟类放在一起我找不到文件。如果有同志实现了,可以交流下。呵呵。

 /**
    * 通过读取文件,插入初始化数据
    * @throws IOException
    */
	public void initInsert() throws IOException {
		
	 InputStreamReader reader = new InputStreamReader( mcontext.getResources().openRawResource(R.raw.cardata));
     BufferedReader br = new BufferedReader(reader);
		String s1 = "";
		 sqliteDatabase = openHelper.getWritableDatabase();
		 //通过事务,进行批量插入
		sqliteDatabase.beginTransaction();

		while ((s1 = br.readLine()) != null) {
			//System.out.println(s1);
			String sql = s1;
			//System.out.println("sql---"+sql);
			sqliteDatabase.execSQL(sql);
		}
		
		sqliteDatabase.setTransactionSuccessful();
		sqliteDatabase.endTransaction();

		br.close();
		reader.close();
		sqliteDatabase.close();

	}

 

我是用按行读取的,比较简便。嘿嘿难一点的,你们自己试吧。

4之后就是查询了。

  public List<Car> getCompanyList(long startIndex, long maxCount) throws UnsupportedEncodingException {
    	 //路径/data/data/jw.oil/files
    /*	String path=mcontext.getFilesDir().getPath().substring(0);
    	System.out.println(path);*/

         String sql = "SELECT DISTINCT(company_name) company_name FROM car ";
         //String[] selectionArgs = { String.valueOf(startIndex), String.valueOf(maxCount) };
         sqliteDatabase = openHelper.getReadableDatabase();  
         Cursor cursor = sqliteDatabase.rawQuery(sql, null);
         
         List<Car> cars = new ArrayList<Car>();
         
		if (cursor.getCount() != 0) {// 如果有数据
			while (cursor.moveToNext()) {
				Car car = new Car();
				
				car.setCompany_name(cursor.getString(0));
				System.out.println("----" + car.getCompany_name());
				cars.add(car);
			}
				cursor.close();
				sqliteDatabase.close();//关闭数据库
			
		} else {
			cars = null;
		}
         return cars;
}

 

如果填充数据没错,就出现效果了。

 



 

出现问题:因为总是测试,很多时候使用命令行查看数据库。删除应用的时候,只是删除文件夹。有好几次在程序初始化时都会报错:unable to open database file

 查了很多资料,最后才明白是自己的应用没有删干净。建议用模拟器自带的卸载管理。

 

  • 大小: 9 KB
分享到:
评论
1 楼 jiae 2015-01-09  
为啥我的插入语句乱码?  但是可以插入数据库    然后复制你的sql文件,改下语句,不乱码了,但是执行语句总是报错

相关推荐

    Android 个人理财工具二:使用SQLite实现启动时初始化数据

    关于SQLite  sqlite是嵌入式SQL数据库引擎SQLite(SQLite Embeddable SQL Database ... 我在多年前就关注sqlite的发展,非常看好sqlite的前景,因为在移动、嵌入式的应用里面,sqlite具有非常好的特性来满足需求。  

    移动端的背单词应用Wordman.zip

    用户安装 Wordman 后首次启动时进行初始化: 生成 UUID,用于标识该 Wordman 应用(2.0.0 后用于上报 Words) 将词库 SQL.zip 逐个导入 Web SQL 数据库 计划生成 当用户选定了一个要学习的词库后...

    GitHub-UserSearch:Android应用程序概念,可通过GitHub API搜索用户

    GitHub用户搜索Android应用程序通过GitHub API搜索用户该项目演示了如何使用Kotlin,Android体系结构组件,Dagger和RxJava执行远程API调用并在本地数据库中缓存数据结构体: 启动屏幕-显示徽标并并行进行Dagger组件...

    BrBa-Compose

    应用启动-在应用启动时初始化组件。 MVVM模式 Kotlin协程和流程 材料设计 交错垂直网格 执照 Designed and developed by 2021 shinhyo Licensed under the Apache License, Version 2.0 (the "License"); you may ...

    Sapientia-Android2020-Project:这是Android课程的项目

    Sapientia-Android2020-Project:在哪里吃饭? 在Android课程中,我们不得不将一个小应用程序作为一个项目,在这里我们可以探索餐厅并利用我们的经验扩展REST API中的数据...在这里进行加载,数据被初始化,并且当用户

    redpill:ruby 矩阵 irc 网关

    您还需要运行一次ruby intialize_app.rb来初始化应用程序,然后运行ruby webserver.rb来启动服务器。 一切都运行后,您应该能够在 Matrix 中加入#irc/your-channel:example.com并且机器人将自动加入在您的设置中...

    工程硕士学位论文 基于Android+HTML5的移动Web项目高效开发探究

    市场上相应的检测平台诸如检测通、凡特网等皆为pc端检测网站,并且操作繁琐不够人性化,用户在实地使用中存在很多问题。昆山工业技术研究院着眼于为委托用户和质检机构搭建良好的沟通桥梁,免去目前市场业务中企业...

Global site tag (gtag.js) - Google Analytics