overview

Origin

Hutool-db is a database operation tool class based on JDBC. It operates the database by wrapping and using the ActiveRecord concept. In Hutool-db, Entity (essentially a Map) is used instead of Bean to make database operations more flexible, while providing conversion between Bean and Entity to support traditional ORM compatibility.

Overall Architecture

The overall architecture is divided into several parts:

  1. Data Source DataSource
  2. SQL Executor SqlExecutor
  3. CRUD Encapsulation Db, SqlConnRunner, SqlRunner
  4. Transactional CRUD Encapsulation Session
  5. Various Result Set Handling Classes handler
  6. Database Utility Methods Summary DbUtil

In addition, there is the dialect (database dialect) that is not listed. I will automatically identify the database based on the given DataSource, Connection, and other objects, and then construct SQL statements using different dialects. The currently supported databases are MySQL, Oracle, and SqlLite3. If the identification fails, ANSI SQL will be used so that most methods can be handled even for unsupported databases.

Let me explain:

CRUD Encapsulation Db, SqlConnRunner, SqlRunner

These two classes are somewhat similar as they both encapsulate methods for adding, deleting, modifying, querying, paginating, and counting. The difference is that SqlConnRunner requires a Connection object to be passed for each method, while SqlRunner inherits from SqlConnRunner and automatically obtains the Connection object when passing a DataSource.

Various Result Set Handling Classes handler

This package contains an interface called RsHandler that takes a ResultSet object and specifies what to return in the handle method. The implemented classes are:

  1. EntityListHandler converts the result set into a list of Entities.
  2. NumberHandler is used when executing statements like “select count(1)” or when the result set contains only one numerical result.
  3. EntityHandler is used when returning a single record.

Database Utility Methods Summary DbUtil

Provides some utility methods. The most commonly used one is the close method. Since JDK7 implemented the Closeable interface for ResultSet, Statement, PreparedStatement, and Connection, it was necessary to check the type and close them individually before. The close method can now close multiple objects.

Object Explanation

1. Entity

In ORM, I map a row of data in a table to a class called Entity, which inherits from HashMap. The key is the field name, and the value is an Object type representing the field value. An Entity object represents a record in a database table. It also contains a field for the table name to facilitate subsequent operations. Most of the objects used for database CRUD operations are of this type.

This object serves two roles. One is as a data carrier, representing a piece of data. The other is as a WHERE statement condition. When acting as a WHERE condition, the key is still the field name, and the value is the field condition value. For example:

Entity where = Entity.create(TABLE_NAME).set("条件1", "条件值");

The resulting WHERE statement is:

WHERE `条件1` = 条件值

PreparedStatement will be used to prevent SQL injection.

2. Table Column

These two objects mainly describe the database table structure and are currently not related to the ORM itself. They are used to obtain table structure information when needed:

// Get the table names of all tables in the current database
List<String> tableNames = MetaUtil.getTables(dataSource);
Log.info("{}", tableNames);

/*
 * Obtain table structure information. The table structure is encapsulated in a Table object, which contains Column objects representing each column. The Column object contains information such as column name, type, size, and whether it allows null values.
 */
Table table = MetaUtil.getTableMeta(dataSource, TABLE_NAME);
Log.info("{}", table);