diff --git a/mybatis-flex-annotation/src/main/java/com/mybatisflex/annotation/NoneListener.java b/mybatis-flex-annotation/src/main/java/com/mybatisflex/annotation/NoneListener.java index f3e5a49b..b1ff0ee8 100644 --- a/mybatis-flex-annotation/src/main/java/com/mybatisflex/annotation/NoneListener.java +++ b/mybatis-flex-annotation/src/main/java/com/mybatisflex/annotation/NoneListener.java @@ -15,7 +15,7 @@ */ package com.mybatisflex.annotation; -public class NoneListener implements InsertListener, UpdateListener { +public class NoneListener implements InsertListener, UpdateListener, SetListener { @Override public void onInsert(Object entity) { @@ -25,4 +25,9 @@ public class NoneListener implements InsertListener, UpdateListener { public void onUpdate(Object entity) { } + + @Override + public Object onSet(Object entity, String property, Object value) { + return null; + } } diff --git a/mybatis-flex-annotation/src/main/java/com/mybatisflex/annotation/SetListener.java b/mybatis-flex-annotation/src/main/java/com/mybatisflex/annotation/SetListener.java new file mode 100644 index 00000000..16b5f467 --- /dev/null +++ b/mybatis-flex-annotation/src/main/java/com/mybatisflex/annotation/SetListener.java @@ -0,0 +1,21 @@ +/** + * Copyright (c) 2022-2023, Mybatis-Flex (fuhai999@gmail.com). + *

+ * 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 + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * 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.annotation; + +public interface SetListener { + + Object onSet(Object entity, String property, Object value); +} diff --git a/mybatis-flex-annotation/src/main/java/com/mybatisflex/annotation/Table.java b/mybatis-flex-annotation/src/main/java/com/mybatisflex/annotation/Table.java index 72c7eecc..4e98c673 100644 --- a/mybatis-flex-annotation/src/main/java/com/mybatisflex/annotation/Table.java +++ b/mybatis-flex-annotation/src/main/java/com/mybatisflex/annotation/Table.java @@ -51,4 +51,9 @@ public @interface Table { * 监听 entity 的 update 行为 */ Class onUpdate() default NoneListener.class; + + /** + * 监听 entity 的查询数据的 set 行为,用户主动 set 不会触发 + */ + Class onSet() default NoneListener.class; } \ No newline at end of file diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/mybatis/FlexConfiguration.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/mybatis/FlexConfiguration.java index d20f269d..9d7042a0 100644 --- a/mybatis-flex-core/src/main/java/com/mybatisflex/core/mybatis/FlexConfiguration.java +++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/mybatis/FlexConfiguration.java @@ -21,6 +21,7 @@ import com.mybatisflex.core.keygen.MultiRowKeyGenerator; import com.mybatisflex.core.keygen.MybatisKeyGeneratorUtil; import com.mybatisflex.core.keygen.RowKeyGenerator; import com.mybatisflex.core.row.RowMapper; +import com.mybatisflex.core.table.EntityWrapperFactory; import com.mybatisflex.core.table.TableInfo; import com.mybatisflex.core.table.TableInfoFactory; import com.mybatisflex.core.util.CollectionUtil; @@ -35,7 +36,6 @@ import org.apache.ibatis.mapping.BoundSql; import org.apache.ibatis.mapping.Environment; import org.apache.ibatis.mapping.MappedStatement; import org.apache.ibatis.mapping.ResultMap; -import org.apache.ibatis.reflection.MetaObject; import org.apache.ibatis.session.Configuration; import org.apache.ibatis.session.ResultHandler; import org.apache.ibatis.session.RowBounds; @@ -50,6 +50,7 @@ public class FlexConfiguration extends Configuration { public FlexConfiguration(Environment environment) { super(environment); setMapUnderscoreToCamelCase(true); + setObjectWrapperFactory(new EntityWrapperFactory()); initDefaultMappers(); } @@ -66,11 +67,6 @@ public class FlexConfiguration extends Configuration { } - @Override - public MetaObject newMetaObject(Object object) { - return super.newMetaObject(object); - } - /** * 为原生 sql 设置参数 */ diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/table/EntityWrapperFactory.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/table/EntityWrapperFactory.java new file mode 100644 index 00000000..fa1d88ea --- /dev/null +++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/table/EntityWrapperFactory.java @@ -0,0 +1,65 @@ +/** + * Copyright (c) 2022-2023, Mybatis-Flex (fuhai999@gmail.com). + *

+ * 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 + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * 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.table; + +import com.mybatisflex.annotation.SetListener; +import org.apache.ibatis.reflection.MetaObject; +import org.apache.ibatis.reflection.property.PropertyTokenizer; +import org.apache.ibatis.reflection.wrapper.BeanWrapper; +import org.apache.ibatis.reflection.wrapper.ObjectWrapper; +import org.apache.ibatis.reflection.wrapper.ObjectWrapperFactory; + +import java.util.Collection; +import java.util.Map; + +public class EntityWrapperFactory implements ObjectWrapperFactory { + + @Override + public boolean hasWrapperFor(Object object) { + Class objectClass = object.getClass(); + if (Map.class.isAssignableFrom(objectClass) || + Collection.class.isAssignableFrom(objectClass)) { + return false; + } + return TableInfoFactory.getByEntityClass(objectClass) != null; + } + + @Override + public ObjectWrapper getWrapperFor(MetaObject metaObject, Object object) { + return new FlexBeanWrapper(metaObject, object); + } + + static class FlexBeanWrapper extends BeanWrapper { + + private Object entity; + private SetListener onSetListener; + + public FlexBeanWrapper(MetaObject metaObject, Object object) { + super(metaObject, object); + this.entity = object; + this.onSetListener = TableInfoFactory.getByEntityClass(object.getClass()).getOnSetListener(); + } + + @Override + public void set(PropertyTokenizer prop, Object value) { + Object v = value; + if (onSetListener != null) { + v = onSetListener.onSet(entity, prop.getName(), value); + } + super.set(prop, v); + } + } +} diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/table/TableInfo.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/table/TableInfo.java index 89d0c4b6..f0fe002c 100644 --- a/mybatis-flex-core/src/main/java/com/mybatisflex/core/table/TableInfo.java +++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/table/TableInfo.java @@ -16,6 +16,7 @@ package com.mybatisflex.core.table; import com.mybatisflex.annotation.InsertListener; +import com.mybatisflex.annotation.SetListener; import com.mybatisflex.annotation.UpdateListener; import com.mybatisflex.core.FlexConsts; import com.mybatisflex.annotation.KeyType; @@ -79,6 +80,7 @@ public class TableInfo { private InsertListener onInsertListener; private UpdateListener onUpdateListener; + private SetListener onSetListener; private final ReflectorFactory reflectorFactory = new BaseReflectorFactory() { @@ -223,6 +225,14 @@ public class TableInfo { this.onUpdateListener = onUpdateListener; } + public SetListener getOnSetListener() { + return onSetListener; + } + + public void setOnSetListener(SetListener onSetListener) { + this.onSetListener = onSetListener; + } + public List getColumnInfoList() { return columnInfoList; } @@ -523,6 +533,9 @@ public class TableInfo { ColumnInfo columnInfo = columnInfoMapping.get(column); if (columnInfo != null && metaObject.hasSetter(columnInfo.property)) { Object value = ConvertUtil.convert(row.get(column), metaObject.getSetterType(columnInfo.property)); + if (onSetListener != null) { + value = onSetListener.onSet(instance, columnInfo.property, value); + } metaObject.setValue(columnInfo.property, value); } } diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/table/TableInfoFactory.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/table/TableInfoFactory.java index 192c74f0..3896bd05 100644 --- a/mybatis-flex-core/src/main/java/com/mybatisflex/core/table/TableInfoFactory.java +++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/table/TableInfoFactory.java @@ -77,6 +77,11 @@ public class TableInfoFactory { } + public static TableInfo getByEntityClass(Class entityClass) { + return tableInfoMap.get(entityClass); + } + + private static Class getEntityClass(Class mapperClass) { Type[] genericInterfaces = mapperClass.getGenericInterfaces(); if (genericInterfaces.length == 1) { @@ -112,6 +117,10 @@ public class TableInfoFactory { tableInfo.setOnUpdateListener(ClassUtil.newInstance(table.onUpdate())); } + if (table.onSet() != NoneListener.class){ + tableInfo.setOnSetListener(ClassUtil.newInstance(table.onSet())); + } + if (StringUtil.isNotBlank(table.dataSource())){ tableInfo.setDataSource(table.dataSource()); } diff --git a/mybatis-flex-test/mybatis-flex-native-test/src/main/java/com/mybatisflex/test/Account.java b/mybatis-flex-test/mybatis-flex-native-test/src/main/java/com/mybatisflex/test/Account.java index d28f2d94..b1316743 100644 --- a/mybatis-flex-test/mybatis-flex-native-test/src/main/java/com/mybatisflex/test/Account.java +++ b/mybatis-flex-test/mybatis-flex-native-test/src/main/java/com/mybatisflex/test/Account.java @@ -8,7 +8,7 @@ import java.util.Date; import java.util.HashMap; import java.util.Map; -@Table(value = "tb_account",dataSource = "ds2") +@Table(value = "tb_account",dataSource = "ds2",onSet = AccountOnSetListener.class) public class Account { @Id(keyType = KeyType.Auto) diff --git a/mybatis-flex-test/mybatis-flex-native-test/src/main/java/com/mybatisflex/test/AccountOnSetListener.java b/mybatis-flex-test/mybatis-flex-native-test/src/main/java/com/mybatisflex/test/AccountOnSetListener.java new file mode 100644 index 00000000..96e94020 --- /dev/null +++ b/mybatis-flex-test/mybatis-flex-native-test/src/main/java/com/mybatisflex/test/AccountOnSetListener.java @@ -0,0 +1,12 @@ +package com.mybatisflex.test; + +import com.mybatisflex.annotation.SetListener; + +public class AccountOnSetListener implements SetListener { + @Override + public Object onSet(Object entity, String property, Object value) { +// System.out.println(">>>>>>> entity: " + entity); + System.out.println(">>>>>>> property: " + property +" value:" + value); + return value; + } +} diff --git a/mybatis-flex-test/mybatis-flex-native-test/src/main/java/com/mybatisflex/test/EntityTestStarter.java b/mybatis-flex-test/mybatis-flex-native-test/src/main/java/com/mybatisflex/test/EntityTestStarter.java index 86d5f602..6b8932bd 100644 --- a/mybatis-flex-test/mybatis-flex-native-test/src/main/java/com/mybatisflex/test/EntityTestStarter.java +++ b/mybatis-flex-test/mybatis-flex-native-test/src/main/java/com/mybatisflex/test/EntityTestStarter.java @@ -16,11 +16,13 @@ package com.mybatisflex.test; import com.mybatisflex.core.MybatisFlexBootstrap; +import com.mybatisflex.core.query.QueryWrapper; import org.apache.ibatis.logging.stdout.StdOutImpl; import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder; import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType; import javax.sql.DataSource; +import java.util.List; public class EntityTestStarter { @@ -44,10 +46,14 @@ public class EntityTestStarter { // System.out.println(account); AccountMapper accountMapper = bootstrap.getMapper(AccountMapper.class); + Account account = accountMapper.selectOneById(1); - for (int i = 0; i < 100; i++) { - Account account = accountMapper.selectOneById(1); - } + + List accounts = accountMapper.selectAll(); + System.out.println(accounts); +// + long l = accountMapper.selectCountByQuery(QueryWrapper.create()); + System.out.println("count: "+ l); // System.out.println(account); //