• Android数据库ORMlite框架翻译系列(第二章:part 1)


    前言

    由于第二章是整个文档的核心,内容也很多,所以分次翻译。下一章的内容会继续本章接着翻译。

    -------------------------------------------------------------------------------------

    2 如何使用

    这一章进入到更多详细地使用ORMLite的各种功能。

     

    2.1 配置你的Class

    为了配置你的class使其持久化,你需要做下面几步:

    ①添加@DatabaseTable 注解到你每个需要持久化的类的顶部。你也可以用@Entity

    ②添加@DatabaseField 注解到你需要持久化的字段的上面。你也可以使用@Column和其他的。

    ③为每个class添加一个无参的构造器,并且构造器在包内是可见的。

     

    2.1.1 添加ORMLite 注解

    自从java5开始,注解是有效的特殊代码标识,它提供meta信息包括类、方法或成员变量。把指定的类和成员变量存入数据库,ORMLite既支持它自己的注解(@DatabaseTable和 @DatabaseField)也支持很多来自javax.persistence包中标准的注解。注解是配置你的class最简单的方式,当然你也可以使用java代码或者Spring xmlSpring是个框架,更多信息google一下)对class进行配置。

    ORMLite注解,对每个你想要持久化到SQL数据库的java类你都需要添加@DatabaseTable注解到public class 这一行的正上方。每个被这些注解标记过的class都将持久化到它自己的数据库表中。例如:

    @DatabaseTable(tableName = "accounts")
    
    public class Account {
    
    ...

    @DatabaseTable注解可以有个可选的tableName 参数,也就是这个类对于的表名。如果没有特别指出,那么这个类名将默认作为表名。使用示例中的Account的对象都将会作为一条记录持久化到数据库名为account的表中。这将会在DaoManager实例化内部Dao的时候使用到。

    除此之外,对于每个class你需要添加@DatabaseField注解到class的成员变量上,这个类是需要持久化到数据库的。每个成员变量都将被作为数据库中记录的一个字段进行持久化。示例:

     

    @DatabaseTable(tableName = "accounts")
    
    public class Account {
    
    @DatabaseField(id = true)
    
    private String name;
    
    @DatabaseField(canBeNull = false)
    
    private String password;
    
    ...

    name字段,它是一个字符串并且是数据库中记录的唯一标识(主键)。在上面的示例中,account表的每条记录都有两个字段:

    password字段,它也是一个字符串,它不能为null

    @DatabaseField注解可以用下面的一些成员:(对常用的字段进行翻译,其他的参考原文)

    常用的注解

    成员名

    数据类型

    描述

    columnName

    String

    数据库的列名。如果你没有设置这个成员名,会用标准的形式代替它。

    dataType

     

    字段的数据类型。通常情况下,数据类型是从java类的成员变量获取的,并不需要进行特殊指出。它相当于是SQL的数据类型。

    defaultValue

    String

    当我们在表中创建新的记录时的一个字段的默认值。默认情况下是没有这个值的。

    width

    Integer

    字段的宽度,主要用于字符串字段。默认是0,意味着采用默认的数据类型和具体的数据库的默认情况。对于字符串以为在255个字符即使有些数据库并不支持。

    canBeNull

    Boolean

    字段是否能被分配null值。默认是true。如果你设置成false,那么你每次在数据库中插入数据是都必须为这个字段提供值。

    id

    Boolean

    这个字段是否是id,默认是false。在一个class中只有一个成变量可以有这个值。id字段是一条记录的唯一标识而且是必需的,只有generatedId和 generatedIdSequence其中之一。

    generatedId

    Boolean

    字段是否自动增加。默认为false。类中的一个成员变量设置了这个值,它告诉数据库每添加一条新记录都自动增加id。当一个有generatedid的对象被创建时使用Dao.create()方法,数据库将为记录生成一个id,它会被返回并且被create方法设置进对象。

    generatedIdSequence

    String

    序列编号的名字,这个值在生成的时候会被使用。和generatedId相似,但是你能够指定使用的序列名称。默认是没有的。一个class中只有一个成员变量可以设置这个值。这仅仅在数据库需要序列生成id时才需要它。如果你选择使用generatedId代替它,那么代码将自动增加序列名。

     

    其他注解

    foreign

    throwIfNull

    useGetSet

    persisted

    unknownEnumName

    format

    uniqueIndexName

    allowGeneratedIdInsert

    foreignAutoRefresh

    columnDefinition

    unique

    uniqueIndex

    uniqueCombo

    indexName

    index

    uniqueIndexName

    version

    maxForeignAutoRefreshLevel

    foreignColumnName

    foreignAutoCreate

     

    2.1.2 使用javax.persistence 注解

    取代使用ORMLite注解,你可以使用来自javax.persistence包的更多的标准JPA注解。取代@DatabaseTable注解,你可以使用javax.persistence @Entity注解。示例:

    @Entity(name = "accounts")
    
    public class Account {
    
    ...

    @Entity注解有个可选的name参数,它用于指定表名。如果没有指定,类名将是默认的表名。

    在每个成员变量中取代使用@DatabaseField注解,你可以用javax.persistence注解: @Column, @Id, @GeneratedValue, @OneToOne,@ManyToOne, @JoinColumn, and @Version. 示例:


    下面这些javax.persistence注解和字段都支持:

    注解

    注解属性

    描述

    @Entity

    name

    用于关联的数据库表的名字。如果没有设置那么类名将被作为表名。

    @Column

    name

    用作表字段的名字。如果没有设置那么变量名将作为字段名。

    length

    数据库表字段的长度。可能只有应用在字符串并且只被某些数据库类型支持。默认是255

    nullable

    设置成true,那么这个字段允许插入null值。

    unique

     添加一个约束,它在表中必须是唯一的。

    @GeneratedValue

     

    用于定义一个自动增长的id值,它只能用于添加到@Id注解。

     

    @OneToOne 

     

    成员变量使用这些注解后会被认为是外键字段。 ORMLite没有实现多个或一个关系,它也不能使用任何注解成员。它只能使用这些注解的两者之一来表明它是一个外键。

    @ManyToOne

     

    @JoinColumn

    name

    设置成员变量的列名(字段名)。

    nullable

    设置成true,那么这个字段允许插入null值。

    @Version

     

    使用它将会把short, integer, long,  Date这些类型的成员转化成版本成员。

    如果@Column注解在成员变量上用了一个未知的类型,那么它将被认为是序列化类型字段并且这个对象需要实现java.io.Serializable

     

    2.1.3 添加无参构造器

    在你给class添加了注解字段后,你也需要添加一个无参的包内可见的构造器。当一个对象在查询中被返回时,ORMLite使用java反射机制构造一个对象并且构造器需要被调用。所以你最终的示例拥有注解和构造器的Account类应该像这样:

     

    @DatabaseTable(tableName = "accounts")
    
    public class Account {
    
    @DatabaseField(id = true)
    
    private String name;
    
    @DatabaseField(canBeNull = false)
    
    private String password;
    
    ...
    
    Account() {
    
    // all persisted classes must define a no-arg constructor
    
    // with at least package visibility
    
    }
    
    ...
    
    }

    2.2 持久化数据类型 

    下面这些java类型能够被ORMLite持久化到数据库。数据库具体编码帮助SQL类型和数据库具体持有类型的相互转化。

    (具体的类型相互转化在此就不作介绍了,参见原文)。

     

    2.3 连接源

    注意:关于连接源,android用户应该参见手册中Android详细文档。

    为了使用数据库和DAO对象,你需要配置JDBC调用数据源和ORMLite调用连接源。连接源是连接物理SQL数据库的一个工厂。这里是创建简单、单连接的代码示例:

    // single connection source example for a database URI
    
    ConnectionSource connectionSource =
    
    new JdbcConnectionSource("jdbc:h2:mem:account");

    这包中也包括了类JdbcPooledConnectionSource ,它是一个相对简单的连接池的实现。一个数据库连接已经释放而成为关闭,之后向他们添加内部列表他们都会拒绝。只有在没有休眠的可用的连接时,新的连接才需要创建。JdbcPooledConnectionSource也是同步的并且可以用于多线程中。在连接关闭前它可以设置空闲连接的最大数和存活的最长时间。

    // pooled connection source
    
    JdbcPooledConnectionSource connectionSource =
    
    new JdbcPooledConnectionSource("jdbc:h2:mem:account");
    
    // only keep the connections open for 5 minutes
    
    connectionSource.setMaxConnectionAgeMillis(5 * 60 * 1000);


    JdbcPooledConnectionSource也有一个一直存活的线程,它偶尔ping一下池中空闲的每个连接,目的是为了确认他们是有效的,关闭的那个就不再有效。在你从池中取得连接之前你也可以测试连接是否有效。

    // change the check-every milliseconds from 30 seconds to 60
    
    connectionSource.setCheckConnectionsEveryMillis(60 * 1000);
    
    // for extra protection, enable the testing of connections
    
    // right before they are handed to the user
    
    connectionSource.setTestBeforeGet(true);


    有很多其他额外的数据,他们能够被使用,包括很多更强大甚至高性能的池连接管理器。你可以用你自己直接封装的DataSourceConnectionSource类来例举说明。

    // basic Apache data source
    
    BasicDataSource dataSource = new BasicDataSource();
    
    String databaseUrl = "jdbc:h2:mem:account";
    
    dataSource.setUrl(databaseUrl);
    
    // we wrap it in the DataSourceConnectionSource
    
    ConnectionSource connectionSource =
    
    new DataSourceConnectionSource(dataSource, databaseUrl);


    当你用ConnectionSource时,你想调用close()方法来关闭一些底层的连接。推荐像下面这样的模式。

    JdbcConnectionSource connectionSource =
    
    new JdbcPooledConnectionSource("jdbc:h2:mem:account");
    
    try {
    
    // work with the data-source and DAOs
    
    ...
    
    } finally {
    
    connectionSource.close();
    
    }


    很不幸,DataSource接口没有关闭方法,所以你使用DataSourceConnectionSource你必须关闭底层数据源,通过操作DataSourceConnectionSource上的close()方法。

     

    2.4 配置DAOs

    一旦在你的类中有注解并且定义了你的ConnectionSource,你就需要创建一个DAOData Access Object),它是一个拥有数据库操作句柄的单一持久化类。每个DAO都有两个泛型参数:①我们用DAO持久化的类,②id字段,它用于确定数据库具体的记录。如果你的类没有ID字段,你可以放入Object或者Void作为第二个参数。例如,在上面的Account类,成员变量nameID字段,所以ID类是String

    创建DAO最简单的方式是使用DaoManager类的静态方法createDao。示例:

    Dao<Account, String> accountDao =
    
    DaoManager.createDao(connectionSource, Account.class);
    
    Dao<Order, Integer> orderDao =
    
    DaoManager.createDao(connectionSource, Order.class);


    注意:你需要使用DaoManager.createDao()方法创建你自己的DAO类,所以如果内置ORMLite功能是需要他们,他们可以被再次利用并且不能再次生成。创建DAO会有昂贵的操作代价并且很多设备有资源限制(比如移动设备应用),尽可能重复使用DAO 

    如果你想更好的类层次的机构或者你需要添加附加的方法套你的DAOs中,你应该考虑定义一个接口,它继承自Dao接口。这个接口不是必需的,但是他说一种好的模式,这样你的代码在关联JDBC持久化的时候会更少。接下来是一个相当于本手册前面章节Account类的DAO接口的示例:

    /** Account DAO which has a String id (Account.name) */
    
    public interface AccountDao extends Dao<Account, String> {
    
    // empty wrapper, you can add additional DAO methods here
    
    }

    然后在实现中,你需要扩展BaseDaoImpl基类。这里是个实现你的DAO接口的示例。

    /** JDBC implementation of the AccountDao interface. */
    
    public class AccountDaoImpl extends BaseDaoImpl<Account, String>
    
    implements AccountDao {
    
    public AccountDaoImpl(ConnectionSource connectionSource)
    
    throws SQLException {
    
    super(connectionSource, Account.class);
    
    }
    
    }


    那就是你需要定义你的DAO类。如果有特殊的操作需要并且Dao基类没有提供的方法,你可以自由添加更多方法到你的DAO接口和添加到你的实现中。

    注意:如果你正在使用一个定制的DAO,然后确保添加daoClass参数到你自己定制的DAO类的@DatabaseTable注解。这会被DaoManager用于内部实例化DAO

     

    2.5 支持的数据库

    ORMLite支持下面的数据库。这些数据库中的某些数据库有具体需要遵守的文档。(下面给出支持的数据库,具体文档参见官方文档)

    支持的数据库

    MySQL

    H2

    Android SQLite

    HSQLDB

    Netezza

    DB2

    Postgres

    SQLite

    Microsoft SQL Server

    Derby

    ODBC

    Oracle

     

    2.6 整合

    这样你有一个注解对象被持久化,添加一个无参构造器,创建你的ConnectionSource并且定义你的DAO类。你已经开始持久化和查询你的数据库对象了。你需要下载并且添加H2 jar文件到你的classPath中,如果你想让这个示例跑起来的话。下面是整合的代码:

    // h2 by default but change to match your database
    
    String databaseUrl = "jdbc:h2:mem:account";
    
    JdbcConnectionSource connectionSource =
    
    new JdbcConnectionSource(databaseUrl);
    
    // instantiate the dao with the connection source
    
    AccountDaoImpl accountDao = new AccountDaoImpl(connectionSource);
    
    // if you need to create the 'accounts' table make this call
    
    TableUtils.createTable(connectionSource, Account.class);
    
    // create an instance of Account
    
    Account account = new Account("Jim Coakley");
    
    // persist the account object to the database
    
    accountDao.create(account);
    
    ...
    
    // destroy the data source which should close underlying connections
    
    connectionSource.destroy();


    PS: 第二章还在翻译中... 文中有不妥之处希望读者提出,转载请注明出处。

     

  • 相关阅读:
    构建之法阅读笔记05
    构建之法阅读笔记04
    大二上学期软件工程概论学习进度表(第十二周)
    构建之法阅读笔记03
    四则运算二
    GCD
    Category的使用
    适配6 、6P 来源互联网
    UIView阴影和圆角的关系
    NSSet类型 以及与NSArray区别
  • 原文地址:https://www.cnblogs.com/vanezkw/p/2619798.html
Copyright © 2020-2023  润新知