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
}

关键点说明:

  • @DatabaseTabletableName 属性可自定义表名(默认使用类名)
  • 每个需持久化的字段必须添加 @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 仓库


原始标题:Introduction to ORMLite | Baeldung

« 上一篇: Deeplearning4j 指南