DAO操作对多个工作簿同时编辑时,为什么只是只读

VB使用DAO方式调用ACCESS数据库
引用DAO类型库
1、从“工程”菜单中选择“引用”菜单项;
2、在可引用列表框中选择“Microsoft DAO 3.6 Object Library”项
3、最后“确定”即可
设置DAO数据类型变量
DAO数据类型变量共分成两种:
1、Database变量
Public db As Database
对应于Access数据库,通常在模块中被定义为Public全程变量
2、RecordSet变量
Dim rs As RecordSet
设置DAO数据类型变量(二)
建立了数据库对象变量后,我们便可打开数据库了,在一般情况下都只是访问一个数据库,当打开数据库后再对数据库中的各个记录进行操作,这就要用到Recordset
对象建立记录集
打开数据库
Private Sub Command_OpenDatabase_Click() Dim db as Database Dim rs
As Recordset Set db = OpenDatabase ( App.path &
"\数据库名称.mdb" ) Set rs = db.OpenRecordset ( " select * from 表名 " )
End Sub 这样,数据库中的记录便放到Recordset中,可以进行后续操作了
Opendatabase 方法
Opendatabase 方法是打开数据库并返回此数据库的database对象,其语法如下:
Set database的对象变量=opendatabase ([数据库名称及路径],[除外性],[只读])
除外性:由true和false值所构成,当值为true时代表仅允许唯一的使用者使用数据库。
只读:由true和false值所构成,为true代表数据库仅提供读取的服务
Opendatabase 方法(二)
OpenDatabase方法有两种给出路径的方法
Set db = OpenDatabase ( App.path & "\student.mdb"
App.path对象返回目前运行程序所在的路径名称,使用相当路径避免了程序变换了路径的麻烦,但必须保证数据库和程序在同一文件夹下
Set db=OpenDatabase(“e:\student.mdb" ,
false,false)
Openrecordset 方法
Openrecordset方法用来创建一个新的recordset对象,语法为:
Set recordset 对象变量=数据库变量.openrecordset(来源,种类)
Vb所提供的recordset对象有5种,分别为:表(table)、动态集(dynaset)、快照集(snapshot)、动态(dynamic)、正向(forward-only),其中经常用的时动态集(dynaset),它实际上是引用一个或多个表种数据记录的集合,是功能最强的数据记录集合类型
Openrecordset 方法
Set rs = db.OpenRecordset ( " select * from 表名 " )
Set rs = db.OpenRecordset ( “ select * from 表名 ”,dbopendynaset
Fields集合
Fields集合包括结果集合全部 Field对象,这些 Field对象引用方法为: RS.Fields(I),其中 I是该
Field对象在中的位置序号,从 0开始计数, RS.Fields(0)表示你的数据库的第一个字段,如:
RS.Fields(I)=”111”
使用数据库
当打开数据库,建立Recordset 记录集后,便可浏览、删除、添加、查找数据库中的内容
使text显示数据如下:
Text1.caption=rs.fields(0)
Text1(I).caption=rs.fields(I)
Recordcount 属性
Recordcount 属性用来记录目前数据记录的数量,如判断数据库是否为空:
If rs.recordcount & 0 then
Private Sub cmd_del_Click() On Error GoTo handle Dim msg as string
msg = "是否要删除记录"& Chr$(10) msg = msg
& label(0) &把删除记录的代号加入msg中 If Msgbox(msg , 17 ,
"删除记录") && 1 Then Exit sub rs.delete
rs.Movenext If rs.EOF = True Then rs.MovePrevious End if   
删除记录(二)
for I = 0 to 11 label(I).caption = rs.Fields(I) &
"" next Exit Sub
handle: MsgBox "该记录无法删除!!!" End Sub
On error goto 语法
目的是为了程序运行时,一旦发生错误,即可通过该程序代码,将程序运行流程切换到适当位置,进行适当处理,避免死机
On error goto
的程序代码编写位置,必须在发生错误的程序代码之前,因此,常常将它写在程序或某个程序功能模块的最前面
向数据库中添加记录比较麻烦一点,大致分为三步:首先,用AddNew方法向数据库添加一个新的空白记录;其次,将要输入的数据分别赋到数据库的各个字段中;最后,用Updata的方法,把记录写到数据库中去
Private Sub cmd_new_Click() rs.AddNew For I = 0 to 11 rs.Fields(I)
= TextBox(I).Text Next rs.Updata End Sub   
Private Sub Cmd_search_Click() Set rs =
dbase.openRecordset("表名",dbopenDynaset) rs.findfirst "字段名= ' "
& Text.Text & " ' " &
Text.Text是输入的关键字 if rs.Nomatch = True then Msgbox "对不起,没有该记录" else
For I = 0 to 11 label(I).caption = rs.Fields(I) &
"" Next End if rs.close End Sub   
Rs.fields(I)=text1(I)
已投稿到:
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。为什么在EXCEL中保存时会弹出该文件为“只读”文件,该如何处理?_百度知道
为什么在EXCEL中保存时会弹出该文件为“只读”文件,该如何处理?
我有更好的答案
你使用的电脑网络应该是局域网,且使用了共享,EXCEL有他人在使用,所以你使用时就是只读。还有一个情况是EXCEL已加密
当某个EXCEL文件已经打开了,又被第二次打开时,后来打开的同一个文件,不能进行编辑和保存,该文件被限制为“只读文件”只能阅读,不能编辑和保存。只有初始打开的那个文件才能编辑和保存,这样才能保证不会出现混乱现象。关掉这个“只读文件”即可,再找一找前面已经打开的文件进行操作。
本回答被网友采纳
点左上角菜单---另存为--EXCEL工作簿在弹出的窗口里,点左下角的工具--常规选项,选上建议只读. 然后保存一下。关闭再打开就有只读提示了。 当然,你也可以在这里设置修改权限密码的。
是不是和别人共享的
去掉就行了
本回答被网友采纳
所谓“只读”(Read-Only),表示这个文档只能打开来读,不能修改也不能储存。有些重要的档案会设定成只读状态,免得一不小心修改这些文档的内容,除非解除只读的状态,不然这些文档是不能修改的。就像是一个密闭的透明玻璃瓶子,如果不打开盖子,只能看到里面的东西,却无法取出或放入东西。 编辑本段解决方法  如何将文档设成只读状态,或是解除只读状态呢?  在文件上按一下鼠标右键,在弹出的菜单中选“属性”,在出现的“属性”对话框中勾选“只读”,再按下“确定”即可。若要解除只读状态,依照上述步骤,进行一次逆操作即可取消“只读”的选项。  另外,还可以通过命令行的方式来给文件设置只读状态或是解除只读状态:开始→运行→输入cmd.exe,回车打开命令提示符窗口,输入attrib +r &文件全路径& 或者 attrib -r &文件全路径& 可以分别给文件设置只读和解除只读状态。 编辑本段具体应用  只读文件有两种情况:  一种是windows系统提供的功能,可以用右键-属性查看并修改。把文件设置为这样的只读可以防止不小心的误操作修改或者覆盖该文件。比如Windows XP系统的引导配置文件boot.ini,一般都被设置成了只读状态,防止病毒或人为的随意篡改导致系统无法引导。  还有一种是由具体的软件提供的功能,可以把文件设置为只读并附加密码,还可以防止作品被篡改。比如Excel表格类型的文档就有这样的功能。  当然,除了有只读文件以外,对文件来讲还有系统文件(System)、存档文件(Archive)、隐藏文件(Hidden)的称呼。一个文件可以有多个这样的“标签”,归根到底这些都是文件的属性(Properties),您可以随心所欲地添加或者撤销它们。
本回答被网友采纳
2条折叠回答
其他3条回答
为您推荐:
其他类似问题
excel的相关知识
换一换
回答问题,赢新手礼包
个人、企业类
违法有害信息,请在下方选择后提交
色情、暴力
我们会通过消息、邮箱等方式尽快将举报结果通知您。下次自动登录
现在的位置:
& 综合 & 正文
3)type、options 和 lockedits 参数
type参数可选表
dbOpenDynaset
dbOpenSnapshot
dbOpenForwardOnly
dbOpenDynamic
dbOpenTable
Recordset对象表类型
Recordset对象快照类型
Recordset对象仅向前类型
Recordset对象动态类型
Recordset对象动态集类型
options参数可选表
dbAppendOnly
dbReadOnly
dbSeeChanges
dbDenyWrite
dbDenyRead
禁止其它用户写
禁止其它用户读
仅对动态集
仅对Microsoft Jet 工作区
仅用于动态集类型的记录集
仅用于Recordset对象
仅用于表类型的记录集
dbForwardOnly
dbSQLPassThrough
dbConsistent
dbInconsistent
仅向前快照
source是SQL
不一致更新
仅用于Microsoft Jet数据源
仅用于快照
仅用于动态集类型和快照类型
仅用于动态集类型和快照类型
lockedits 参数可选表
可以使用 lockedits 参数控制对记录集的锁定。可用以下常数。
dbReadOnly
禁止用户对记录集进行修改
DbPessimistic
在多用户环境中,使用保守式锁定来决定修改记录集的方式
DbOptimisticValue
使用基于行值而非行 IDs 的优化并发。仅用于 ODBCDirect 数据源
【上篇】【下篇】您所在位置: &
&nbsp&&nbsp&nbsp&&nbsp
 第8章-使用DAO访问数据库.ppt 81页
本文档一共被下载:
次 ,您可全文免费在线阅读后下载本文档。
下载提示
1.本站不保证该用户上传的文档完整性,不预览、不比对内容而直接下载产生的反悔问题本站不予受理。
2.该文档所得收入(下载+内容+预览三)归上传者、原创者。
3.登录后可充值,立即自动返金币,充值渠道很便利
你可能关注的文档:
··········
··········
第8章 使用DAO访问数据库 第8章 使用DAO访问数据库 8.1 DAO层次结构 8.2 DAO对象 8.3 DAO编程实例
8.1 DAO层次结构 DAO提供两种不同的编程模型结构: Microsoft Jet Workspaces DAO模型 ODBC Direct Workspaces DAO模型。 数据访问对象模型是Jet为数据库引擎的面向对象的接口。由一系列数据库对象和对象的集合按一定的层次结构组成。其层次结构和关系数据库的逻辑视图相符合。数据访问对象类以分层结构来组织,其中的大多数类属于集合类。在分层结构中,它又属于其上层的另一个类。DAO的层次结构如图8.1所示。
8.1 DAO层次结构 8.2 DAO对象 8.2.1 DBEngine对象 8.2.2 Workspace对象 8.2.3 Database对象 8.2.4 TableDef对象 8.2.5 Recordset对象 8.2.6 QueryDef对象 8.2.7 Field对象
8.2 DAO对象 DBEngine对象 DBEngine对象相当于Jet数据库引擎,它是不需要创建就已经存在的对象,而且一个应用界面只能有一个DBEngine对象。DBEngine对象位于DAO对象的顶层,其层次结构如图8.2所示。
8.2 DAO对象 DBEngine对象的属性 DefaultUser:缺省用户名称。进行数据库访问时设置的缺省用户名称,是一个长度小于20个字符的String变量,DefaultUser的缺省值是Admin。 DefaultPassword:缺省用户口令。进行数据库访问时设置的缺省用户口令,DefaultPassword的缺省值是空字符串。 SystemDB:系统数据库名称。本地Microsoft Jet数据库工作组文件,缺省值为System.mdw 8.2 DAO对象 IniPath:初始文件位置。设置或返回Windows注册文件中存有Microsoft Jet数据库引擎值的键的有关信息。 LoginTimeout:注册超时。在注册进入一个ODBC数据库时,系统发出错误信号前等待的时间。缺省值为20秒,如果设为零,系统将永久等待 Version:DAO版本信息。用来返回正在使用的DAO的版本信息 DefaultType:Workspace对象的类型。设置或返回一个值,该值为创建下一个工作区对象指出默认连接类型(工作区类型)。该属性的取值有两个:DbUseJet表示创建连接到Microsoft Jet数据库引擎的工作区对象, DbUseODBC表示创建连接到数据源的工作区对象。
8.2 DAO对象 DBEngine对象的方法 CreateWorkspace:创建一个新的Workspace对象。可以选用参数来设置Workspace的类型以及访问的用户名称和访问的口令。 CompactDatabase:压缩或转换一个关闭的Microsoft Jet数据库。 RegisterDatabase:将ODBC数据源的连接信息注册到Windows。 8.2 DAO对象 RepairDatabase:修复一个关闭的Microsoft Jet数据库。 Idle:挂起数据处理进程,使DBEngine处于空闲状态
8.2 DAO对象 CreateWorkspace方法用于创建一个具有指定类型、用户名称和口令的Workspace对象。其语法如下: Set Workspace对象变量=DBEngine.CreateWorkspace(name,user,password,type) CreateWorkspace的参数有name、user、password、type,说明如下。 name:String类型,用于指明Workspace的名称。 user:String类型,用于指明访问的用户名称。 password:String类型,用于指定访问的口令。 type:常量,指明所建立的Workspace的类型,取值有两个,分别是dbUseJet(创建Microsoft Jet工作区)和dbUseODBC(创建ODBC工作区)。 8.2 DAO对象 Workspace对象 Workspace对象的属性 Name:设置或返回用户定义的Workspace对象的名称。 Type:Workspace对象的类型。如果连接Microsoft Jet数据库,则为Microsoft Jet Workspace对象;如果连接ODBC数据库,则为ODBC Workspace对象。 (3)UserName:拥有该Workspace对象的用户或用户组的名称。 (4)LoginTimeout:在注册进入一个ODBC数据库时,系统发出错误信号前等待的时间,缺省值为20秒。如果设为零,系统
正在加载中,请稍后...
22页19页34页44页21页25页11页14页76页182页GreenDao设置数据库路径以及数据库升级 - 简书
GreenDao设置数据库路径以及数据库升级
1. APP开发期间的数据库
在中封装了GreenDaoManager中有个构造方法如下:
private GreenDaoManager(){
if (mInstance == null) {
DaoMaster.DevOpenHelper devOpenHelper = new
DaoMaster.DevOpenHelper(MyApplication.getContext(), "database_name", null);//此处openhelper为自动生成开发所使用,发布版本需自定义
MySQLiteOpenHelper devOpenHelper = new
MySQLiteOpenHelper(new GreenDaoContext(), "database_name.db", null);//GreenDaoContext为创建数据库路径使用
mDaoMaster = new DaoMaster(devOpenHelper.getWritableDatabase());
mDaoSession = mDaoMaster.newSession();
其中注释掉的两行代码中:
DaoMaster.DevOpenHelper devOpenHelper = new
DaoMaster.DevOpenHelper(MyApplication.getContext(), "database_name", null);//此处DevOpenHelper 为自动生成开发所使用,发布版本需自定义
其中的MyApplication.getContext()上下文表示了数据库存储路径为手机内存。这里的DevOpenHelper即为DaoMaster中自动生成代码,完整代码如下:
/** * WARNING: Drops all table on Upgrade! Use only during development. */
public static class DevOpenHelper extends OpenHelper {
public DevOpenHelper(Context context, String name, CursorFactory factory) {
super(context, name, factory);
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
Log.i("greenDAO", "Upgrading schema from version " + oldVersion + " to " + newVersion + " by dropping all tables");
dropAllTables(db, true);
onCreate(db);
注意看第一行注释:WARNING: Drops all table on Upgrade! Use only during development.
数据库升级的话,会删除所有表,然后重新创建。这种方式在开发期间,APP还没有上线之前是可以的。
当APP上线后,我们不能使用这种方式,因为这样会导致已经存在的数据会被删除。
2. APP上线后,数据库升级
我们需要重写一个类MySQLiteOpenHelper实现OpenHelper.
需要自己实现了onUpgrade方法来自定义升级过程。
当然升级过程中也要修改DaoMaster.SCHEMA_VERSION
当DaoMaster.SCHEMA_VERSION跟你当前数据库的版本比较后,会根据你当前数据库的版本,然后进行升级。
关键代码onUpgrade方法,会比较新数据库和旧数据库的版本,然后执行相应的sql升级:
public class MySQLiteOpenHelper extends DaoMaster.OpenHelper
public MySQLiteOpenHelper(Context context, String name) {
super(context, name);
public MySQLiteOpenHelper(Context context, String name, SQLiteDatabase.CursorFactory factory) {
super(context, name, factory);
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
//数据迁移模块
MigrationHelper.migrate(db,
UserDao.class,
ProfessionDao.class,
LTestDao.class);
数据库升级不外乎两种情况:
  1.修改表结构。
  2.添加新表。
针对onUpgrade中的实现方法可以采用两种不同策略:(稍后都会提供两种策略的代码实现,下面主要讲述第二种数据迁移实现方式)
 1.逐级版本迭代升级,比如当前版本为1,最新版本为3,此方案就是先从1--&2--&3.
 2.把数据库中的数据备份,然后全删数据库,再重新创建新的数据库,把备份数据导入。此方案直接从1--&3。
3. 数据迁移(数据库备份)的具体实现
android上面对的数据库基本上就是轻量级数据库sqlite,首先我们需要了解一些后面需要用到的数据库操作语句:
判断sqlite表是否存在
SELECT * FROM sqlite_master WHERE type='table' AND name='tempTableName';
sqlite判断临时表是否存在
SELECT * FROM sqlite_temp_master WHERE type='table' AND name='tempTableName';
sqlite创建表tableName的临时表
create temporary table tempTableName as select * from tableN
删除临时表
drop table tempTableN
sqlite的系统表sqlite_master、临时表sqlite_temp_master
SQLite数据库中一个特殊的名叫 SQLITE_MASTER上执行一个SELECT查询以获得所有表的索引。每一个 SQLite 数据库都有一个叫 SQLITE_MASTER的表, 它定义数据库的模式。 SQLITE_MASTER表看起来如下:
CREATE TABLE sqlite_master (
type TEXT,
name TEXT,
tbl_name TEXT,
rootpage INTEGER,
type 字段永远是 ‘table’,name 字段永远是对应表的名字。所以,要获得数据库中所有表的列表, 使用下列SELECT语句:
SELECT name FROM sqlite_master
WHERE type=’table’
对于索引,type 等于 ‘index’, name 则是索引的名字,tbl_name 是该索引所属的表的名字。 不管是表还是索引,sql 字段是原先用 CREATE TABLE 或 CREATE INDEX 语句创建它们时的命令文本。对于自动创建的索引(用来实现 PRIMARY KEY 或 UNIQUE 约束),sql字段为NULL。
SQLITE_MASTER 表是只读的。不能对它使用 UPDATE、INSERT 或 DELETE。 它会被 CREATE TABLE、CREATE INDEX、DROP TABLE 和 DROP INDEX 命令自动更新。
临时表及其索引和触发器存放在另外一个叫 SQLITE_TEMP_MASTER 的表中。SQLITE_TEMP_MASTER 跟 SQLITE_MASTER 差不多, 但它只是对于创建那些临时表的应用可见。如果要获得所有表的列表, 不管是永久的还是临时的,可以使用类似下面的命令:
SELECT name FROM
(SELECT * FROM sqlite_master UNION ALL
SELECT * FROM sqlite_temp_master)
WHERE type=’table’
ORDER BY name
数据迁移的工具类MigrationHelper。
public final class MigrationHelper {
public static boolean DEBUG =
private static String TAG = "MigrationHelper";
private static final String SQLITE_MASTER = "sqlite_master";
private static final String SQLITE_TEMP_MASTER = "sqlite_temp_master";
public static void migrate(SQLiteDatabase db, Class&? extends AbstractDao&?, ?&&... daoClasses) {
Database database = new StandardDatabase(db);
printLog("【The Old Database Version】" + db.getVersion());
printLog("【Generate temp table】start");
generateTempTables(database, daoClasses);
printLog("【Generate temp table】complete");
dropAllTables(database, true, daoClasses);
createAllTables(database, false, daoClasses);
printLog("【Restore data】start");
restoreData(database, daoClasses);
printLog("【Restore data】complete");
private static void generateTempTables(Database db, Class&? extends AbstractDao&?, ?&&... daoClasses)
for (int i = 0; i & daoClasses. i++) {
String tempTableName =
DaoConfig daoConfig = new DaoConfig(db, daoClasses[i]);
String tableName = daoConfig.
if (!isTableExists(db, false, tableName)) {//不存在系统表中,表明是新增表,不需要创建临时表
printLog("【New Table】" + tableName);
tempTableName = daoConfig.tablename.concat("_TEMP");
StringBuilder dropTableStringBuilder = new StringBuilder();
dropTableStringBuilder.append("DROP TABLE IF EXISTS ").append(tempTableName).append(";");
db.execSQL(dropTableStringBuilder.toString());
StringBuilder insertTableStringBuilder = new StringBuilder();
insertTableStringBuilder.append("CREATE TEMPORARY TABLE ").append(tempTableName);
insertTableStringBuilder.append(" AS SELECT * FROM ").append(tableName).append(";");
db.execSQL(insertTableStringBuilder.toString());
printLog("【Table】" + tableName +"\n ---Columns--&"+getColumnsStr(daoConfig));
printLog("【Generate temp table】" + tempTableName);
} catch (SQLException e) {
Log.e(TAG, "【Failed to generate temp table】" + tempTableName, e);
private static boolean isTableExists(Database db, boolean isTemp, String tableName) {
if (db == null || TextUtils.isEmpty(tableName)) {
String dbName = isTemp ? SQLITE_TEMP_MASTER : SQLITE_MASTER;
String sql = "SELECT COUNT(*) FROM " + dbName + " WHERE type = ? AND name = ?";
Cursor cursor=
int count = 0;
cursor = db.rawQuery(sql, new String[]{"table", tableName});
if (cursor == null || !cursor.moveToFirst()) {
count = cursor.getInt(0);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (cursor != null)
cursor.close();
return count & 0;
private static String getColumnsStr(DaoConfig daoConfig) {
if (daoConfig == null) {
return "no columns";
StringBuilder builder = new StringBuilder();
for (int i = 0; i & daoConfig.allColumns. i++) {
builder.append(daoConfig.allColumns[i]);
builder.append(",");
if (builder.length() & 0) {
builder.deleteCharAt(builder.length() - 1);
return builder.toString();
private static void dropAllTables(Database db, boolean ifExists, @NonNull Class&? extends AbstractDao&?, ?&&... daoClasses) {
reflectMethod(db, "dropTable", ifExists, daoClasses);
printLog("【Drop all table】");
private static void createAllTables(Database db, boolean ifNotExists, @NonNull Class&? extends AbstractDao&?, ?&&... daoClasses) {
reflectMethod(db, "createTable", ifNotExists, daoClasses);
printLog("【Create all table】");
* dao class already define the sql exec method, so just invoke it
private static void reflectMethod(Database db, String methodName, boolean isExists, @NonNull Class&? extends AbstractDao&?, ?&&... daoClasses) {
if (daoClasses.length & 1) {
for (Class cls : daoClasses) {
Method method = cls.getDeclaredMethod(methodName, Database.class, boolean.class);
method.invoke(null, db, isExists);
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
private static void restoreData(Database db, Class&? extends AbstractDao&?, ?&&... daoClasses) {
for (int i = 0; i & daoClasses. i++) {
DaoConfig daoConfig = new DaoConfig(db, daoClasses[i]);
String tableName = daoConfig.
String tempTableName = daoConfig.tablename.concat("_TEMP");
if (!isTableExists(db, true, tempTableName)) {
// get all columns from tempTable, take careful to use the columns list
List&String& columns = getColumns(db, tempTableName);
ArrayList&String& properties = new ArrayList&&(columns.size());
for (int j = 0; j & daoConfig.properties. j++) {
String columnName = daoConfig.properties[j].columnN
if (columns.contains(columnName)) {
properties.add(columnName);
if (properties.size() & 0) {
final String columnSQL = TextUtils.join(",", properties);
StringBuilder insertTableStringBuilder = new StringBuilder();
insertTableStringBuilder.append("INSERT INTO ").append(tableName).append(" (");
insertTableStringBuilder.append(columnSQL);
insertTableStringBuilder.append(") SELECT ");
insertTableStringBuilder.append(columnSQL);
insertTableStringBuilder.append(" FROM ").append(tempTableName).append(";");
db.execSQL(insertTableStringBuilder.toString());
printLog("【Restore data】 to " + tableName);
StringBuilder dropTableStringBuilder = new StringBuilder();
dropTableStringBuilder.append("DROP TABLE ").append(tempTableName);
db.execSQL(dropTableStringBuilder.toString());
printLog("【Drop temp table】" + tempTableName);
} catch (SQLException e) {
Log.e(TAG, "【Failed to restore data from temp table 】" + tempTableName, e);
private static List&String& getColumns(Database db, String tableName) {
List&String& columns =
Cursor cursor =
cursor = db.rawQuery("SELECT * FROM " + tableName + " limit 0", null);
if (null != cursor && cursor.getColumnCount() & 0) {
columns = Arrays.asList(cursor.getColumnNames());
} catch (Exception e) {
e.printStackTrace();
} finally {
if (cursor != null)
cursor.close();
if (null == columns)
columns = new ArrayList&&();
private static void printLog(String info){
if(DEBUG){
Log.d(TAG, info);
4. 设置数据库路径
在第一模块中有句代码:
MySQLiteOpenHelper devOpenHelper = new MySQLiteOpenHelper(new GreenDaoContext(), "database_name.db", null);//GreenDaoContext为创建数据库路径使用
里面有个上下文GreenDaoContext继承了ContextWrapper,里面设置了数据库路径,代码如下:
public class GreenDaoContext
extends ContextWrapper {
private String currentUserId = "greendao";//一般用来针对一个用户一个数据库,以免数据混乱问题
private Context mC
public GreenDaoContext() {
super(MyApplication.getContext());
this.mContext = MyApplication.getContext();
this.currentUserId = "greendao";//初始化
* 获得数据库路径,如果不存在,则创建对象
* @param dbName
public File getDatabasePath(String dbName) {
String dbDir = CommonUtils.getDBPath();
if (TextUtils.isEmpty(dbDir)){
Log.e("SD卡管理:", "SD卡不存在,请加载SD卡");
File baseFile = new File(dbDir);
// 目录不存在则自动创建目录
if (!baseFile.exists()){
baseFile.mkdirs();
StringBuffer buffer = new StringBuffer();
buffer.append(baseFile.getPath());
buffer.append(File.separator);
buffer.append(currentUserId);
dbDir = buffer.toString();// 数据库所在目录
buffer.append(File.separator);
buffer.append(dbName+"_"+currentUserId);//也可以采用此种方式,将用户id与表名联系到一块命名
buffer.append(dbName);
String dbPath = buffer.toString();// 数据库路径
// 判断目录是否存在,不存在则创建该目录
File dirFile = new File(dbDir);
if (!dirFile.exists()){
dirFile.mkdirs();
// 数据库文件是否创建成功
boolean isFileCreateSuccess =
// 判断文件是否存在,不存在则创建该文件
File dbFile = new File(dbPath);
if (!dbFile.exists()) {
isFileCreateSuccess = dbFile.createNewFile();// 创建文件
} catch (IOException e) {
e.printStackTrace();
isFileCreateSuccess =
// 返回数据库文件对象
if (isFileCreateSuccess)
return dbF
return super.getDatabasePath(dbName);
* 重载这个方法,是用来打开SD卡上的数据库的,android 2.3及以下会调用这个方法。
* @param name
* @param mode
* @param factory
public SQLiteDatabase openOrCreateDatabase(String name, int mode,
SQLiteDatabase.CursorFactory factory) {
SQLiteDatabase result = SQLiteDatabase.openOrCreateDatabase(getDatabasePath(name), factory);
* Android 4.0会调用此方法获取数据库。
* @param name
* @param mode
* @param factory
* @param errorHandler
* @see android.content.ContextWrapper#openOrCreateDatabase(java.lang.String, int,
* android.database.sqlite.SQLiteDatabase.CursorFactory,
* android.database.DatabaseErrorHandler)
public SQLiteDatabase openOrCreateDatabase(String name, int mode, SQLiteDatabase.CursorFactory factory,
DatabaseErrorHandler errorHandler) {
SQLiteDatabase result = SQLiteDatabase.openOrCreateDatabase(getDatabasePath(name), factory);
OK,先到这了。。。
http://jinnianshilongnian.iteye.com/blog/2022468
Realm数据库系列教程 http://www.easydone.cn/数据库greendao升级笔记 packagexcxin.filexpert.or...
本文介绍Android平台进行数据存储的五大方式,分别如下: 1使用SharedPreferences存储数据 2文件存储数据 3SQLite数据库存储数据 4使用ContentProvider存储数据 5网络存储数据 下面详细讲解这五种方式的特点 第一种:使用Shared...
Spark SQL, DataFrames and Datasets Guide Overview SQL Datasets and DataFrames 开始入门 起始点: SparkSession 创建 DataFrames 无类型的Dataset操作 (aka Dat...
使用场景 版本升级后,增加表、删除表、增加字段、删减字段等。为了保留原始数据,需要将数据进行迁移。使用GreenDao数据库的升级操作该如何进行呢? GreenDao的简单实现可以参考:http://www.jianshu.com/p/4986100eff90 思路 创建临...
前言: 上一篇简介了greendao的数据库的接入以及简单的操作,既然涉及到数据库中的数据,那就必须考虑到加密问题了,可能有些隐秘的数据不能直接加密,我们就需要使用加密了。一旦我们数据库结构改变了,我们就需要使用数据库更新了。 一:数据库加密 我们这里使用sqlcipher...
可能也有同学和我有一样的疑问,为什么request.getInputStream不能用在get方式提交表单上呢? 因为get方式一般没有请求包体,request.getInputStream是针对http请求包包体进行读取,也就是说,只适用于post方式提交表单的方式了。 ...
长大后第一次吃汉堡王,新年第一天,坐标成都,外卖点了一张毛爷爷的汉堡王,给男朋友拍照他直流口水,叫我写吃后感,干脆写了一篇测评,小吃货决定把吃过的每一样美食都用心记录下来,跟其他的小吃货们一起分享讨论~ 薯霸王 汉堡王的薯条比KFC和M记的粗短一些,更偏向于美式薯条,味道上...
我只是把你给我的感受一点点讲清楚给你听。你经常跟我们在一起时,总是会说安排了自己什么时候做正事,给我们的感觉是你很忙,可是只要是你的朋友一个电话,你常常都是上一秒钟才对我们说有正事,下一秒钟就愉快的答应别人先去玩!感受是没有错的,何况我们是你最亲的人。你自己去想想吧,我越来...
以前写到跑步,我总是在说它的好处,以及如何喜欢上它,如何把它变成生活的一部分。但是也有读者留言说,你为什么不说跑步也容易受伤呢? 说实话,在我已累计跑过的这一年零八个月的时间里,在我已累计跑过的这3500公里的路程上,我不是没有受过伤,我也很了解一个刚刚爱上跑步不久就受伤的...
今天是练习与点评时间 回顾了过去三次课程,1连续说话整天不累的方法,2打开口腔说话,听清你的表达,3让你的声音有色彩,语言表情更动人。 对老师的讲解又多了一层领悟,练习了基本功和作业。 数量的积累,实践,思考,质量的变化开始显现。 老师的几次点评,包括没有力量,缺乏层次,声...}

我要回帖

更多关于 只读工作簿 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信