mirror of
https://gitee.com/mybatis-flex/mybatis-flex.git
synced 2025-12-07 00:58:24 +08:00
add RowUtil.java
This commit is contained in:
parent
59a3cb1d7a
commit
8cbec82681
@ -37,24 +37,58 @@ Page<Row> rowPage = Db.paginate("tb_account",3,10,query);
|
||||
>
|
||||
> 具体参考: [Db.java](./mybatis-flex-core/src/main/java/com/mybatisflex/core/row/Db.java) 。
|
||||
|
||||
## Row 转换为 Entity
|
||||
## Row.toEntity()
|
||||
|
||||
`Row.toEntity(Entity.class)` 方法主要是用于可以把 Row 转换为 entity 实体类。通过这个方法,可以把 Entity 里的
|
||||
`@Column()` 配置的列名和 Row 里的 key 进行自动关联。
|
||||
|
||||
代码示例:
|
||||
|
||||
```java
|
||||
Row row = Db.selectOneById("tb_account","id",1);
|
||||
Row row = Db.selectOneBySql("select * from ....");
|
||||
Account entity = row.toEntity(Account.class);
|
||||
```
|
||||
|
||||
## 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);
|
||||
```
|
||||
|
||||
## Row 字段转化为驼峰风格
|
||||
|
||||
```java
|
||||
Row row = Db.selectOneById("tb_account","id",1);
|
||||
Row row = Db..selectOneBySql("select * from ....");
|
||||
Map result = row.toCamelKeysMap();
|
||||
```
|
||||
|
||||
## Row 字段转换为下划线风格
|
||||
|
||||
```java
|
||||
Row row = Db.selectOneById("tb_account","id",1);
|
||||
Row row = Db..selectOneBySql("select * from ....");
|
||||
Map result = row.toUnderlineKeysMap();
|
||||
```
|
||||
|
||||
@ -92,3 +126,12 @@ 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 属性的映射关系。
|
||||
@ -17,9 +17,10 @@ package com.mybatisflex.core.row;
|
||||
|
||||
import com.mybatisflex.core.javassist.ModifyAttrsRecord;
|
||||
import com.mybatisflex.core.query.QueryColumn;
|
||||
import com.mybatisflex.core.table.TableInfo;
|
||||
import com.mybatisflex.core.table.TableInfoFactory;
|
||||
import com.mybatisflex.core.util.*;
|
||||
import com.mybatisflex.core.util.ArrayUtil;
|
||||
import com.mybatisflex.core.util.ConvertUtil;
|
||||
import com.mybatisflex.core.util.SqlUtil;
|
||||
import com.mybatisflex.core.util.StringUtil;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
@ -275,14 +276,11 @@ public class Row extends HashMap<String, Object> implements ModifyAttrsRecord {
|
||||
}
|
||||
|
||||
public <T> T toEntity(Class<T> entityClass) {
|
||||
TableInfo tableInfo = TableInfoFactory.ofEntityClass(entityClass);
|
||||
return tableInfo.newInstanceByRow(this);
|
||||
return RowUtil.toEntity(this, entityClass);
|
||||
}
|
||||
|
||||
public <T> T toObject(Class<T> objectClass) {
|
||||
Object instance = ClassUtil.newInstance(objectClass);
|
||||
RowSetter.setObject(this, instance);
|
||||
return (T) instance;
|
||||
return RowUtil.toObject(this, objectClass);
|
||||
}
|
||||
|
||||
public Map<String, Object> toCamelKeysMap() {
|
||||
|
||||
@ -1,71 +0,0 @@
|
||||
/**
|
||||
* 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.row;
|
||||
|
||||
import com.mybatisflex.core.util.ClassUtil;
|
||||
import com.mybatisflex.core.util.ConvertUtil;
|
||||
import com.mybatisflex.core.util.StringUtil;
|
||||
import org.apache.ibatis.util.MapUtil;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
class RowSetter {
|
||||
|
||||
static Map<Class<?>, Map<String, Method>> getterMethods = new ConcurrentHashMap<>();
|
||||
|
||||
static void setObject(Row row, Object toObject) {
|
||||
Map<String, Method> setterMethods = getSetterMethods(toObject.getClass());
|
||||
row.forEach((column, columnValue) -> {
|
||||
Method setter = setterMethods.get(column);
|
||||
try {
|
||||
if (setter != null) {
|
||||
Object value = ConvertUtil.convert(columnValue, setter.getParameterTypes()[0]);
|
||||
setter.invoke(toObject, value);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Can not invoke method: " + setter);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
private static Map<String, Method> getSetterMethods(Class<?> aClass) {
|
||||
return MapUtil.computeIfAbsent(getterMethods, aClass, aClass1 -> {
|
||||
Map<String, Method> getterMethodsMapping = new HashMap<>();
|
||||
List<Method> setters = ClassUtil.getAllMethods(aClass1,
|
||||
method -> method.getName().startsWith("set")
|
||||
&& method.getParameterCount() == 1
|
||||
&& Modifier.isPublic(method.getModifiers())
|
||||
);
|
||||
for (Method setter : setters) {
|
||||
String column = setter.getName().substring(3);
|
||||
getterMethodsMapping.put(column, setter);
|
||||
getterMethodsMapping.put(column.toLowerCase(), setter);
|
||||
getterMethodsMapping.put(column.toUpperCase(), setter);
|
||||
getterMethodsMapping.put(StringUtil.firstCharToLowerCase(column), setter);
|
||||
getterMethodsMapping.put(StringUtil.camelToUnderline(column), setter);
|
||||
getterMethodsMapping.put(StringUtil.camelToUnderline(column).toUpperCase(), setter);
|
||||
getterMethodsMapping.put(StringUtil.underlineToCamel(column), setter);
|
||||
}
|
||||
return getterMethodsMapping;
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,108 @@
|
||||
/**
|
||||
* 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.row;
|
||||
|
||||
import com.mybatisflex.core.table.TableInfo;
|
||||
import com.mybatisflex.core.table.TableInfoFactory;
|
||||
import com.mybatisflex.core.util.ClassUtil;
|
||||
import com.mybatisflex.core.util.ConvertUtil;
|
||||
import com.mybatisflex.core.util.StringUtil;
|
||||
import org.apache.ibatis.util.MapUtil;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
public class RowUtil {
|
||||
|
||||
private static final Map<Class<?>, Map<String, Method>> classGettersMapping = new ConcurrentHashMap<>();
|
||||
|
||||
public static <T> T toObject(Row row, Class<T> objectClass) {
|
||||
T instance = ClassUtil.newInstance(objectClass);
|
||||
Map<String, Method> setterMethods = getSetterMethods(objectClass);
|
||||
row.forEach((column, columnValue) -> {
|
||||
Method setter = setterMethods.get(column.toLowerCase());
|
||||
try {
|
||||
if (setter != null) {
|
||||
Object value = ConvertUtil.convert(columnValue, setter.getParameterTypes()[0]);
|
||||
setter.invoke(instance, value);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Can not invoke method: " + setter);
|
||||
}
|
||||
});
|
||||
return instance;
|
||||
}
|
||||
|
||||
|
||||
public static <T> List<T> toObjectList(List<Row> rows, Class<T> objectClass) {
|
||||
if (rows == null || rows.isEmpty()) {
|
||||
return Collections.emptyList();
|
||||
} else {
|
||||
List<T> objectList = new ArrayList<>();
|
||||
for (Row row : rows) {
|
||||
objectList.add(toObject(row, objectClass));
|
||||
}
|
||||
return objectList;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static <T> T toEntity(Row row, Class<T> entityClass) {
|
||||
TableInfo tableInfo = TableInfoFactory.ofEntityClass(entityClass);
|
||||
return tableInfo.newInstanceByRow(row);
|
||||
}
|
||||
|
||||
|
||||
public static <T> List<T> toEntityList(List<Row> rows, Class<T> entityClass) {
|
||||
if (rows == null || rows.isEmpty()) {
|
||||
return Collections.emptyList();
|
||||
} else {
|
||||
TableInfo tableInfo = TableInfoFactory.ofEntityClass(entityClass);
|
||||
List<T> entityList = new ArrayList<>();
|
||||
for (Row row : rows) {
|
||||
T entity = tableInfo.newInstanceByRow(row);
|
||||
entityList.add(entity);
|
||||
}
|
||||
return entityList;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static void registerMapping(Class<?> clazz, Map<String, Method> columnSetterMapping) {
|
||||
classGettersMapping.put(clazz, columnSetterMapping);
|
||||
}
|
||||
|
||||
|
||||
private static Map<String, Method> getSetterMethods(Class<?> aClass) {
|
||||
return MapUtil.computeIfAbsent(classGettersMapping, aClass, aClass1 -> {
|
||||
Map<String, Method> columnSetterMapping = new HashMap<>();
|
||||
List<Method> setters = ClassUtil.getAllMethods(aClass1,
|
||||
method -> method.getName().startsWith("set")
|
||||
&& method.getParameterCount() == 1
|
||||
&& Modifier.isPublic(method.getModifiers())
|
||||
);
|
||||
for (Method setter : setters) {
|
||||
String column = setter.getName().substring(3);
|
||||
columnSetterMapping.put(column.toLowerCase(), setter);
|
||||
columnSetterMapping.put(StringUtil.camelToUnderline(column).toLowerCase(), setter);
|
||||
columnSetterMapping.put(StringUtil.underlineToCamel(column).toUpperCase(), setter);
|
||||
}
|
||||
return columnSetterMapping;
|
||||
});
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user