ORMLite使用示例

ORMLite是一款适用于Java和Android的轻量级ORM框架,支持多种数据库。本文详细介绍了ORMLite的注解使用、连接池、DAO创建、增删改查操作、SQL支持、Spring配置、事务与批量操作等核心功能,帮助开发者快速掌握ORMLite的使用技巧。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

ORMLite是一款优秀的轻量级的ORM框架,常用于Android平台,但它并不是 Android 平台专用的ORM框架,它也可用于普通的Java环境中。 ORMLite除了支持Sqlite外还支持MySQL, Postgres, Microsoft SQL Server, H2, Derby, HSQLDB等数据库。支持JDBC连接,Spring以及Android平台。语法中广泛使用了注解(Annotation)。

必须的jar包:ORMLite的核心包是ormlite-core.jar,在普通的java环境中使用还需要添加ormlite-jdbc.jar,在Android环境中使用则需要ormlite-android.jar。

可选的jar包:(Log包)
Apache commons logging,,Log4j,Android Log 等
ORMLite启动后log代码会在classpath中依次查找android.util.Log、org.apache.commons.logging.LogFactory、org.apache.log4j.Logger等,如果找到前一个则不再继续查找。如果这几个类都不存在,ORMLite则使用自身内置的log代码记录日志。

本文以普通java环境中ORMLite的使用为例展示ORMLite的常用技巧和注意事项。ORMLite在Android环境中的使用与普通java环境中的使用基本一致,不同的是数据源以及配置的不同,而且Android环境中ormlite-android.jar提供了一些特定的工具类,使用起来更加方便,具体请参见官网:http://ormlite.com/

入门示例

ORMLite的使用非常简单,先看一个入门代码示例:

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

    @DatabaseField(canBeNull = false)
    private String password;
        Account() {
        // 必须有一个无参数构造函数
        }
Account(String name, String pwd) {
this.name=name;
this.password=pwd;      
    }
   }
// 数据库url
String databaseUrl = "jdbc:h2:mem:account";
// 创建一个数据库连接
ConnectionSource connectionSource =
     new JdbcConnectionSource(databaseUrl);

// 创建DAO对象
Dao<Account,String> accountDao =
     DaoManager.createDao(connectionSource, Account.class);

// 创建表(视需求而定)
TableUtils.createTable(connectionSource, Account.class);

// 创建实体对象
String name = "Jim Smith";
Account account = new Account(name, "_secret");

// 持久化到数据库
accountDao.create(account);

// 从数据库中查询
Account account2 = accountDao.queryForId(name);
System.out.println("Account: " + account2.getPassword());

// 关闭连接池
connectionSource.close();

ORMLite中注解的使用

ORMLite使用注解标明实体字段与数据库表字段的对应关系。注解既可使用ORMLite的注解,如 @DatabaseTable,@DatabaseField等;也可使用javax.persistence的注解,如@Entity、@Id、@Column等

比如:

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

等价于

@Entity(name = "accounts")
    public class Account {
        @Id
        private String name;
        @Column(nullable = false)
        private String password;
        //      …
    }

注意事项:

  • 实体类必须有一个无参构造函数,有get/set方法

ORMLite连接池的使用

ORMLite对连接池做了一层封装,使用com.j256.ormlite.support.ConnectionSource接口表示。ConnectionSource接口的实现类有JdbcConnectionSource、JdbcPooledConnectionSource、DataSourceConnectionSource等,分别代表单个连接的连接池、jdbc可复用连接池、数据源连接池等。

示例如下:

final String url="jdbc:h2:mem:account";
        // 单个连接的连接池
        ConnectionSource jdbcconnectionSource =  
                new JdbcConnectionSource(url);
        // 带缓存的连接池
        JdbcPooledConnectionSource pooledconnectionSource =
                new JdbcPooledConnectionSource(url);
        // 数据源
        BasicDataSource dataSource = new BasicDataSource();
        dataSource.setUrl(url);
        // 数据源连接池
        ConnectionSource dsconnectionSource = 
          new DataSourceConnectionSource(dataSource, url);

注意事项:

  • DataSource接口没有close方法,因而调用DataSourceConnectionSource的close方法其实什么也没做,DataSource需要我们手动关闭。
  • JdbcConnectionSource不是线程安全的,不能用在多线程环境中

ORMLite中DAO的创建

Data Access Object (DAO) 可以使用DaoManager.createDao方法创建,也可以继承BaseDaoImpl类创建具有额外功能的自定义DAO。
示例如下:

//使用DaoManager创建Dao,泛型第一个参数为实体类,第二个参数为主键类
        Dao<User, Integer> userDao =
                  DaoManager.createDao(connectionSource, User.class);
自定义DAO
/** 继承BaseDaoImpl实现自定义DAO类 */
    public class UserDaoImpl extends BaseDaoImpl<User, Integer>{
        public UserDaoImpl(ConnectionSource connectionSource)
          throws SQLException {
            super(connectionSource, User.class);
        }
    }
//在实体类上用注解标明自定义DAO的类文件
@DatabaseTable(daoClass = UserDaoImpl.class)
    public class Account {
       //…
    }

注意事项:

  • 创建DAO的开销比较大,尽量将DAO重复利用。DaoManager具有缓存功能,可以将创建的DAO缓存下来,避免重复创建,因此尽量使用DaoManager创建DAO

ORMLite使用DAO进行增删改查操作

ORMLite框架的DAO接口为用户提供了丰富的CRUD操作的重载方法。

CRUD示例:

                //构造JavaBean
                User u=new User(111,"ormlite_111");
                //插入数据
                userDao.create(u);
                //更新
                u1.setName("ormlite_111_updated");
                userDao.update(u);              
                //查询
                User uq = userDao.queryForId(111);
                //删除
                userDao.delete(u);

注意事项:查询、更新、删除操作要求实体类标明主键(id)

ORMLite的DAO接口还是可迭代的。可以通过Dao接口遍历一张数据表。示例如下:

for (Account account : accountDao) {
            System.out.println(account.getName());
        }

注意事项:Dao接口的循环迭代要求迭代完全部而不能中途返回(比如for循环中有return语句),否则迭代器不会被关闭从而造成资源泄露

也可以使用显式的迭代器,确保手动关闭迭代器资源,如下:

CloseableIterator<Account> iterator =
                accountDao.closeableIterator();
            try {
                while (iterator.hasNext()) {
                    Account account = iterator.next();
                    System.out.println(account.getName());
                }
            } finally {
                // close it at the end to close underlying SQL statement
                iterator.close();
            }

DAO Enabled 实体

ORMLite允许实体类自身具有类似Dao的功能,通过继承BaseDaoEnabled类实现。
示例:

@DatabaseTable(tableName = "t_test")
    public class User extends BaseDaoEnabled<User, Object> {
        @DatabaseField(id = true)
        private int id;
        @DatabaseField(canBeNull = false)
        private String name;
//      …
    }

CRUD操作如下:

User u=new User();
        u.setDao(userDao);
        u.create();//insert
        u.refresh();//query the new data
        u.update();//update
        u.delete();//delete

ORMLite中数据库与表的创建

ORMLite提供一些工具类用于创建和销毁Schema和table。

TableUtils类:

根据实体类直接创建表
TableUtils.createTable(connectionSource, Account.class);
根据config创建表

        DatabaseFieldConfig dfc=new DatabaseFieldConfig();
        //      dfc.setColumnName("name");
        List<DatabaseFieldConfig> fieldConfigs = Arrays.asList(dfc);
        DatabaseTableConfig<Account> tableConfig =
           new DatabaseTableConfig<Account>(Account.class, fieldConfigs);
        // 创建表
        TableUtils.createTable(connectionSource, tableConfig);

如果没有则创建
TableUtils.createTableIfNotExists(connectionSource, tableConfig);
删除表
TableUtils.dropTable(ConnectionSource, Class, boolean ignoreErrors);

这些创建、删除表的操作对测试非常方便,可以在测试类中创建表、删除表等

ORMLite对原生SQL支持

ORMLite定义的Dao功能并不保证覆盖所有的SQL操作,比如sum、count、avg等函数功能,因而ORMLite提供了对原生SQL的支持。

查询操作示例:

GenericRawResults<String[]> rawResults 
            =accountDao.queryRaw("select count(*) from t_test where id < 10");

还可以使用QueryBuilder构建prepareStatement查询:

QueryBuilder<Account, Integer> qb = accountDao.queryBuilder();
qb.where().gt("orderCount", 10);
GenericRawResults<String[]> results = accountDao.queryRaw(qb.prepareStatementString());

带参数的prepareStatement查询

QueryBuilder<Account, Integer> qb = accountDao.queryBuilder();
qb.where().lt("orderCount", new SelectArg());
GenericRawResults<String[]> results = accountDao.queryRaw(qb.prepareStatementString(), "10");

查询结果自动映射到对象

// 传入映射对象
    GenericRawResults<User> rawResults =
         userDao.queryRaw(
           "select id,name from t_test order by id",
           new RawRowMapper<User>() {
                 public User mapRow(String[] columnNames,
                   String[] resultColumns) {
                    return new User(Integer.parseInt(resultColumns[0]),resultColumns[1]); } });
        // 取出映射结果
        for (User u : rawResults) {
          System.out.println(u);
        }
        rawResults.close();

注意事项:

  • rawResults是可迭代的,迭代全部结果集后会自动关闭,否则结果集最后必须手动关闭;
  • 使用prepareStatement查询时,如果查询字段中没有id字段,则QueryBuilder会自动添加上去,因此查询结果可能会比预想的多一列。

更新示例:(包括Insert,Update,Delete)
userDao.updateRaw("INSERT INTO t_test (id, name) VALUES(111,Lee)");

ORMLite使用QueryBuilder构建高级查询

使用ORMLite的QueryBuilder可以构建类似于原生SQL的自定义查询,而且使用更加方便。

示例1:(where条件查询)

QueryBuilder<Account, Object> queryBuilder =
                  accountDao.queryBuilder();
    Where<Account, Object> where = queryBuilder.where();
    where.eq(Account.NAME_FIELD_NAME, "foo");
    where.and();
    where.eq(Account.PASSWORD_FIELD_NAME, "_secret");
    PreparedQuery<Account> preparedQuery = queryBuilder.prepare();
 ```

上述符合查询相当于如下SQL: 

`SELECT * FROM account  WHERE (name = 'foo' AND password = '_secret')`

示例2:复杂查询

```java
Where<Account, Object> where = queryBuilder.where();
            where.or(
              where.and(
                where.eq(Account.NAME_FIELD_NAME, "foo"),
                where.eq(Account.PASSWORD_FIELD_NAME, "_secret")),
              where.and(
                where.eq(Account.NAME_FIELD_NAME, "bar"),
                where.eq(Account.PASSWORD_FIELD_NAME, "qwerty"))
              );




<div class="se-preview-section-delimiter"></div>

相当于如下SQL:

SELECT * FROM account WHERE ((name = 'foo' AND password = '_secret') OR (name = 'bar' AND password = 'qwerty'))

ORMLite进行联合查询

ORMLite支持Join联合查询,示例如下

QueryBuilder<User, Object> userQb = userDao.queryBuilder();
userQb.where().ge("id", 10);
QueryBuilder<Account, Object> accountQb = accountDao.queryBuilder();
// join with the order query
List<Account> results = accountQb.join(userQb).query();




<div class="se-preview-section-delimiter"></div>

注意事项:ORMLite仅支持内连接与左连接,不支持右连接与全连接

ORMLite在Spring中的配置

ORMLite支持Spring容器中使用

下面的示例片段是Spring对ORMLite的url,数据源,connectionsource,Dao工厂的配置片段:(完整的配置文件见附录代码)

<!-- database url -->
    <bean id="databaseUrl" class="java.lang.String">
        <constructor-arg index="0" value="jdbc:sqlite:Q:/sqlite3/abc.db" />
    </bean>

    <!--使用dbcp数据源 -->
    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
        destroy-method="close">
        <property name="driverClassName" value="org.sqlite.JDBC" />
        <property name="url" ref="databaseUrl" />
    </bean>

    <!-- ConnectionSource -->
    <bean id="connectionSource" class="com.j256.ormlite.jdbc.DataSourceConnectionSource"
        init-method="initialize">
        <property name="databaseUrl" ref="databaseUrl" />
        <property name="dataSource" ref="dataSource" />
    </bean>

    <!-- accountDao -->
    <bean id="accountDao" class="com.j256.ormlite.spring.DaoFactory" factory-method="createDao">
        <constructor-arg index="0" ref="connectionSource" />
        <constructor-arg index="1" value="com.fiberhome.ormlite.spring.Account" />
    </bean>




<div class="se-preview-section-delimiter"></div>

*注意事项:
1、所有类型ConnectionSource必须配置初始化方法initialize,否则抛异常
2、前文已提到DataSourceConnectionSource无法关闭数据源,因而数据源需要配置destroy-method=”close” 项来关闭数据源*

ORMLite事务支持与批量操作

Sqlite支持事务。使用ORMLite时可用通过ORMLite内置的事务管理器完成事务操作。

事务操作示例代码如下:

TransactionManager.callInTransaction(connectionSource,
                      new Callable<Void>() {
                        public Void call() throws Exception {
                            // insert our order
accountDao.create(account);
                        // now add the account to the order
                            order.setAccount(account);
                            // update our order object
                            orderDao.update(order);
                                // you could pass back an object here
                            return null;
                        }
                    });




<div class="se-preview-section-delimiter"></div>

ORMLite支持批量操作。对于大量的插入、修改等操作来说,调用批量操作接口可用提高数据库的性能。
示例代码如下:

accountDao.callBatchTasks(new Callable<Void>() {
                public Void call() throws Exception {
                    for (Account account : accountsToInsert) {
                        accountDao.create(account);
                    }
                }
            });

*注意事项:
1、从源码层面看,事务与批量操作的实现十分相似,都是首先setAutoCommit(false),然后执行一系列操作,最后在连接上执行 commit()方法,不同的是如果发生异常,事务会回滚而批量操作不会回滚。
2、事物内部通过调用connectionSource的getReadWriteConnection() 方法获取一个数据库连接,然后在该数据库连接上进行事务操作。connectionSource内部通过一个ThreadLocal变量保证同一个线程获取到的数据库连接是同一个连接,我们也可以手动的获取连接配置提交事务,但最后要记得释放连接到连接池中。*

“`

注意事项:

  • ORMLite仅支持内连接与左连接,不支持右连接与全连接

ORMLite在Spring中的配置

ORMLite支持Spring容器中使用

下面的示例片段是Spring对ORMLite的url,数据源,connectionsource,Dao工厂的配置片段:(完整的配置文件见附录代码)

“`xml



<!--使用dbcp数据源 -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
    destroy-method="close">
    <property name="driverClassName" value="org.sqlite.JDBC" />
    <property name="url" ref="databaseUrl" />
</bean>

<!-- ConnectionSource -->
<bean id="connectionSource" class="com.j256.ormlite.jdbc.DataSourceConnectionSource"
    init-method="initialize">
    <property name="databaseUrl" ref="databaseUrl" />
    <property name="dataSource" ref="dataSource" />
</bean>

<!-- accountDao -->
<bean id="accountDao" class="com.j256.ormlite.spring.DaoFactory" factory-method="createDao">
    <constructor-arg index="0" ref="connectionSource" />
    <constructor-arg index="1" value="com.fiberhome.ormlite.spring.Account" />
</bean>

“`

注意事项:

  • 所有类型ConnectionSource必须配置初始化方法initialize,否则抛异常
  • 前文已提到DataSourceConnectionSource无法关闭数据源,因而数据源需要配置destroy-method=”close” 项来关闭数据源

ORMLite事务支持与批量操作

Sqlite支持事务。使用ORMLite时可用通过ORMLite内置的事务管理器完成事务操作。

事务操作示例代码如下:

“`java
TransactionManager.callInTransaction(connectionSource,
new Callable() {
public Void call() throws Exception {
// insert our order
accountDao.create(account);
// now add the account to the order
order.setAccount(account);
// update our order object
orderDao.update(order);
// you could pass back an object here
return null;
}
});


ORMLite支持批量操作。对于大量的插入、修改等操作来说,调用批量操作接口可用提高数据库的性能。
示例代码如下:

```java
accountDao.callBatchTasks(new Callable<Void>() {
                public Void call() throws Exception {
                    for (Account account : accountsToInsert) {
                        accountDao.create(account);
                    }
                }
            });

注意事项:

  • 从源码层面看,事务与批量操作的实现十分相似,都是首先setAutoCommit(false),然后执行一系列操作,最后在连接上执行 commit()方法,不同的是如果发生异常,事务会回滚而批量操作不会回滚。
  • 事物内部通过调用connectionSource的getReadWriteConnection() 方法获取一个数据库连接,然后在该数据库连接上进行事务操作。connectionSource内部通过一个ThreadLocal变量保证同一个线程获取到的数据库连接是同一个连接,我们也可以手动的获取连接配置提交事务,但最后要记得释放连接到连接池中。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值