`

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具有非常好的特性来满足需求。  

    BrBa-Compose

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

    开源_易语言中文分词_非网页调用

    ' ' 窗口启动的时候,初始化类会把数据库载入内存,以增加运算速度,所以占用内存稍微大一点,如果不喜欢,可以修改类初始化部分{方初始化()} ' 子重置词典数据库() 这个功能用于自定义词库,吧文本词库转换为sqlite数据库...

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

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

    新版Android开发教程.rar

    ----------------------------------- Android 编程基础 1 封面----------------------------------- Android 编程基础 ...• SQLite SQLite SQLite SQLite 用作结构化的数据存储 • 多媒体支持 包括常见的音频、视频和...

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

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

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

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

    ASP.NET3.5从入门到精通

    2.3.4 声明并初始化字符串 2.3.5 操作字符串 2.3.6 创建和使用常量 2.3.7 创建并使用枚举 2.3.8 类型转换 2.4 编写表达式 2.4.1 表达式和运算符 2.4.2 运算符的优先级 2.5 使用条件语句 2.5.1 if 语句的使用方法 ...

    ASP.NET 3.5 开发大全11-15

    2.3.4 声明并初始化字符串 2.3.5 操作字符串 2.3.6 创建和使用常量 2.3.7 创建并使用枚举 2.3.8 类型转换 2.4 编写表达式 2.4.1 表达式和运算符 2.4.2 运算符的优先级 2.5 使用条件语句 2.5.1 if语句的使用方法 ...

    ASP.NET 3.5 开发大全

    2.3.4 声明并初始化字符串 2.3.5 操作字符串 2.3.6 创建和使用常量 2.3.7 创建并使用枚举 2.3.8 类型转换 2.4 编写表达式 2.4.1 表达式和运算符 2.4.2 运算符的优先级 2.5 使用条件语句 2.5.1 if语句的使用方法 ...

    ASP.NET 3.5 开发大全1-5

    2.3.4 声明并初始化字符串 2.3.5 操作字符串 2.3.6 创建和使用常量 2.3.7 创建并使用枚举 2.3.8 类型转换 2.4 编写表达式 2.4.1 表达式和运算符 2.4.2 运算符的优先级 2.5 使用条件语句 2.5.1 if语句的使用方法 ...

    ASP.NET 3.5 开发大全word课件

    2.3.4 声明并初始化字符串 2.3.5 操作字符串 2.3.6 创建和使用常量 2.3.7 创建并使用枚举 2.3.8 类型转换 2.4 编写表达式 2.4.1 表达式和运算符 2.4.2 运算符的优先级 2.5 使用条件语句 2.5.1 if语句的使用方法 ...

    ASPNET35开发大全第一章

    2.3.4 声明并初始化字符串 2.3.5 操作字符串 2.3.6 创建和使用常量 2.3.7 创建并使用枚举 2.3.8 类型转换 2.4 编写表达式 2.4.1 表达式和运算符 2.4.2 运算符的优先级 2.5 使用条件语句 2.5.1 if语句的使用方法 ...

    php网络开发完全手册

    9.1.5 运行时的错误 138 9.2 PHP程序调试策略 138 9.2.1 PHP的错误级别 138 9.2.2 打开PHP的错误报告 140 9.2.3 使用print进行程序调试 140 9.3 使用PHPEclipse进行PHP程序调试 141 9.3.1 使用Eclipse编写PHP程序的 ...

    redpill:ruby 矩阵 irc 网关

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

    疯狂Android讲义源码

     6.11.4 为Android应用提供国际化  资源 255  6.11.5 国际化Android应用 256  6.12 本章小结 258  第7章 图形与图像处理 259  7.1 使用简单图片 260  7.1.1 使用Drawable对象 260  7.1.2 Bitmap和...

    疯狂Android讲义.part2

    18.3.2 初始化游戏状态数据 606 18.4 加载界面的图片 610 18.5 实现游戏Activity 612 18.6 实现游戏逻辑 618 18.6.1 定义GameService组件接口 618 18.6.2 实现GameService组件 619 18.6.3 获取触碰点的方块 620 18.6...

Global site tag (gtag.js) - Google Analytics