开发AIR应用程序使用SQLite的最佳做法应用程序、做法、AIR、SQLite

2023-09-08 12:25:11 作者:凉心骚年i

我要开始做一对夫妇将使用由 AIR 提供的SQLite 功能的Adobe AIR项目。由于这是我第一次尝试这样做,我会AP preciate发展的一些指针,技巧和最佳实践。

I am going to start doing a couple of Adobe AIR projects that will be using SQLite feature provided by AIR. Since this is the first time I am attempting to do this, I would appreciate some pointers, tips and Best Practices for development.

由于该应用程序将访问本地数据库,我想我可以打开的应用程序开始连接到数据库并保持打开状态,直到应用程序关闭。这是一个正确的方法用在这里?

Since this application will be accessing a local db, I think I can open a connection to the database at the start of the app and keep it open till the application closes. Is this a right approach to use here?

如果我使用一个MVC框架,比如应该如何设计我的应用程序配合凯恩戈姆

How should design my application if I am using an MVC framework like Mate or Cairngorm?

我应该创造一些包装类执行数据库操作,所以我可以在其他一些项目中重用呢?期待一些有价值的信息...

Should I create some wrapper class to perform the db operations so I can reuse this in some other project? Looking forward to some valuable information...

推荐答案

第一个和你必须做出到目前为止最重要的决定,就是不管你是要同步或异步访问该数据库。他们都有自己的优点和缺点,所以这将取决于你的情况。

The first and by far most important decision you have to make, is whether you're going to access that database synchronously or asynchronously. They both have their pros and cons, so it will depend on your situation.

同步

在简单的架构 更容易阅读 更适合于小规模行动 冻结的应用程序,而这样做的作业

适合小规模的应用程序

异步

在更复杂的架构 难读 在长时间操作也不会冻结UI 如果你有一台服务器数据库同步,您可以为本地和远程数据库服务的接口(如类 LocalUserService RemoteUserService 都实现,迫使他们有一个方法的接口 saveUser()) more complex architecture harder to read long operations will not freeze the UI if you have to sync with a server DB, you can create an interface for both local and remote DB services (e.g. the class LocalUserService and RemoteUserService both implement an interface that forces them to have a method saveUser())

适合较大规模的应用程序,并同步本地和远程数据。

Good for larger scale app and synchronizing local and remote data.

我倾向于几乎总是选择异步方法 - 因为它更灵活 - 和抽象的复杂性之外的......一个包装类。所以,回答你的问题的一部分。

I tend to almost always opt for the asynchronous approach - since it's more flexible - and abstract the complexity away in ... a wrapper class. So that answers that part of your question.

建筑

我不喜欢的框架,所以我不能回答你关于配合或-shudder- 凯恩戈姆。但这里是我认为一个比较好的办法:

I don't like frameworks, so I can't answer your question about Mate or -shudder- Cairngorm. But here's what I consider a fairly good approach:

为模型中的每一个实体,创建数据艾策斯对象(DAO),将只返回原始查询结果(如的UserDAO 的quering用户)。这个类应该只包含查询。 在匹配每个DAO创建一个生成器/工厂,可以采取这些查询结果和产卵模型对象(如UserBuilder) 这通常是足以让我,但你也可以把他们两个人一起在一个服务层(如UserService的)。该服务层还可能有助于匹配现有的远程服务层到本地服务。 for each entity in your model, create a Data Acces Object (DAO) that will return only raw query results (e.g. UserDAO for quering Users). That class should contain only queries. matching each DAO create a Builder/Factory that can take those query results and spawn model objects (e.g. UserBuilder) this is usually enough for me, but you could also bring the two of them together in a service layer (e.g. UserService). This service layer might also help matching an existing remote service layer to your local services.

对于保持连接打开。我一直这样做的,从未发生过任何问题了。我并不确切地知道当一个应用程序崩溃和连接没有正确关闭会发生什么,但这不是Oracle或SQL Server,我们正在谈论。我不认为SQLite的将保持开放的指针或东西,因为它只是一个简单的文件,但我可能是错的。

As for keeping the connection open. I've always done so and never had any issues with it. I don't exactly know what happens when an application crashes and the connection wasn't properly closed, but this is not Oracle or SQL Server we're talking about. I don't think SQLite will keep open pointers or something since it's just a simple file, but I might be wrong.

编辑:的DAO /工厂模式的一些详细信息(如要求OP)

some more details on the DAO / Factory pattern (as requested by OP).

一UserDAO的同一种功能的例子:

An example of a UserDAO with one function:

public class PupilDAO extends AsynchronousDAO {

    public function getUserById(id:int, handleResult:Function):Responder {
        return getResults(
            "SELECT * FROM user WHERE user_id = ?", 
            handleResult, [id]
        );
    }

}

正如你所看到的,我已经抽象出复杂到 AsynchronousDAO 的基类,所以我们只能看到在UserDAO的必要的信息。该 handleResult 函数是只要查询已准备好,通过在ResultSet作为参数,将调用回调函数。我们通常会传递结果集到工厂/生成器类。

As you can see, I've abstracted out the complexity into the AsynchronousDAO base class, so we can see only the necessary information in UserDAO. The handleResult function is a callback that will be called whenever the query is ready, passing in the resultset as an argument. We'll usually pass that resultset into the factory/builder class.

一UserBuilder的一个例子:

An example of a UserBuilder:

public class UserBuilder {

    public function buildUser(record:*):User {
        var user:User = new User();
        user.id = record.user_id;
        user.firstname = record.firstname;
        user.lastname = record.lastname;
        return user;
    }

}

这显然是一个简单的例子,但你可以在构建器创建更复杂的数据结构。有关工厂和生成器模式之间的差异的一些信息,我建议谷歌。

This is obviously a simple example, but you can create more complex data structures in the builder. For some info on the difference between the Factory and Builder patterns I recommend Google.

现在,让我们绑在一起,在服务类:

Now let's tie it together in the service class:

public class UserService {
    private var dao:UsetDAO;
    private var builder:UserBuilder;

    public UserService(dao:UserDAO, builder:UserBuilder) {
        this.dao = dao;
        this.builder = builder;
    }

    public function getUserById(id:int, handleResult):void {
        var handleResultSet:Function = function(resultSet:SQLResult):void {
            var user:User = builder.buildUser(resultSet.data[0]);
            if (handleResult!= null) handleResult(user);
        }

        dao.getUserById(id, handleResultSet);            
    }

}

最后,让我们把三人的使用方法:

Finally, let's put the trio to use:

var userService = new UserService(new UserDAO(), new UserBuilder());
userService.getUserById(1, handleUser);

function handleUser(user:User):void {
    trace(user);
}

有关的比如我建类与并通过了DAO和建设者的构造函数的参数,但你可以使用注射或单身或任何框架,你喜欢做的事建筑给你。

For the example I constructed the classes with new and passed the dao and the builder as constructor arguments, but you could use injection or singletons or whatever framework you like to do the construction for you.