ORMLite使用示例
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 {@Idprivate 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示例:
//构造JavaBeanUser 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 statementiterator.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();//insertu.refresh();//query the new datau.update();//updateu.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 orderorder.setAccount(account);// update our order objectorderDao.update(order);// you could pass back an object herereturn 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变量保证同一个线程获取到的数据库连接是同一个连接,我们也可以手动的获取连接配置提交事务,但最后要记得释放连接到连接池中。
ORMLite使用示例相关推荐
- ormlite android studio,OrmLite-android入门体验
入门体验 OrmLite 是一个轻量级的ORM(Object Relational Mapping)数据库工具,方便持久化java对象到数据库 1. 使用准备 使用androidADT创建androi ...
- Ormlite的工具使用
配置 compile 'com.j256.ormlite:ormlite-android:5.0' 使用 常用注解 @DatabaseTable(tableName = "t_user&qu ...
- ormlite 笔记
添加依赖: compile 'com.j256.ormlite:ormlite-android:5.0' 使用 常用注解: @DatabaseTable(tableName = "t_use ...
- .net连接mysql数据_.net连接MYSQL数据库的方法及示例!
连接MYSQL数据库的方法及示例 方法一: 使用MYSQL推出的MySQL Connector/Net is an ADO.NET driver for MySQL 该组件为MYSQL为ADO.NET ...
- CPU Cache原理与示例
CPU Cache原理与示例 基础知识 现在的 CPU 多核技术,都会有几级缓存,老的 CPU 会有两级内存(L1 和 L2),新的CPU会有三级内存(L1,L2,L3 ),如下图所示: 其中: ...
- 编译器 llvm clang 源码转换示例
编译器 llvm clang 源码转换示例 从git获取llvm项目的源码方式: git clone https://github.com/llvm/llvm-project.git 下载源码后,进入 ...
- Cache Memory技术示例
Cache Memory技术示例 为什么需要cache?如何判断一个数据在cache中是否命中?cache的种类有哪些,区别是什么? 为什么需要cache memory 先思考第一个问题:程序是如何运 ...
- Swift与LLVM-Clang原理与示例
Swift与LLVM-Clang原理与示例 LLVM 学习 从 简单汇编基础 到 Swift 不简单的 a + 1 作为iOS开发,程序崩溃犹如家常便饭,秉着没有崩溃也要制造崩溃的原则 每天都吃的很饱 ...
- C语言与OpenCL的编程示例比较
C语言与OpenCL的编程示例比较 OpenCL支持数据并行,任务并行编程,同时支持两种模式的混合.对于同步 OpenCL支持同一工作组内工作项的同步和命令队列中处于同一个上下文中的 命令的同步. 在 ...
最新文章
- 在Mybatis3开发中与配置相关的7点体会
- controller层没反应_埋地管道防腐层探测检漏仪FJ-10地下管线探测仪的说明及应用...
- LazyT 提供对延迟初始化的支持
- 国科大高级人工智能7-命题逻辑
- 每日笔记---使用@ConfigurationProperties读取yml配置
- DockerFile最佳实践:
- MacBook Pro 用户学会这 5 个小技巧,让你的 Touch Bar 更好用
- 仙人掌之歌——权力的游戏(1)
- 电子合同助力企业实现全程无纸化闭环
- Systrace 学习笔记
- Vue解决跨域问题之Node反向代理
- EMQ优特云-贵阳娃哈哈生产基地物联网能耗监控项目回顾与展望
- C#实例.net_经典例子400个
- 十年前你绝对没有看懂的《大话西游》.
- 电脑有网但打不开网页怎么办?
- storm 2.2.1 java + idea实现wordcount
- 热敏电阻的选型参数含义解读
- 华为完成首个5G测试;央行搭建区块链平台;苹果将于今夜凌晨举行发布会;蔚来汽车明日在美上市; | 雷锋网9月12日消息...
- 4月热搜:揭秘金融级人脸实名认证解决方案背后的技术硬货
- Google的Logo颜色参数