001/* 002 * Copyright (c) 2022-2023, 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.mybatis.Mappers; 021import com.mybatisflex.core.table.TableInfo; 022import com.mybatisflex.core.table.TableInfoFactory; 023import com.mybatisflex.core.util.SqlUtil; 024 025import java.io.Serializable; 026import java.util.Optional; 027 028/** 029 * <p>使用 {@link BaseMapper} 进行 CRUD 操作的实体类的抽象接口。 030 * 031 * <p>使用接口是为了方便拓展,该接口提供了简单的根据 <b>主键</b> 操作数据的方法, 032 * 实现类可以进行其他方法的扩展。 033 * 034 * @param <T> 实体类类型 035 * @author 王帅 036 * @since 2023-07-23 037 */ 038@SuppressWarnings({"unused", "unchecked"}) 039public interface MapperModel<T> { 040 041 /** 042 * 获取实体类对应的 {@link BaseMapper} 接口。 043 * 044 * @return {@link BaseMapper} 接口 045 */ 046 default BaseMapper<T> baseMapper() { 047 return Mappers.ofEntityClass((Class<T>) getClass()); 048 } 049 050 /** 051 * <p>获取实体类主键数据。 052 * 053 * <p>可以拓展该方法提高效率,例如: 054 * <pre>{@code 055 * return new Object[]{id}; 056 * }</pre> 057 * 058 * @return 主键数据数组 059 */ 060 default Object pkValue() { 061 TableInfo tableInfo = TableInfoFactory.ofEntityClass(getClass()); 062 return tableInfo.getPkValue(this); 063 } 064 065 /** 066 * 保存数据(自动忽略 {@code null} 值)。 067 * 068 * @return {@code true} 保存成功,{@code false} 保存失败 069 */ 070 default boolean save() { 071 return save(true); 072 } 073 074 /** 075 * 保存数据(自动忽略 {@code null} 值),结果使用 {@link Optional} 076 * 返回源对象回调,保存成功返回 {@code Optional.of(this)},保存失败返回 077 * {@code Optional.empty()}。 078 * 079 * @return {@link Optional} 链式调用 080 */ 081 default Optional<T> saveOpt() { 082 return saveOpt(true); 083 } 084 085 /** 086 * 保存数据,并设置是否忽略 {@code null} 值。 087 * 088 * @param ignoreNulls 是否忽略 {@code null} 值 089 * @return {@code true} 保存成功,{@code false} 保存失败 090 */ 091 default boolean save(boolean ignoreNulls) { 092 return SqlUtil.toBool(baseMapper().insert((T) this, ignoreNulls)); 093 } 094 095 /** 096 * 保存数据,并设置是否忽略 {@code null} 值,结果使用 {@link Optional} 097 * 返回源对象回调,保存成功返回 {@code Optional.of(this)},保存失败返回 098 * {@code Optional.empty()}。 099 * 100 * @param ignoreNulls 是否忽略 {@code null} 值 101 * @return {@link Optional} 链式调用 102 */ 103 default Optional<T> saveOpt(boolean ignoreNulls) { 104 return save(ignoreNulls) ? Optional.of((T) this) : Optional.empty(); 105 } 106 107 /** 108 * 保存或者更新数据,如果实体类主键没有值,则 <b>保存</b> 数据;如果实体类主键有值,则 109 * <b>更新</b> 数据(全部自动忽略 {@code null} 值)。 110 * 111 * @return {@code true} 保存或更新成功,{@code false} 保存或更新失败 112 */ 113 default boolean saveOrUpdate() { 114 return saveOrUpdate(true); 115 } 116 117 /** 118 * 保存或者更新数据,如果实体类主键没有值,则 <b>保存</b> 数据;如果实体类主键有值,则 119 * <b>更新</b> 数据(全部自动忽略 {@code null} 值),结果使用 {@link Optional} 120 * 返回源对象回调,保存或更新成功返回 {@code Optional.of(this)},保存或更新失败返回 121 * {@code Optional.empty()}。 122 * 123 * @return {@link Optional} 链式调用 124 */ 125 default Optional<T> saveOrUpdateOpt() { 126 return saveOrUpdateOpt(true); 127 } 128 129 /** 130 * 保存或者更新数据,如果实体类主键没有值,则 <b>保存</b> 数据;如果实体类主键有值,则 131 * <b>更新</b> 数据,并设置是否忽略 {@code null} 值。 132 * 133 * @param ignoreNulls 是否忽略 {@code null} 值 134 * @return {@code true} 保存或更新成功,{@code false} 保存或更新失败 135 */ 136 default boolean saveOrUpdate(boolean ignoreNulls) { 137 return SqlUtil.toBool(baseMapper().insertOrUpdate((T) this, ignoreNulls)); 138 } 139 140 /** 141 * 保存或者更新数据,如果实体类主键没有值,则 <b>保存</b> 数据;如果实体类主键有值,则 142 * <b>更新</b> 数据,并设置是否忽略 {@code null} 值,结果使用 {@link Optional} 143 * 返回源对象回调,保存或更新成功返回 {@code Optional.of(this)},保存或更新失败返回 144 * {@code Optional.empty()}。 145 * 146 * @param ignoreNulls 是否忽略 {@code null} 值 147 * @return {@link Optional} 链式调用 148 */ 149 default Optional<T> saveOrUpdateOpt(boolean ignoreNulls) { 150 return saveOrUpdate(ignoreNulls) ? Optional.of((T) this) : Optional.empty(); 151 } 152 153 /** 154 * 根据实体类主键删除数据。 155 * 156 * @return {@code true} 删除成功,{@code false} 删除失败 157 */ 158 default boolean removeById() { 159 return SqlUtil.toBool(baseMapper().deleteById((Serializable) pkValue())); 160 } 161 162 /** 163 * 根据实体类主键删除数据,结果使用 {@link Optional} 返回源对象回调,删除成功返回 164 * {@code Optional.of(this)},删除失败返回 {@code Optional.empty()}。 165 * 166 * @return {@link Optional} 链式调用 167 */ 168 default Optional<T> removeByIdOpt() { 169 return removeById() ? Optional.of((T) this) : Optional.empty(); 170 } 171 172 /** 173 * 根据实体类主键更新数据(自动忽略 {@code null} 值)。 174 * 175 * @return {@code true} 更新成功,{@code false} 更新失败 176 */ 177 default boolean updateById() { 178 return updateById(true); 179 } 180 181 /** 182 * 根据实体类主键更新数据(自动忽略 {@code null} 值),结果使用 {@link Optional} 183 * 返回源对象回调,更新成功返回 {@code Optional.of(this)},更新失败返回 184 * {@code Optional.empty()}。 185 * 186 * @return {@link Optional} 链式调用 187 */ 188 default Optional<T> updateByIdOpt() { 189 return updateByIdOpt(true); 190 } 191 192 /** 193 * 根据实体类主键更新数据,并设置是否忽略 {@code null} 值。 194 * 195 * @param ignoreNulls 是否忽略 {@code null} 值 196 * @return {@code true} 更新成功,{@code false} 更新失败 197 */ 198 default boolean updateById(boolean ignoreNulls) { 199 return SqlUtil.toBool(baseMapper().update((T) this, ignoreNulls)); 200 } 201 202 /** 203 * 根据实体类主键更新数据,并设置是否忽略 {@code null} 值,结果使用 {@link Optional} 204 * 返回源对象回调,更新成功返回 {@code Optional.of(this)},更新失败返回 205 * {@code Optional.empty()}。 206 * 207 * @param ignoreNulls 是否忽略 {@code null} 值 208 * @return {@link Optional} 链式调用 209 */ 210 default Optional<T> updateByIdOpt(boolean ignoreNulls) { 211 return updateById(ignoreNulls) ? Optional.of((T) this) : Optional.empty(); 212 } 213 214 /** 215 * 根据实体类主键获取一条数据。 216 * 217 * @return 数据 218 */ 219 default T oneById() { 220 return baseMapper().selectOneById((Serializable) pkValue()); 221 } 222 223 /** 224 * 根据实体类主键获取一条数据,并封装为 {@link Optional} 返回。 225 * 226 * @return 数据 227 */ 228 default Optional<T> oneByIdOpt() { 229 return Optional.ofNullable(oneById()); 230 } 231 232}