mirror of
https://gitee.com/mybatis-flex/mybatis-flex.git
synced 2025-12-07 00:58:24 +08:00
commit
1da9aed0cd
@ -63,6 +63,7 @@ export default defineConfig({
|
|||||||
{text: 'QueryWrapper', link: '/zh/base/querywrapper'},
|
{text: 'QueryWrapper', link: '/zh/base/querywrapper'},
|
||||||
{text: 'QueryWrapperChain', link: '/zh/base/query-wrapper-chain'},
|
{text: 'QueryWrapperChain', link: '/zh/base/query-wrapper-chain'},
|
||||||
{text: 'Db + Row', link: '/zh/base/db-row'},
|
{text: 'Db + Row', link: '/zh/base/db-row'},
|
||||||
|
{text: 'Active Record', link: '/zh/base/active-record'},
|
||||||
{text: 'IService', link: '/zh/base/service'},
|
{text: 'IService', link: '/zh/base/service'},
|
||||||
{text: 'SpringBoot 配置文件', link: '/zh/base/configuration'},
|
{text: 'SpringBoot 配置文件', link: '/zh/base/configuration'},
|
||||||
{text: 'MyBatisFlexCustomizer', link: '/zh/base/mybatis-flex-customizer'},
|
{text: 'MyBatisFlexCustomizer', link: '/zh/base/mybatis-flex-customizer'},
|
||||||
|
|||||||
141
docs/zh/base/active-record.md
Normal file
141
docs/zh/base/active-record.md
Normal file
@ -0,0 +1,141 @@
|
|||||||
|
# Active Record
|
||||||
|
|
||||||
|
[Active Record 模式](http://www.martinfowler.com/eaaCatalog/activeRecord.html)出自 Martin Fowler
|
||||||
|
写的《[企业应用架构模式](https://book.douban.com/subject/4826290/)》书中。在 Active Record
|
||||||
|
模式中,对象中既有持久存储的数据,也有针对数据的操作。Active Record 模式把数据存取逻辑作为对象的一部分,处理对象的用户知道如何把数据写入数据库,还知道如何从数据库中读出数据。
|
||||||
|
|
||||||
|
在 MyBatis-Flex 中实现 Active Record
|
||||||
|
功能十分简单,只需继承 [Model](https://gitee.com/mybatis-flex/mybatis-flex/blob/main/mybatis-flex-core/src/main/java/com/mybatisflex/core/activerecord/Model.java)
|
||||||
|
即可。
|
||||||
|
|
||||||
|
::: tip 注意事项
|
||||||
|
|
||||||
|
- 使用 Active Record 功能时,项目中必须注入对应实体类的 BaseMapper 对象!
|
||||||
|
- 如果不想手动创建 Mapper 接口,可以使用 [APT](../others/apt.md#配置文件和选项) 辅助生成。
|
||||||
|
:::
|
||||||
|
|
||||||
|
## 使用示例
|
||||||
|
|
||||||
|
在以下示例当中,使用了 [Lombok](https://www.projectlombok.org/) 对实体类进行了增强,以便我们全链式调用:
|
||||||
|
|
||||||
|
1. `@Table` 标记了实体类对应的数据表。
|
||||||
|
2. `@Data` 为我们生成了 setter/getter、toString、equals、hashCode 等方法,
|
||||||
|
其中 `staticConstructor = "create"` 为我们创建了一个 `create()` 静态方法用于链式调用。
|
||||||
|
3. `@Accessors(chain = true)` 为我们开启了 `return this;` 这样既可以被序列化,又可以链式调用。
|
||||||
|
|
||||||
|
```java
|
||||||
|
|
||||||
|
@Table("tb_account")
|
||||||
|
@Accessors(chain = true)
|
||||||
|
@Data(staticConstructor = "create")
|
||||||
|
public class Account extends Model<Account> {
|
||||||
|
|
||||||
|
@Id(keyType = KeyType.Auto)
|
||||||
|
private Long id;
|
||||||
|
private String userName;
|
||||||
|
private Integer age;
|
||||||
|
private Date birthday;
|
||||||
|
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
这样我们就可以流畅的使用 Active Record 功能了:
|
||||||
|
|
||||||
|
```java
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/account")
|
||||||
|
public class AccountController {
|
||||||
|
|
||||||
|
@PostMapping("save")
|
||||||
|
public boolean save(@RequestBody Account account) {
|
||||||
|
return account.save();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 保存数据
|
||||||
|
|
||||||
|
`Model` 提供了 `save` 方法来保存数据,调用该方法前需要将保存数据填充:
|
||||||
|
|
||||||
|
```java
|
||||||
|
Account.create()
|
||||||
|
.setUserName("张三")
|
||||||
|
.setAge(18)
|
||||||
|
.setBirthday(new Date())
|
||||||
|
.save();
|
||||||
|
```
|
||||||
|
|
||||||
|
## 删除数据
|
||||||
|
|
||||||
|
`Model` 提供了 `remove` 方法来删除数据:
|
||||||
|
|
||||||
|
- 根据主键删除
|
||||||
|
|
||||||
|
```java
|
||||||
|
Account.create()
|
||||||
|
.setId(1L)
|
||||||
|
.removeById();
|
||||||
|
```
|
||||||
|
|
||||||
|
- 根据条件删除
|
||||||
|
|
||||||
|
```java
|
||||||
|
Account.create()
|
||||||
|
.where(Account::getId).eq(1L)
|
||||||
|
.remove();
|
||||||
|
```
|
||||||
|
|
||||||
|
## 更新数据
|
||||||
|
|
||||||
|
`Model` 提供了 `update` 方法来更新数据,调用该方法前需要将更新数据填充:
|
||||||
|
|
||||||
|
- 根据主键更新
|
||||||
|
|
||||||
|
```java
|
||||||
|
Account.create()
|
||||||
|
.setId(1L)
|
||||||
|
.setAge(100)
|
||||||
|
.updateById();
|
||||||
|
```
|
||||||
|
|
||||||
|
- 根据条件更新
|
||||||
|
|
||||||
|
```java
|
||||||
|
Account.create()
|
||||||
|
.setAge(100)
|
||||||
|
.where(Account::getId).eq(1L)
|
||||||
|
.update();
|
||||||
|
```
|
||||||
|
|
||||||
|
## 查询数据
|
||||||
|
|
||||||
|
### 查询一条数据
|
||||||
|
|
||||||
|
`Model` 提供了 `one` 方法来查询一条数据:
|
||||||
|
|
||||||
|
```java
|
||||||
|
Account.create()
|
||||||
|
.where(Account::getId).eq(1L)
|
||||||
|
.one();
|
||||||
|
```
|
||||||
|
|
||||||
|
### 查询多条数据
|
||||||
|
|
||||||
|
`Model` 提供了 `list` 方法来查询多条数据:
|
||||||
|
|
||||||
|
```java
|
||||||
|
Account.create()
|
||||||
|
.where(Account::getAge).ge(18)
|
||||||
|
.list();
|
||||||
|
```
|
||||||
|
|
||||||
|
### 查询分页数据
|
||||||
|
|
||||||
|
`Model` 提供了 `page` 方法来查询分页数据:
|
||||||
|
|
||||||
|
```java
|
||||||
|
Account.create()
|
||||||
|
.where(Account::getAge).ge(18)
|
||||||
|
.page(Page.of(1,10));
|
||||||
|
```
|
||||||
@ -0,0 +1,150 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2022-2023, Mybatis-Flex (fuhai999@gmail.com).
|
||||||
|
* <p>
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
* <p>
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* <p>
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.mybatisflex.core.activerecord;
|
||||||
|
|
||||||
|
import com.mybatisflex.core.BaseMapper;
|
||||||
|
import com.mybatisflex.core.mybatis.Mappers;
|
||||||
|
import com.mybatisflex.core.table.TableInfo;
|
||||||
|
import com.mybatisflex.core.table.TableInfoFactory;
|
||||||
|
import com.mybatisflex.core.util.SqlUtil;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>使用 {@link BaseMapper} 进行 CRUD 操作的实体类的抽象接口。
|
||||||
|
*
|
||||||
|
* <p>使用接口是为了方便拓展,该接口提供了简单的根据 <b>主键</b> 操作数据的方法,
|
||||||
|
* 实现类可以进行其他方法的扩展。
|
||||||
|
*
|
||||||
|
* @param <T> 实体类类型
|
||||||
|
* @author 王帅
|
||||||
|
* @since 2023-07-23
|
||||||
|
*/
|
||||||
|
@SuppressWarnings({"unused", "unchecked"})
|
||||||
|
public interface MapperModel<T> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取实体类对应的 {@link BaseMapper} 接口。
|
||||||
|
*
|
||||||
|
* @return {@link BaseMapper} 接口
|
||||||
|
*/
|
||||||
|
default BaseMapper<T> baseMapper() {
|
||||||
|
return Mappers.ofEntityClass((Class<T>) getClass());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>获取实体类主键数据。
|
||||||
|
*
|
||||||
|
* <p>可以拓展该方法提高效率,例如:
|
||||||
|
* <pre>{@code
|
||||||
|
* return new Object[]{id};
|
||||||
|
* }</pre>
|
||||||
|
*
|
||||||
|
* @return 主键数据数组
|
||||||
|
*/
|
||||||
|
default Object[] getPkValues() {
|
||||||
|
TableInfo tableInfo = TableInfoFactory.ofEntityClass(getClass());
|
||||||
|
return tableInfo.buildPkSqlArgs(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 保存数据(自动忽略 {@code null} 值)。
|
||||||
|
*
|
||||||
|
* @return {@code true} 保存成功,{@code false} 保存失败
|
||||||
|
*/
|
||||||
|
default boolean save() {
|
||||||
|
return save(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 保存数据,并设置是否忽略 {@code null} 值。
|
||||||
|
*
|
||||||
|
* @param ignoreNulls 是否忽略 {@code null} 值
|
||||||
|
* @return {@code true} 保存成功,{@code false} 保存失败
|
||||||
|
*/
|
||||||
|
default boolean save(boolean ignoreNulls) {
|
||||||
|
return SqlUtil.toBool(baseMapper().insert((T) this, ignoreNulls));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 保存或者更新数据,如果实体类主键没有值,则 <b>保存</b> 数据;如果实体类主键有值,则
|
||||||
|
* <b>更新</b> 数据(全部自动忽略 {@code null} 值)。
|
||||||
|
*
|
||||||
|
* @return {@code true} 保存或更新成功,{@code false} 保存或更新失败
|
||||||
|
*/
|
||||||
|
default boolean saveOrUpdate() {
|
||||||
|
return saveOrUpdate(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 保存或者更新数据,如果实体类主键没有值,则 <b>保存</b> 数据;如果实体类主键有值,则
|
||||||
|
* <b>更新</b> 数据,并设置是否忽略 {@code null} 值。
|
||||||
|
*
|
||||||
|
* @param ignoreNulls 是否忽略 {@code null} 值
|
||||||
|
* @return {@code true} 保存或更新成功,{@code false} 保存或更新失败
|
||||||
|
*/
|
||||||
|
default boolean saveOrUpdate(boolean ignoreNulls) {
|
||||||
|
return SqlUtil.toBool(baseMapper().insertOrUpdate((T) this, ignoreNulls));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据实体类主键删除数据。
|
||||||
|
*
|
||||||
|
* @return {@code true} 删除成功,{@code false} 删除失败
|
||||||
|
*/
|
||||||
|
default boolean removeById() {
|
||||||
|
return SqlUtil.toBool(baseMapper().deleteById(getPkValues()));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据实体类主键更新数据(自动忽略 {@code null} 值)。
|
||||||
|
*
|
||||||
|
* @return {@code true} 更新成功,{@code false} 更新失败
|
||||||
|
*/
|
||||||
|
default boolean updateById() {
|
||||||
|
return updateById(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据实体类主键更新数据,并设置是否忽略 {@code null} 值。
|
||||||
|
*
|
||||||
|
* @param ignoreNulls 是否忽略 {@code null} 值
|
||||||
|
* @return {@code true} 更新成功,{@code false} 更新失败
|
||||||
|
*/
|
||||||
|
default boolean updateById(boolean ignoreNulls) {
|
||||||
|
return SqlUtil.toBool(baseMapper().update((T) this, ignoreNulls));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据实体类主键获取一条数据。
|
||||||
|
*
|
||||||
|
* @return 数据
|
||||||
|
*/
|
||||||
|
default T oneById() {
|
||||||
|
return baseMapper().selectOneById(getPkValues());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据实体类主键获取一条数据,并封装为 {@link Optional} 返回。
|
||||||
|
*
|
||||||
|
* @return 数据
|
||||||
|
*/
|
||||||
|
default Optional<T> oneByIdOpt() {
|
||||||
|
return Optional.ofNullable(oneById());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,121 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2022-2023, Mybatis-Flex (fuhai999@gmail.com).
|
||||||
|
* <p>
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
* <p>
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* <p>
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.mybatisflex.core.activerecord;
|
||||||
|
|
||||||
|
import com.mybatisflex.core.activerecord.query.QueryModel;
|
||||||
|
import com.mybatisflex.core.paginate.Page;
|
||||||
|
import com.mybatisflex.core.util.SqlUtil;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Active Record 模型。
|
||||||
|
*
|
||||||
|
* @param <T> 实体类类型
|
||||||
|
* @author 王帅
|
||||||
|
* @since 2023-07-24
|
||||||
|
*/
|
||||||
|
@SuppressWarnings({"unused", "unchecked"})
|
||||||
|
public abstract class Model<T extends Model<T>>
|
||||||
|
extends QueryModel<T>
|
||||||
|
implements MapperModel<T> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据实体类构建的条件删除数据。
|
||||||
|
*
|
||||||
|
* @return {@code true} 删除成功,{@code false} 删除失败
|
||||||
|
*/
|
||||||
|
public boolean remove() {
|
||||||
|
return SqlUtil.toBool(baseMapper().deleteByQuery(getQueryWrapper()));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据实体类构建的条件更新数据(自动忽略 {@code null} 值)。
|
||||||
|
*
|
||||||
|
* @return {@code true} 更新成功,{@code false} 更新失败
|
||||||
|
*/
|
||||||
|
public boolean update() {
|
||||||
|
return update(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据实体类构建的条件更新数据,并设置是否忽略 {@code null} 值。
|
||||||
|
*
|
||||||
|
* @param ignoreNulls 是否忽略 {@code null} 值
|
||||||
|
* @return {@code true} 更新成功,{@code false} 更新失败
|
||||||
|
*/
|
||||||
|
public boolean update(boolean ignoreNulls) {
|
||||||
|
return SqlUtil.toBool(baseMapper().updateByQuery((T) this, ignoreNulls, getQueryWrapper()));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据实体类构建的条件查询数据数量。
|
||||||
|
*
|
||||||
|
* @return 数据数量
|
||||||
|
*/
|
||||||
|
public long count() {
|
||||||
|
return baseMapper().selectCountByQuery(getQueryWrapper());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据实体类构建的条件判断数据是否存在。
|
||||||
|
*
|
||||||
|
* @return {@code true} 数据存在,{@code false} 数据不存在
|
||||||
|
*/
|
||||||
|
public boolean exists() {
|
||||||
|
return SqlUtil.toBool(count());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据实体类构建的条件获取一条数据。
|
||||||
|
*
|
||||||
|
* @return 数据
|
||||||
|
*/
|
||||||
|
public T one() {
|
||||||
|
return baseMapper().selectOneByQuery(getQueryWrapper().limit(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据实体类构建的条件获取一条数据,并封装为 {@link Optional} 返回。
|
||||||
|
*
|
||||||
|
* @return 数据
|
||||||
|
*/
|
||||||
|
public Optional<T> oneOpt() {
|
||||||
|
return Optional.ofNullable(one());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据实体类构建的条件获取多条数据。
|
||||||
|
*
|
||||||
|
* @return 数据列表
|
||||||
|
*/
|
||||||
|
public List<T> list() {
|
||||||
|
return baseMapper().selectListByQuery(getQueryWrapper());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据实体类构建的条件获取分页数据。
|
||||||
|
*
|
||||||
|
* @param page 分页对象
|
||||||
|
* @return 分页数据
|
||||||
|
*/
|
||||||
|
public Page<T> page(Page<T> page) {
|
||||||
|
return baseMapper().paginate(page, getQueryWrapper());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,20 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2022-2023, Mybatis-Flex (fuhai999@gmail.com).
|
||||||
|
* <p>
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
* <p>
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* <p>
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Active Record 功能。
|
||||||
|
*/
|
||||||
|
package com.mybatisflex.core.activerecord;
|
||||||
@ -0,0 +1,47 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2022-2023, Mybatis-Flex (fuhai999@gmail.com).
|
||||||
|
* <p>
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
* <p>
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* <p>
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package com.mybatisflex.core.activerecord.query;
|
||||||
|
|
||||||
|
|
||||||
|
import com.mybatisflex.core.query.QueryColumn;
|
||||||
|
import com.mybatisflex.core.util.LambdaGetter;
|
||||||
|
import com.mybatisflex.core.util.LambdaUtil;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lambda 排序构建器。
|
||||||
|
*
|
||||||
|
* @author 王帅
|
||||||
|
* @since 2023-07-25
|
||||||
|
*/
|
||||||
|
public class OrderByBuilder<R extends QueryModel<R>> {
|
||||||
|
|
||||||
|
private final R queryModel;
|
||||||
|
private final QueryColumn queryColumn;
|
||||||
|
|
||||||
|
public <T> OrderByBuilder(R queryModel, LambdaGetter<T> getter) {
|
||||||
|
this.queryModel = queryModel;
|
||||||
|
this.queryColumn = LambdaUtil.getQueryColumn(getter);
|
||||||
|
}
|
||||||
|
|
||||||
|
public R asc() {
|
||||||
|
return queryModel.orderBy(queryColumn.asc());
|
||||||
|
}
|
||||||
|
|
||||||
|
public R desc() {
|
||||||
|
return queryModel.orderBy(queryColumn.desc());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,178 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2022-2023, Mybatis-Flex (fuhai999@gmail.com).
|
||||||
|
* <p>
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
* <p>
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* <p>
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.mybatisflex.core.activerecord.query;
|
||||||
|
|
||||||
|
import com.mybatisflex.annotation.Column;
|
||||||
|
import com.mybatisflex.core.query.*;
|
||||||
|
import com.mybatisflex.core.util.LambdaGetter;
|
||||||
|
import com.mybatisflex.core.util.LambdaUtil;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>实体类条件查询构建模型。
|
||||||
|
*
|
||||||
|
* <p>该类内部维护了一个 {@link QueryWrapper} 属性,用来构建查询条件。
|
||||||
|
* 通过实体类属性构建的查询条件都是值等于,该扩展用于非等于值构建,及一些其他方法。
|
||||||
|
* 如果不想通过实体类直接构建查询条件,可以不继承该类。
|
||||||
|
*
|
||||||
|
* @param <T> 实体类类型
|
||||||
|
* @author 王帅
|
||||||
|
* @since 2023-07-24
|
||||||
|
*/
|
||||||
|
@SuppressWarnings({"unused", "unchecked"})
|
||||||
|
public abstract class QueryModel<T extends QueryModel<T>> {
|
||||||
|
|
||||||
|
@Column(ignore = true)
|
||||||
|
private QueryWrapper queryWrapper;
|
||||||
|
|
||||||
|
protected QueryWrapper getQueryWrapper() {
|
||||||
|
if (queryWrapper == null) {
|
||||||
|
queryWrapper = QueryWrapper.create();
|
||||||
|
}
|
||||||
|
return queryWrapper;
|
||||||
|
}
|
||||||
|
|
||||||
|
public T select() {
|
||||||
|
return (T) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public T select(String... columns) {
|
||||||
|
getQueryWrapper().select(columns);
|
||||||
|
return (T) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public T select(QueryColumn... queryColumns) {
|
||||||
|
getQueryWrapper().select(queryColumns);
|
||||||
|
return (T) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public <E> T select(LambdaGetter<E>... columns) {
|
||||||
|
getQueryWrapper().select(columns);
|
||||||
|
return (T) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public T select(QueryColumn[]... queryColumns) {
|
||||||
|
getQueryWrapper().select(queryColumns);
|
||||||
|
return (T) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public T where(QueryCondition queryCondition) {
|
||||||
|
getQueryWrapper().where(queryCondition);
|
||||||
|
return (T) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public T where(String sql) {
|
||||||
|
getQueryWrapper().where(sql);
|
||||||
|
return (T) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public T where(String sql, Object... params) {
|
||||||
|
getQueryWrapper().where(sql, params);
|
||||||
|
return (T) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public <E> WhereBuilder<T> where(LambdaGetter<E> column) {
|
||||||
|
return new WhereBuilder<>((T) this, LambdaUtil.getQueryColumn(column), SqlConnector.AND);
|
||||||
|
}
|
||||||
|
|
||||||
|
public T and(QueryCondition queryCondition) {
|
||||||
|
getQueryWrapper().and(queryCondition);
|
||||||
|
return (T) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public T and(String sql) {
|
||||||
|
getQueryWrapper().and(sql);
|
||||||
|
return (T) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public T and(String sql, Object... params) {
|
||||||
|
getQueryWrapper().and(sql, params);
|
||||||
|
return (T) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public <E> WhereBuilder<T> and(LambdaGetter<E> column) {
|
||||||
|
return new WhereBuilder<>((T) this, LambdaUtil.getQueryColumn(column), SqlConnector.AND);
|
||||||
|
}
|
||||||
|
|
||||||
|
public T or(QueryCondition queryCondition) {
|
||||||
|
getQueryWrapper().or(queryCondition);
|
||||||
|
return (T) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public T or(String sql) {
|
||||||
|
getQueryWrapper().or(sql);
|
||||||
|
return (T) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public T or(String sql, Object... params) {
|
||||||
|
getQueryWrapper().or(sql, params);
|
||||||
|
return (T) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public <E> WhereBuilder<T> or(LambdaGetter<E> column) {
|
||||||
|
return new WhereBuilder<>((T) this, LambdaUtil.getQueryColumn(column), SqlConnector.OR);
|
||||||
|
}
|
||||||
|
|
||||||
|
public T groupBy(String... names) {
|
||||||
|
getQueryWrapper().groupBy(names);
|
||||||
|
return (T) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public T groupBy(QueryColumn... columns) {
|
||||||
|
getQueryWrapper().groupBy(columns);
|
||||||
|
return (T) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public <E> T groupBy(LambdaGetter<E>... columns) {
|
||||||
|
getQueryWrapper().groupBy(columns);
|
||||||
|
return (T) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public T having(QueryCondition queryCondition) {
|
||||||
|
getQueryWrapper().having(queryCondition);
|
||||||
|
return (T) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public T orderBy(QueryOrderBy... orderBys) {
|
||||||
|
getQueryWrapper().orderBy(orderBys);
|
||||||
|
return (T) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public T orderBy(String... orderBys) {
|
||||||
|
getQueryWrapper().orderBy(orderBys);
|
||||||
|
return (T) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public <E> OrderByBuilder<T> orderBy(LambdaGetter<E> column) {
|
||||||
|
return new OrderByBuilder<>((T) this, column);
|
||||||
|
}
|
||||||
|
|
||||||
|
public T limit(Integer rows) {
|
||||||
|
getQueryWrapper().limit(rows);
|
||||||
|
return (T) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public T offset(Integer offset) {
|
||||||
|
getQueryWrapper().offset(offset);
|
||||||
|
return (T) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public T limit(Integer offset, Integer rows) {
|
||||||
|
getQueryWrapper().limit(offset, rows);
|
||||||
|
return (T) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,352 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2022-2023, Mybatis-Flex (fuhai999@gmail.com).
|
||||||
|
* <p>
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
* <p>
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* <p>
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package com.mybatisflex.core.activerecord.query;
|
||||||
|
|
||||||
|
import com.mybatisflex.core.query.CPI;
|
||||||
|
import com.mybatisflex.core.query.QueryColumn;
|
||||||
|
import com.mybatisflex.core.query.SqlConnector;
|
||||||
|
import com.mybatisflex.core.util.LambdaGetter;
|
||||||
|
import com.mybatisflex.core.util.LambdaUtil;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lambda 条件构建器。
|
||||||
|
*
|
||||||
|
* @author 王帅
|
||||||
|
* @since 2023-07-24
|
||||||
|
*/
|
||||||
|
public class WhereBuilder<R extends QueryModel<R>> {
|
||||||
|
|
||||||
|
private final R queryModel;
|
||||||
|
private final QueryColumn queryColumn;
|
||||||
|
private final SqlConnector connector;
|
||||||
|
|
||||||
|
public WhereBuilder(R queryModel, QueryColumn queryColumn, SqlConnector connector) {
|
||||||
|
this.queryModel = queryModel;
|
||||||
|
this.queryColumn = queryColumn;
|
||||||
|
this.connector = connector;
|
||||||
|
}
|
||||||
|
|
||||||
|
public R eq(Object value) {
|
||||||
|
if (value != null) {
|
||||||
|
CPI.addWhereQueryCondition(queryModel.getQueryWrapper(), queryColumn.eq(value), connector);
|
||||||
|
}
|
||||||
|
return queryModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public <T> R eq(Object value, Predicate<T> when) {
|
||||||
|
if (value != null) {
|
||||||
|
CPI.addWhereQueryCondition(queryModel.getQueryWrapper(), queryColumn.eq(value, when), connector);
|
||||||
|
}
|
||||||
|
return queryModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public <T> R eq(LambdaGetter<T> value) {
|
||||||
|
return eq(LambdaUtil.getQueryColumn(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
public <T> R eq(LambdaGetter<T> value, Predicate<T> when) {
|
||||||
|
return eq(LambdaUtil.getQueryColumn(value), when);
|
||||||
|
}
|
||||||
|
|
||||||
|
public R ne(Object value) {
|
||||||
|
if (value != null) {
|
||||||
|
CPI.addWhereQueryCondition(queryModel.getQueryWrapper(), queryColumn.ne(value), connector);
|
||||||
|
}
|
||||||
|
return queryModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public <T> R ne(Object value, Predicate<T> when) {
|
||||||
|
if (value != null) {
|
||||||
|
CPI.addWhereQueryCondition(queryModel.getQueryWrapper(), queryColumn.ne(value, when), connector);
|
||||||
|
}
|
||||||
|
return queryModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public <T> R ne(LambdaGetter<T> value) {
|
||||||
|
return ne(LambdaUtil.getQueryColumn(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
public <T> R ne(LambdaGetter<T> value, Predicate<T> when) {
|
||||||
|
return ne(LambdaUtil.getQueryColumn(value), when);
|
||||||
|
}
|
||||||
|
|
||||||
|
public R like(Object value) {
|
||||||
|
if (value != null) {
|
||||||
|
CPI.addWhereQueryCondition(queryModel.getQueryWrapper(), queryColumn.like(value), connector);
|
||||||
|
}
|
||||||
|
return queryModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public <T> R like(Object value, Predicate<T> when) {
|
||||||
|
if (value != null) {
|
||||||
|
CPI.addWhereQueryCondition(queryModel.getQueryWrapper(), queryColumn.like(value, when), connector);
|
||||||
|
}
|
||||||
|
return queryModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public R likeLeft(Object value) {
|
||||||
|
if (value != null) {
|
||||||
|
CPI.addWhereQueryCondition(queryModel.getQueryWrapper(), queryColumn.likeLeft(value), connector);
|
||||||
|
}
|
||||||
|
return queryModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public <T> R likeLeft(Object value, Predicate<T> when) {
|
||||||
|
if (value != null) {
|
||||||
|
CPI.addWhereQueryCondition(queryModel.getQueryWrapper(), queryColumn.likeLeft(value, when), connector);
|
||||||
|
}
|
||||||
|
return queryModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public R likeRight(Object value) {
|
||||||
|
if (value != null) {
|
||||||
|
CPI.addWhereQueryCondition(queryModel.getQueryWrapper(), queryColumn.likeRight(value), connector);
|
||||||
|
}
|
||||||
|
return queryModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public <T> R likeRight(Object value, Predicate<T> when) {
|
||||||
|
if (value != null) {
|
||||||
|
CPI.addWhereQueryCondition(queryModel.getQueryWrapper(), queryColumn.likeRight(value, when), connector);
|
||||||
|
}
|
||||||
|
return queryModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public R gt(Object value) {
|
||||||
|
if (value != null) {
|
||||||
|
CPI.addWhereQueryCondition(queryModel.getQueryWrapper(), queryColumn.gt(value), connector);
|
||||||
|
}
|
||||||
|
return queryModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public <T> R gt(Object value, Predicate<T> when) {
|
||||||
|
if (value != null) {
|
||||||
|
CPI.addWhereQueryCondition(queryModel.getQueryWrapper(), queryColumn.gt(value, when), connector);
|
||||||
|
}
|
||||||
|
return queryModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public <T> R gt(LambdaGetter<T> value) {
|
||||||
|
return gt(LambdaUtil.getQueryColumn(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
public <T> R gt(LambdaGetter<T> value, Predicate<T> when) {
|
||||||
|
return gt(LambdaUtil.getQueryColumn(value), when);
|
||||||
|
}
|
||||||
|
|
||||||
|
public R ge(Object value) {
|
||||||
|
if (value != null) {
|
||||||
|
CPI.addWhereQueryCondition(queryModel.getQueryWrapper(), queryColumn.ge(value), connector);
|
||||||
|
}
|
||||||
|
return queryModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public <T> R ge(Object value, Predicate<T> when) {
|
||||||
|
if (value != null) {
|
||||||
|
CPI.addWhereQueryCondition(queryModel.getQueryWrapper(), queryColumn.ge(value, when), connector);
|
||||||
|
}
|
||||||
|
return queryModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public <T> R ge(LambdaGetter<T> value) {
|
||||||
|
return ge(LambdaUtil.getQueryColumn(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
public <T> R ge(LambdaGetter<T> value, Predicate<T> when) {
|
||||||
|
return ge(LambdaUtil.getQueryColumn(value), when);
|
||||||
|
}
|
||||||
|
|
||||||
|
public R lt(Object value) {
|
||||||
|
if (value != null) {
|
||||||
|
CPI.addWhereQueryCondition(queryModel.getQueryWrapper(), queryColumn.lt(value), connector);
|
||||||
|
}
|
||||||
|
return queryModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public <T> R lt(Object value, Predicate<T> when) {
|
||||||
|
if (value != null) {
|
||||||
|
CPI.addWhereQueryCondition(queryModel.getQueryWrapper(), queryColumn.lt(value, when), connector);
|
||||||
|
}
|
||||||
|
return queryModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public <T> R lt(LambdaGetter<T> value) {
|
||||||
|
return lt(LambdaUtil.getQueryColumn(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
public <T> R lt(LambdaGetter<T> value, Predicate<T> when) {
|
||||||
|
return lt(LambdaUtil.getQueryColumn(value), when);
|
||||||
|
}
|
||||||
|
|
||||||
|
public R le(Object value) {
|
||||||
|
if (value != null) {
|
||||||
|
CPI.addWhereQueryCondition(queryModel.getQueryWrapper(), queryColumn.le(value), connector);
|
||||||
|
}
|
||||||
|
return queryModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public <T> R le(Object value, Predicate<T> when) {
|
||||||
|
if (value != null) {
|
||||||
|
CPI.addWhereQueryCondition(queryModel.getQueryWrapper(), queryColumn.le(value, when), connector);
|
||||||
|
}
|
||||||
|
return queryModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public <T> R le(LambdaGetter<T> value) {
|
||||||
|
return le(LambdaUtil.getQueryColumn(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
public <T> R le(LambdaGetter<T> value, Predicate<T> when) {
|
||||||
|
return le(LambdaUtil.getQueryColumn(value), when);
|
||||||
|
}
|
||||||
|
|
||||||
|
public R isNull() {
|
||||||
|
CPI.addWhereQueryCondition(queryModel.getQueryWrapper(), queryColumn.isNull(), connector);
|
||||||
|
return queryModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public <T> R isNull(Predicate<T> when) {
|
||||||
|
CPI.addWhereQueryCondition(queryModel.getQueryWrapper(), queryColumn.isNull(when), connector);
|
||||||
|
return queryModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public R isNotNull() {
|
||||||
|
CPI.addWhereQueryCondition(queryModel.getQueryWrapper(), queryColumn.isNotNull(), connector);
|
||||||
|
return queryModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public <T> R isNotNull(Predicate<T> when) {
|
||||||
|
CPI.addWhereQueryCondition(queryModel.getQueryWrapper(), queryColumn.isNotNull(when), connector);
|
||||||
|
return queryModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public R in(Object... arrays) {
|
||||||
|
if (arrays != null) {
|
||||||
|
CPI.addWhereQueryCondition(queryModel.getQueryWrapper(), queryColumn.in(arrays), connector);
|
||||||
|
}
|
||||||
|
return queryModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public <T> R in(Object[] arrays, Predicate<T> when) {
|
||||||
|
//忽略 QueryWrapper.in("name", null) 的情况
|
||||||
|
if (arrays != null) {
|
||||||
|
CPI.addWhereQueryCondition(queryModel.getQueryWrapper(), queryColumn.in(arrays, when), connector);
|
||||||
|
}
|
||||||
|
return queryModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public R in(R queryModel) {
|
||||||
|
if (queryModel != null) {
|
||||||
|
CPI.addWhereQueryCondition(queryModel.getQueryWrapper(), queryColumn.in(queryModel), connector);
|
||||||
|
}
|
||||||
|
return this.queryModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public <T> R in(R queryModel, Predicate<T> when) {
|
||||||
|
if (queryModel != null) {
|
||||||
|
CPI.addWhereQueryCondition(queryModel.getQueryWrapper(), queryColumn.in(queryModel, when), connector);
|
||||||
|
}
|
||||||
|
return this.queryModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public R in(Collection<?> collection) {
|
||||||
|
if (queryModel != null) {
|
||||||
|
CPI.addWhereQueryCondition(queryModel.getQueryWrapper(), queryColumn.in(collection), connector);
|
||||||
|
}
|
||||||
|
return queryModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public <T> R in(Collection<?> collection, Predicate<T> when) {
|
||||||
|
if (queryModel != null) {
|
||||||
|
CPI.addWhereQueryCondition(queryModel.getQueryWrapper(), queryColumn.in(collection, when), connector);
|
||||||
|
}
|
||||||
|
return queryModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public R notIn(Object... arrays) {
|
||||||
|
if (queryModel != null) {
|
||||||
|
CPI.addWhereQueryCondition(queryModel.getQueryWrapper(), queryColumn.notIn(arrays), connector);
|
||||||
|
}
|
||||||
|
return queryModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public <T> R notIn(Object[] arrays, Predicate<T> when) {
|
||||||
|
if (queryModel != null) {
|
||||||
|
CPI.addWhereQueryCondition(queryModel.getQueryWrapper(), queryColumn.notIn(arrays, when), connector);
|
||||||
|
}
|
||||||
|
return queryModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public R notIn(Collection<?> collection) {
|
||||||
|
if (queryModel != null) {
|
||||||
|
CPI.addWhereQueryCondition(queryModel.getQueryWrapper(), queryColumn.notIn(collection), connector);
|
||||||
|
}
|
||||||
|
return queryModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public <T> R notIn(Collection<?> collection, Predicate<T> when) {
|
||||||
|
if (queryModel != null) {
|
||||||
|
CPI.addWhereQueryCondition(queryModel.getQueryWrapper(), queryColumn.notIn(collection, when), connector);
|
||||||
|
}
|
||||||
|
return queryModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public R notIn(R queryModel) {
|
||||||
|
if (queryModel != null) {
|
||||||
|
CPI.addWhereQueryCondition(queryModel.getQueryWrapper(), queryColumn.notIn(queryModel), connector);
|
||||||
|
}
|
||||||
|
return this.queryModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public <T> R notIn(R queryModel, Predicate<T> when) {
|
||||||
|
if (queryModel != null) {
|
||||||
|
CPI.addWhereQueryCondition(queryModel.getQueryWrapper(), queryColumn.notIn(queryModel, when), connector);
|
||||||
|
}
|
||||||
|
return this.queryModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public R between(Object start, Object end) {
|
||||||
|
if (queryModel != null) {
|
||||||
|
CPI.addWhereQueryCondition(queryModel.getQueryWrapper(), queryColumn.between(start, end), connector);
|
||||||
|
}
|
||||||
|
return queryModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public <T> R between(Object start, Object end, Predicate<T> when) {
|
||||||
|
if (queryModel != null) {
|
||||||
|
CPI.addWhereQueryCondition(queryModel.getQueryWrapper(), queryColumn.between(start, end, when), connector);
|
||||||
|
}
|
||||||
|
return queryModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public R notBetween(Object start, Object end) {
|
||||||
|
if (queryModel != null) {
|
||||||
|
CPI.addWhereQueryCondition(queryModel.getQueryWrapper(), queryColumn.notBetween(start, end), connector);
|
||||||
|
}
|
||||||
|
return queryModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public <T> R notBetween(Object start, Object end, Predicate<T> when) {
|
||||||
|
if (queryModel != null) {
|
||||||
|
CPI.addWhereQueryCondition(queryModel.getQueryWrapper(), queryColumn.notBetween(start, end, when), connector);
|
||||||
|
}
|
||||||
|
return queryModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,20 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2022-2023, Mybatis-Flex (fuhai999@gmail.com).
|
||||||
|
* <p>
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
* <p>
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* <p>
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 条件查询功能。
|
||||||
|
*/
|
||||||
|
package com.mybatisflex.core.activerecord.query;
|
||||||
@ -125,6 +125,10 @@ public class CPI {
|
|||||||
return queryWrapper.getWhereQueryCondition();
|
return queryWrapper.getWhereQueryCondition();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void addWhereQueryCondition(QueryWrapper queryWrapper, QueryCondition queryCondition, SqlConnector connector) {
|
||||||
|
queryWrapper.addWhereQueryCondition(queryCondition, connector);
|
||||||
|
}
|
||||||
|
|
||||||
public static List<QueryColumn> getGroupByColumns(QueryWrapper queryWrapper) {
|
public static List<QueryColumn> getGroupByColumns(QueryWrapper queryWrapper) {
|
||||||
return queryWrapper.getGroupByColumns();
|
return queryWrapper.getGroupByColumns();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -17,7 +17,9 @@
|
|||||||
package com.mybatisflex.test.model;
|
package com.mybatisflex.test.model;
|
||||||
|
|
||||||
import com.mybatisflex.annotation.Id;
|
import com.mybatisflex.annotation.Id;
|
||||||
|
import com.mybatisflex.annotation.KeyType;
|
||||||
import com.mybatisflex.annotation.Table;
|
import com.mybatisflex.annotation.Table;
|
||||||
|
import com.mybatisflex.core.activerecord.Model;
|
||||||
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
@ -28,35 +30,42 @@ import java.util.Objects;
|
|||||||
* @since 2023-06-07
|
* @since 2023-06-07
|
||||||
*/
|
*/
|
||||||
@Table("tb_good")
|
@Table("tb_good")
|
||||||
public class Good {
|
public class Good extends Model<Good> {
|
||||||
|
|
||||||
@Id
|
@Id(keyType = KeyType.Auto)
|
||||||
private Integer goodId;
|
private Integer goodId;
|
||||||
private String name;
|
private String name;
|
||||||
private double price;
|
private Double price;
|
||||||
|
|
||||||
|
public static Good create() {
|
||||||
|
return new Good();
|
||||||
|
}
|
||||||
|
|
||||||
public Integer getGoodId() {
|
public Integer getGoodId() {
|
||||||
return goodId;
|
return goodId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setGoodId(Integer goodId) {
|
public Good setGoodId(Integer goodId) {
|
||||||
this.goodId = goodId;
|
this.goodId = goodId;
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setName(String name) {
|
public Good setName(String name) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public double getPrice() {
|
public Double getPrice() {
|
||||||
return price;
|
return price;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setPrice(double price) {
|
public Good setPrice(Double price) {
|
||||||
this.price = price;
|
this.price = price;
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -79,23 +88,20 @@ public class Good {
|
|||||||
|
|
||||||
Good good = (Good) o;
|
Good good = (Good) o;
|
||||||
|
|
||||||
if (Double.compare(good.price, price) != 0) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!Objects.equals(goodId, good.goodId)) {
|
if (!Objects.equals(goodId, good.goodId)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return Objects.equals(name, good.name);
|
if (!Objects.equals(name, good.name)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return Objects.equals(price, good.price);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
int result;
|
int result = goodId != null ? goodId.hashCode() : 0;
|
||||||
long temp;
|
|
||||||
result = goodId != null ? goodId.hashCode() : 0;
|
|
||||||
result = 31 * result + (name != null ? name.hashCode() : 0);
|
result = 31 * result + (name != null ? name.hashCode() : 0);
|
||||||
temp = Double.doubleToLongBits(price);
|
result = 31 * result + (price != null ? price.hashCode() : 0);
|
||||||
result = 31 * result + (int) (temp ^ (temp >>> 32));
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -19,9 +19,12 @@ package com.mybatisflex.test.mapper;
|
|||||||
import com.mybatisflex.core.mybatis.Mappers;
|
import com.mybatisflex.core.mybatis.Mappers;
|
||||||
import com.mybatisflex.core.query.QueryWrapper;
|
import com.mybatisflex.core.query.QueryWrapper;
|
||||||
import com.mybatisflex.test.model.Good;
|
import com.mybatisflex.test.model.Good;
|
||||||
|
import org.junit.jupiter.api.Assertions;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.springframework.boot.test.context.SpringBootTest;
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
|
||||||
|
import static com.mybatisflex.test.model.table.GoodTableDef.GOOD;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author 王帅
|
* @author 王帅
|
||||||
* @since 2023-07-23
|
* @since 2023-07-23
|
||||||
@ -31,12 +34,75 @@ class ActiveRecordTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testMapper() {
|
void testMapper() {
|
||||||
Good good = new Good();
|
Good good = Good.create();
|
||||||
good.setPrice(28);
|
|
||||||
|
|
||||||
GoodMapper goodMapper = Mappers.ofMapperClass(GoodMapper.class);
|
good.setPrice(28.0);
|
||||||
|
|
||||||
|
GoodMapper goodMapper = (GoodMapper) Mappers.ofEntityClass(Good.class);
|
||||||
|
|
||||||
goodMapper.selectListByQuery(QueryWrapper.create(good));
|
goodMapper.selectListByQuery(QueryWrapper.create(good));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testInsert() {
|
||||||
|
boolean saved = Good.create()
|
||||||
|
.setPrice(28.0)
|
||||||
|
.setName("摆渡人")
|
||||||
|
.save();
|
||||||
|
|
||||||
|
Assertions.assertTrue(saved);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testUpdate() {
|
||||||
|
Good.create()
|
||||||
|
.setGoodId(11)
|
||||||
|
.setPrice(38.0)
|
||||||
|
.updateById();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testDelete() {
|
||||||
|
boolean removed = Good.create()
|
||||||
|
.setGoodId(1)
|
||||||
|
.removeById();
|
||||||
|
|
||||||
|
Assertions.assertTrue(removed);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testSelectById() {
|
||||||
|
Good good = Good.create()
|
||||||
|
.setGoodId(11)
|
||||||
|
.oneById();
|
||||||
|
|
||||||
|
System.out.println(good);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testSelectOne() {
|
||||||
|
Good good1 = Good.create()
|
||||||
|
.setName("摆渡人")
|
||||||
|
.one();
|
||||||
|
|
||||||
|
Good good2 = Good.create()
|
||||||
|
.where(GOOD.NAME.eq("摆渡人"))
|
||||||
|
.one();
|
||||||
|
|
||||||
|
Good good3 = Good.create()
|
||||||
|
.where(Good::getName).eq("摆渡人")
|
||||||
|
.one();
|
||||||
|
|
||||||
|
Assertions.assertEquals(good1, good2);
|
||||||
|
Assertions.assertEquals(good1, good3);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testSelectList() {
|
||||||
|
Good.create()
|
||||||
|
.where(GOOD.PRICE.ge(28.0))
|
||||||
|
.list()
|
||||||
|
.forEach(System.out::println);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user