1. 概述
ORMLite 是一款专为 Java 应用设计的轻量级 ORM 库。它提供了主流 ORM 工具的核心功能,却避免了其他 ORM 框架常见的复杂性和性能开销。
主要特性包括:
- ✅ 通过 Java 注解定义实体类
- ✅ 可扩展的 DAO(数据访问对象)类
- ✅ QueryBuilder 类用于构建复杂查询
- ✅ 自动生成数据库表创建/删除语句
- ✅ 支持事务操作
- ✅ 支持实体关系映射
接下来我们将逐步探索如何配置库、定义实体类以及执行数据库操作。
2. Maven 依赖
要使用 ORMLite,需在 pom.xml
中添加 ormlite-jdbc
依赖:
<dependency>
<groupId>com.j256.ormlite</groupId>
<artifactId>ormlite-jdbc</artifactId>
<version>6.1</version>
</dependency>
⚠️ 该依赖会自动引入 H2 内存数据库。若需使用其他数据库(如 MySQL/PostgreSQL),需额外添加对应 JDBC 驱动。
3. 定义实体类
使用 ORMLite 定义持久化实体时,主要用到两个注解:
@DatabaseTable
:标记实体类@DatabaseField
:标记持久化字段
下面定义一个 Library
实体,包含 name
字段和自增主键 libraryId
:
@DatabaseTable(tableName = "libraries")
public class Library {
@DatabaseField(generatedId = true)
private long libraryId;
@DatabaseField(canBeNull = false)
private String name;
public Library() {
}
// 标准getter/setter
}
关键点说明:
@DatabaseTable
的tableName
属性可自定义表名(默认使用类名)- 每个需持久化的字段必须添加
@DatabaseField
- 主键可通过
id
/generatedId
/generatedSequence
标记,generatedId=true
实现自增 - ⚠️ 实体类必须包含至少包级可见的无参构造器
其他常用字段属性:columnName
(列名)、dataType
(数据类型)、defaultValue
(默认值)、canBeNull
(是否可空)、unique
(唯一约束)。
3.1. 使用 JPA 注解
除 ORMLite 特有注解外,也支持标准 JPA 注解定义实体。等价的 JPA 版本 Library
:
@Entity
public class LibraryJPA {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long libraryId;
@Column
private String name;
// 标准getter/setter
}
⚠️ 使用 JPA 注解需额外添加 javax.persistence-api
依赖。支持注解包括:@Entity
、@Id
、@Column
、@GeneratedValue
、@OneToOne
、@ManyToOne
、@JoinColumn
、@Version
。
4. ConnectionSource 配置
操作实体前,**必须配置 ConnectionSource
**。推荐使用连接池实现:
JdbcPooledConnectionSource connectionSource
= new JdbcPooledConnectionSource("jdbc:h2:mem:myDb");
// 使用connectionSource执行操作
connectionSource.close();
对于生产环境,建议通过 DataSourceConnectionSource
包装高性能数据源(如 Druid/HikariCP)。
5. TableUtils 工具类
基于 ConnectionSource
,使用 TableUtils
静态方法管理数据库结构:
createTable()
- 根据实体类创建表createTableIfNotExists()
- 表不存在时创建(需数据库支持)dropTable()
- 删除表clearTable()
- 清空表数据
创建 Library
表的示例:
TableUtils.createTableIfNotExists(connectionSource, Library.class);
6. DAO 对象操作
ORMLite 通过 DaoManager
创建具备 CRUD 功能的 DAO 对象:
Dao<Library, Long> libraryDao
= DaoManager.createDao(connectionSource, Library.class);
💡 DaoManager
会缓存 DAO 实例,避免重复创建。
基础 CRUD 操作示例:
Library library = new Library();
library.setName("My Library");
libraryDao.create(library); // 创建
Library result = libraryDao.queryForId(1L); // 查询
library.setName("My Other Library");
libraryDao.update(library); // 更新
libraryDao.delete(library); // 删除
遍历所有记录:
libraryDao.forEach(lib -> {
System.out.println(lib.getName());
});
⚠️ 直接使用 forEach()
存在资源泄漏风险!推荐使用 try-with-resources
:
try (CloseableWrappedIterable<Library> wrappedIterable
= libraryDao.getWrappedIterable()) {
wrappedIterable.forEach(lib -> {
System.out.println(lib.getName());
});
}
6.1. 自定义 DAO 类
扩展 DAO 功能时,先创建接口:
public interface LibraryDao extends Dao<Library, Long> {
public List<Library> findByName(String name) throws SQLException;
}
再实现类(需继承 BaseDaoImpl
):
public class LibraryDaoImpl extends BaseDaoImpl<Library, Long>
implements LibraryDao {
public LibraryDaoImpl(ConnectionSource connectionSource) throws SQLException {
super(connectionSource, Library.class);
}
@Override
public List<Library> findByName(String name) throws SQLException {
return super.queryForEq("name", name);
}
}
⚠️ 必须保留此构造器形式。
最后在实体类中指定自定义 DAO:
@DatabaseTable(tableName = "libraries", daoClass = LibraryDaoImpl.class)
public class Library {
// ...
}
使用自定义 DAO:
LibraryDao customLibraryDao
= DaoManager.createDao(connectionSource, Library.class);
// 调用标准方法 + 自定义方法
Library library = new Library();
library.setName("My Library");
customLibraryDao.create(library);
assertEquals(
1, customLibraryDao.findByName("My Library").size());
7. 定义实体关系
ORMLite 通过 "foreign" 对象/集合实现实体关系映射。
7.1. 外键对象字段
使用 foreign=true
定义单向一对一关系。先创建 Address
实体:
@DatabaseTable(tableName="addresses")
public class Address {
@DatabaseField(generatedId = true)
private long addressId;
@DatabaseField(canBeNull = false)
private String addressLine;
// 标准getter/setter
}
在 Library
中添加外键字段:
@DatabaseTable(tableName = "libraries")
public class Library {
//...
@DatabaseField(foreign=true, foreignAutoCreate = true,
foreignAutoRefresh = true)
private Address address;
// 标准getter/setter
}
关键属性说明:
foreignAutoCreate=true
:保存Library
时自动保存未持久化的Address
foreignAutoRefresh=true
:查询Library
时自动加载关联的Address
操作示例:
Library library = new Library();
library.setName("My Library");
library.setAddress(new Address("Main Street nr 20"));
Dao<Library, Long> libraryDao
= DaoManager.createDao(connectionSource, Library.class);
libraryDao.create(library); // 同时保存Address
// 验证Address已保存
Dao<Address, Long> addressDao
= DaoManager.createDao(connectionSource, Address.class);
assertEquals(1,
addressDao.queryForEq("addressLine", "Main Street nr 20")
.size());
7.2. 外键集合
使用 @ForeignCollectionField
定义一对多关系。在 Library
中添加:
@DatabaseTable(tableName = "libraries")
public class Library {
// ...
@ForeignCollectionField(eager=false)
private ForeignCollection<Book> books;
// 标准getter/setter
}
在 Book
中添加反向引用:
@DatabaseTable
public class Book {
// ...
@DatabaseField(foreign = true, foreignAutoRefresh = true)
private Library library;
// 标准getter/setter
}
ForeignCollection
提供 add()
/remove()
方法:
Library library = new Library();
library.setName("My Library");
libraryDao.create(library);
libraryDao.refresh(library); // 懒加载必须refresh
library.getBooks().add(new Book("1984")); // 自动持久化Book
⚠️ **懒加载集合(eager=false
)使用前必须调用 refresh()
**!
也可通过 Book
端建立关系:
Book book = new Book("It");
book.setLibrary(library);
bookDao.create(book);
验证关联数据:
assertEquals(2, bookDao.queryForEq("library_id", library).size());
(library_id
是默认外键列名)
8. QueryBuilder 查询构建器
每个 DAO 可获取 QueryBuilder
构建复杂查询,支持方法:
selectColumns()
- 指定查询列where()
- 条件过滤groupBy()
- 分组having()
- 分组过滤countOf()
- 计数distinct()
- 去重orderBy()
- 排序join()
- 关联查询
示例:查询拥有超过 1 本书的图书馆:
List<Library> libraries = libraryDao.queryBuilder()
.where()
.in("libraryId", bookDao.queryBuilder()
.selectColumns("library_id")
.groupBy("library_id")
.having("count(*) > 1"))
.query();
9. 总结
本文系统介绍了 ORMLite 的核心功能:
- 实体定义(原生/JPA 注解)
- 数据库连接管理
- 表结构操作
- DAO 基础/高级用法
- 实体关系映射
- 复杂查询构建
作为轻量级 ORM 方案,ORMLite 在中小型项目中表现优异,尤其适合需要快速开发且对性能敏感的场景。完整示例代码可参考 GitHub 仓库。