mirror of
https://gitee.com/mybatis-flex/mybatis-flex.git
synced 2025-12-07 00:58:24 +08:00
204 lines
5.9 KiB
Markdown
204 lines
5.9 KiB
Markdown
# Db + Row 工具的使用
|
||
|
||
Db + Row 工具类,提供了在 Entity 实体类之外的数据库操作能力。使用 Db + Row 时,无需对数据库表进行映射, Row 是一个 HashMap 的子类,相当于一个通用的 Entity。以下为 Db + Row 的一些示例:
|
||
|
||
|
||
```java
|
||
//使用原生 SQL 插入数据
|
||
String sql = "insert into tb_account(id,name) value (?, ?)";
|
||
Db.insertBySql(sql,1,"michael");
|
||
|
||
//使用 Row 插入数据
|
||
Row account = new Row();
|
||
account.set("id",100);
|
||
account.set(ACCOUNT.USER_NAME,"Michael");
|
||
Db.insert("tb_account",account);
|
||
|
||
|
||
//根据主键查询数据
|
||
Row row = Db.selectOneById("tb_account","id",1);
|
||
|
||
//Row 可以直接转换为 Entity 实体类,且性能极高
|
||
Account account = row.toEntity(Account.class);
|
||
|
||
|
||
//查询所有大于 18 岁的用户
|
||
String listsql = "select * from tb_account where age > ?"
|
||
List<Row> rows = Db.selectListBySql(sql,18);
|
||
|
||
|
||
//分页查询:每页 10 条数据,查询第 3 页的年龄大于 18 的用户
|
||
QueryWrapper query = QueryWrapper.create()
|
||
.where(ACCOUNT.AGE.ge(18));
|
||
Page<Row> rowPage = Db.paginate("tb_account",3,10,query);
|
||
```
|
||
|
||
> Db 工具类还提供了更多 增、删、改、查和分页查询等方法。
|
||
>
|
||
> 具体参考: [Db.java](./mybatis-flex-core/src/main/java/com/mybatisflex/core/row/Db.java) 。
|
||
|
||
## Row.toEntity()
|
||
|
||
`Row.toEntity(Entity.class)` 方法主要是用于可以把 Row 转换为 entity 实体类。通过这个方法,可以把 Entity 里的
|
||
`@Column()` 配置的列名和 Row 里的 key 进行自动关联。
|
||
|
||
代码示例:
|
||
|
||
```java
|
||
Row row = Db.selectOneBySql("select * from ....");
|
||
Account entity = row.toEntity(Account.class);
|
||
```
|
||
|
||
需要注意的是,当我们进行 join 关联查询时,返回的结果如果出现重复字段,Row 会自动添加上 字段序号。
|
||
|
||
例如:
|
||
|
||
```sql
|
||
CREATE TABLE IF NOT EXISTS `tb_account`
|
||
(
|
||
`id` INTEGER PRIMARY KEY auto_increment,
|
||
`user_name` VARCHAR(100),
|
||
`age` Integer,
|
||
`is_delete` Integer
|
||
);
|
||
|
||
|
||
CREATE TABLE IF NOT EXISTS `tb_article`
|
||
(
|
||
`id` INTEGER PRIMARY KEY auto_increment,
|
||
`account_id` Integer,
|
||
`title` VARCHAR(100),
|
||
`content` text,
|
||
`is_delete` Integer
|
||
);
|
||
|
||
INSERT INTO tb_account
|
||
VALUES (1, '张三' ,18, 0),
|
||
(2, '王麻子叔叔' ,19, 0);
|
||
|
||
|
||
INSERT INTO tb_article
|
||
VALUES (1, 1,'标题1', '内容1',0),
|
||
(2, 2,'标题2', '内容2',0);
|
||
```
|
||
在以上的数据中,我们通过如下的 left join 查询文章和用户表:
|
||
|
||
```java
|
||
QueryWrapper query = new QueryWrapper();
|
||
query.select().from(ACCOUNT).leftJoin(ARTICLE)
|
||
.on(ACCOUNT.ID.eq(ARTICLE.ACCOUNT_ID));
|
||
|
||
List<Row> rows = Db.selectListByQuery(query);
|
||
```
|
||
|
||
返回的 Row 集合如下:
|
||
```
|
||
|ID |USER_NAME |AGE |IS_DELETE |ID$1 |ACCOUNT_ID |TITLE |CONTENT |IS_DELETE$1 |
|
||
|1 |张三 |18 |0 |1 |1 |标题1 |内容1 |0 |
|
||
|2 |王麻子叔叔 |19 |0 |2 |2 |标题2 |内容2 |0 |
|
||
```
|
||
|
||
前面 4 列属于 `Account` 的数据,后面 5 列属于 `Article` 的数据。在后面的 `Article` 表中,有 `id`、`is_delete` 和 Account 的表的列名重复。
|
||
此时,重复的列名会自动添加上 `$序号` ,而非数据库返回的真正列名。
|
||
|
||
因此,我们进行 toEntity 数据转换的时候,需要添加上序号,例如:
|
||
|
||
```java
|
||
List<Account> accounts = RowUtil.toEntityList(rows, Account.class);
|
||
System.out.println(accounts);
|
||
|
||
//添加上序号 1
|
||
List<Article> articles = RowUtil.toEntityList(rows, Article.class, 1);
|
||
System.out.println(articles);
|
||
```
|
||
|
||
|
||
|
||
## Row.toObject()
|
||
|
||
`Row.toObject(Other.class)` 和 `Row.toEntity(Entity.class)` 和相似。不一样的地方在于 `Row.toObject(Other.class)` 是通过去查找
|
||
`Other.class` 的 `setter` 方法去匹配 Row 的 key 进行赋值的。
|
||
|
||
例如 `Other.class` 的代码如下:
|
||
|
||
```java
|
||
public class Other {
|
||
private String id;
|
||
private String userName;
|
||
|
||
//getter setter
|
||
}
|
||
```
|
||
|
||
那么,当我们去通过 SQL 查询得到 Row 的时候,Row 里的 `key` 为 `userName`、`UserName`、`USERNAME`、`user_name`、`USER_NAME` 等
|
||
都能自动适配到 `Other.userName` 属性。这个方法常用于把 Row 直接转换为 VO 的场景。
|
||
|
||
> PS:我们可以通过调用 `RowUtil.registerMapping(clazz, columnSetterMapping)` 去让更多的 `字段` 名称和 `属性` 进行匹配。
|
||
|
||
|
||
代码示例:
|
||
|
||
```java
|
||
Row row = Db.selectOneBySql("select * from ....");
|
||
Other other = row.toObject(Other.class);
|
||
```
|
||
|
||
在以上代码中,如果出现了 `left join` 等情况下,需要添加上序号。
|
||
|
||
## Row 字段转化为驼峰风格
|
||
|
||
```java
|
||
Row row = Db..selectOneBySql("select * from ....");
|
||
Map result = row.toCamelKeysMap();
|
||
```
|
||
|
||
## Row 字段转换为下划线风格
|
||
|
||
```java
|
||
Row row = Db..selectOneBySql("select * from ....");
|
||
Map result = row.toUnderlineKeysMap();
|
||
```
|
||
|
||
## Row 插入时,设置主键生成方式
|
||
|
||
**ID 自增**
|
||
|
||
```java
|
||
// ID 自增
|
||
Row row = Row.ofKey(RowKey.ID_AUTO);
|
||
row.set(ACCOUNT.USER_NAME,"Michael");
|
||
|
||
Db.insert("tb_account",row);
|
||
```
|
||
|
||
**ID 为 UUID**
|
||
|
||
```java
|
||
// ID 为 uuid
|
||
Row row = Row.ofKey(RowKey.ID_UUID);
|
||
row.set(ACCOUNT.USER_NAME,"Michael");
|
||
|
||
Db.insert("tb_account",row);
|
||
```
|
||
**自定义 Row 主键生成方式**
|
||
|
||
```java
|
||
// 自定义 Row Key,整个应用定义一个常量即可
|
||
RowKey myRowKey = RowKey.of("id", KeyType.Generator, "uuid", true);
|
||
|
||
// 使用自定义的 RowKey
|
||
Row row = Row.ofKey(myRowKey);
|
||
row.set(ACCOUNT.USER_NAME,"Michael");
|
||
|
||
Db.insert("tb_account",row);
|
||
```
|
||
|
||
## RowUtil 工具类
|
||
|
||
`RowUtil` 工具类是用于帮助用户快速的把 `Row` 或者 `List<Row>` 转换为 VO 的工具类。其提供的方法如下:
|
||
|
||
- `RowUtil.toObject(row, objectClass)`
|
||
- `RowUtil.toObjectList(rows, objectClass)`
|
||
- `RowUtil.toEntity(row, entityClass)`
|
||
- `RowUtil.toEntityList(rows, entityClass)`
|
||
- `RowUtil.registerMapping(clazz, columnSetterMapping)` 用于注册数据库 `字段` 名称和 Class 属性的映射关系。 |