001/* 002 * Copyright (c) 2022-2025, Mybatis-Flex (fuhai999@gmail.com). 003 * <p> 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * <p> 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * <p> 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package com.mybatisflex.core.activerecord; 018 019import com.mybatisflex.core.BaseMapper; 020import com.mybatisflex.core.activerecord.query.FieldsQuery; 021import com.mybatisflex.core.activerecord.query.QueryModel; 022import com.mybatisflex.core.activerecord.query.RelationsQuery; 023import com.mybatisflex.core.query.MapperQueryChain; 024import com.mybatisflex.core.query.QueryWrapper; 025import com.mybatisflex.core.query.RelationsBuilder; 026import com.mybatisflex.core.relation.RelationManager; 027import com.mybatisflex.core.util.LambdaGetter; 028import com.mybatisflex.core.util.LambdaUtil; 029import com.mybatisflex.core.util.SqlUtil; 030 031import java.io.Serializable; 032import java.util.Arrays; 033import java.util.Optional; 034 035/** 036 * Active Record 模型。 037 * 038 * @param <T> 实体类类型 039 * @author 王帅 040 * @since 2023-07-24 041 */ 042@SuppressWarnings({"unused", "unchecked"}) 043public abstract class Model<T extends Model<T>> 044 extends QueryModel<T> 045 implements MapperModel<T>, MapperQueryChain<T>, Serializable { 046 047 /** 048 * 根据实体类构建的条件删除数据。 049 * 050 * @return {@code true} 删除成功,{@code false} 删除失败 051 */ 052 public boolean remove() { 053 return SqlUtil.toBool(baseMapper().deleteByQuery(queryWrapper())); 054 } 055 056 /** 057 * 根据实体类构建的条件删除数据,结果使用 {@link Optional} 返回源对象回调,删除成功返回 058 * {@code Optional.of(this)},删除失败返回 {@code Optional.empty()}。 059 * 060 * @return {@link Optional} 链式调用 061 */ 062 public Optional<T> removeOpt() { 063 return remove() ? Optional.of((T) this) : Optional.empty(); 064 } 065 066 /** 067 * 根据实体类构建的条件更新数据(自动忽略 {@code null} 值)。 068 * 069 * @return {@code true} 更新成功,{@code false} 更新失败 070 */ 071 public boolean update() { 072 return update(true); 073 } 074 075 /** 076 * 根据实体类构建的条件更新数据(自动忽略 {@code null} 值),结果使用 {@link Optional} 077 * 返回源对象回调,更新成功返回 {@code Optional.of(this)},更新失败返回 078 * {@code Optional.empty()}。 079 * 080 * @return {@link Optional} 链式调用 081 */ 082 public Optional<T> updateOpt() { 083 return updateOpt(true); 084 } 085 086 /** 087 * 根据实体类构建的条件更新数据,并设置是否忽略 {@code null} 值。 088 * 089 * @param ignoreNulls 是否忽略 {@code null} 值 090 * @return {@code true} 更新成功,{@code false} 更新失败 091 */ 092 public boolean update(boolean ignoreNulls) { 093 return SqlUtil.toBool(baseMapper().updateByQuery((T) this, ignoreNulls, queryWrapper())); 094 } 095 096 /** 097 * 根据实体类构建的条件更新数据,并设置是否忽略 {@code null} 值,结果使用 {@link Optional} 098 * 返回源对象回调,更新成功返回 {@code Optional.of(this)},更新失败返回 099 * {@code Optional.empty()}。 100 * 101 * @param ignoreNulls 是否忽略 {@code null} 值 102 * @return {@link Optional} 链式调用 103 */ 104 public Optional<T> updateOpt(boolean ignoreNulls) { 105 return update(ignoreNulls) ? Optional.of((T) this) : Optional.empty(); 106 } 107 108 @Override 109 public BaseMapper<T> baseMapper() { 110 return MapperModel.super.baseMapper(); 111 } 112 113 @Override 114 public QueryWrapper toQueryWrapper() { 115 return queryWrapper(); 116 } 117 118 @Override 119 public FieldsQuery<T> withFields() { 120 return new FieldsQuery<>(this); 121 } 122 123 @Override 124 public RelationsQuery<T> withRelations() { 125 return new RelationsQuery<>(this); 126 } 127 128 @Override 129 public RelationsBuilder<T> withRelations(LambdaGetter<T>... columns) { 130 if(columns != null && columns.length > 0) { 131 String[] array = Arrays.stream(columns) 132 .map(LambdaUtil::getFieldName) 133 .toArray(String[]::new); 134 RelationManager.addQueryRelations(array); 135 } 136 return new RelationsBuilder<>(this); 137 } 138 139}