Skip to content

Commit

Permalink
write a line into test.file
Browse files Browse the repository at this point in the history
  • Loading branch information
huifer committed Oct 23, 2024
1 parent 8ee8de7 commit 58af292
Show file tree
Hide file tree
Showing 3 changed files with 395 additions and 0 deletions.
245 changes: 245 additions & 0 deletions docs/spring/cs2b2a6db8-90df-11ef-a50a-acde48001122.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,245 @@
/**
* Copyright 2009-2018 the original author or authors.
* <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 org.apache.ibatis.reflection;

import org.apache.ibatis.reflection.invoker.GetFieldInvoker;
import org.apache.ibatis.reflection.invoker.Invoker;
import org.apache.ibatis.reflection.invoker.MethodInvoker;
import org.apache.ibatis.reflection.property.PropertyTokenizer;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.Collection;

/**
* 源类
*
* @author Clinton Begin
*/
public class MetaClass {

/**
* {@link DefaultReflectorFactory}
*/
private final ReflectorFactory reflectorFactory;
/**
* 反射器
*/
private final Reflector reflector;

private MetaClass(Class<?> type, ReflectorFactory reflectorFactory) {
this.reflectorFactory = reflectorFactory;
this.reflector = reflectorFactory.findForClass(type);
}

/**
* 根据 type (java.class) 和 反射工厂{@link DefaultReflectorFactory} 创建 {@link MetaClass}
*
* @param type
* @param reflectorFactory
* @return
*/
public static MetaClass forClass(Class<?> type, ReflectorFactory reflectorFactory) {
return new MetaClass(type, reflectorFactory);
}

public MetaClass metaClassForProperty(String name) {
Class<?> propType = reflector.getGetterType(name);
return MetaClass.forClass(propType, reflectorFactory);
}

/**
* 根据 name 获取数据类型
*
* @param name
* @return
*/
public String findProperty(String name) {
StringBuilder prop = buildProperty(name, new StringBuilder());
return prop.length() > 0 ? prop.toString() : null;
}

public String findProperty(String name, boolean useCamelCaseMapping) {
if (useCamelCaseMapping) {
name = name.replace("_", "");
}
return findProperty(name);
}

public String[] getGetterNames() {
return reflector.getGetablePropertyNames();
}

public String[] getSetterNames() {
return reflector.getSetablePropertyNames();
}

public Class<?> getSetterType(String name) {
PropertyTokenizer prop = new PropertyTokenizer(name);
if (prop.hasNext()) {
MetaClass metaProp = metaClassForProperty(prop.getName());
return metaProp.getSetterType(prop.getChildren());
} else {
return reflector.getSetterType(prop.getName());
}
}

/**
* @param name
* @return
*/
public Class<?> getGetterType(String name) {
PropertyTokenizer prop = new PropertyTokenizer(name);
if (prop.hasNext()) {
MetaClass metaProp = metaClassForProperty(prop);
return metaProp.getGetterType(prop.getChildren());
}
// issue #506. Resolve the type inside a Collection Object
return getGetterType(prop);
}

/**
* 根据属性获取 操作javaType
*
* @param prop
* @return
*/
private MetaClass metaClassForProperty(PropertyTokenizer prop) {
Class<?> propType = getGetterType(prop);
return MetaClass.forClass(propType, reflectorFactory);
}

/**
* 获取数据类型
*
* @param prop
* @return
*/
private Class<?> getGetterType(PropertyTokenizer prop) {
// 在 Reflector 类中获取
Class<?> type = reflector.getGetterType(prop.getName());
if (prop.getIndex() != null && Collection.class.isAssignableFrom(type)) {
Type returnType = getGenericGetterType(prop.getName());
if (returnType instanceof ParameterizedType) {
Type[] actualTypeArguments = ((ParameterizedType) returnType).getActualTypeArguments();
if (actualTypeArguments != null && actualTypeArguments.length == 1) {
returnType = actualTypeArguments[0];
if (returnType instanceof Class) {
type = (Class<?>) returnType;
} else if (returnType instanceof ParameterizedType) {
type = (Class<?>) ((ParameterizedType) returnType).getRawType();
}
}
}
}
return type;
}

private Type getGenericGetterType(String propertyName) {
try {
Invoker invoker = reflector.getGetInvoker(propertyName);
if (invoker instanceof MethodInvoker) {
Field _method = MethodInvoker.class.getDeclaredField("method");
_method.setAccessible(true);
Method method = (Method) _method.get(invoker);
return TypeParameterResolver.resolveReturnType(method, reflector.getType());
} else if (invoker instanceof GetFieldInvoker) {
Field _field = GetFieldInvoker.class.getDeclaredField("field");
_field.setAccessible(true);
Field field = (Field) _field.get(invoker);
return TypeParameterResolver.resolveFieldType(field, reflector.getType());
}
} catch (NoSuchFieldException | IllegalAccessException ignored) {
}
return null;
}

public boolean hasSetter(String name) {
PropertyTokenizer prop = new PropertyTokenizer(name);
if (prop.hasNext()) {
if (reflector.hasSetter(prop.getName())) {
MetaClass metaProp = metaClassForProperty(prop.getName());
return metaProp.hasSetter(prop.getChildren());
} else {
return false;
}
} else {
return reflector.hasSetter(prop.getName());
}
}

public boolean hasGetter(String name) {
PropertyTokenizer prop = new PropertyTokenizer(name);
if (prop.hasNext()) {
if (reflector.hasGetter(prop.getName())) {
MetaClass metaProp = metaClassForProperty(prop);
return metaProp.hasGetter(prop.getChildren());
} else {
return false;
}
} else {
return reflector.hasGetter(prop.getName());
}
}

public Invoker getGetInvoker(String name) {
return reflector.getGetInvoker(name);
}

public Invoker getSetInvoker(String name) {
return reflector.getSetInvoker(name);
}

/**
* @param name
* @param builder
* @return
*/
private StringBuilder buildProperty(String name, StringBuilder builder) {
// 获取name的内容 属性解析
PropertyTokenizer prop = new PropertyTokenizer(name);
if (prop.hasNext()) {
String propertyName = reflector.findPropertyName(prop.getName());
if (propertyName != null) {
builder.append(propertyName);
builder.append(".");
// 创建下级对象
MetaClass metaProp = metaClassForProperty(propertyName);
// 设置属性
metaProp.buildProperty(prop.getChildren(), builder);
}
} else {
// 查找属性
String propertyName = reflector.findPropertyName(name);
if (propertyName != null) {
// 属性添加
builder.append(propertyName);
}
}
return builder;
}

/**
* 是否存在无参数构造方法
* @return
*/
public boolean hasDefaultConstructor() {
return reflector.hasDefaultConstructor();
}

}
13 changes: 13 additions & 0 deletions docs/spring/cs2b525eb8-90df-11ef-a50a-acde48001122.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.github.huifer.ctrpluginexample.repo;

import com.github.huifer.ctrpluginexample.entity.AppEntity;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface AppRepo extends CrudRepository<AppEntity, Long> {

// 现在我拥有一个 CrudRepository的实现类,我想要获取这个实现类的Class 我应该怎么操作

}
137 changes: 137 additions & 0 deletions docs/spring/cs2b750eea-90df-11ef-a50a-acde48001122.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
/**
* Copyright 2009-2019 the original author or authors.
* <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 org.apache.ibatis.executor.resultset;

import org.apache.ibatis.builder.StaticSqlSource;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.executor.ExecutorException;
import org.apache.ibatis.executor.parameter.ParameterHandler;
import org.apache.ibatis.mapping.*;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;
import org.apache.ibatis.type.TypeHandler;
import org.apache.ibatis.type.TypeHandlerRegistry;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;

import java.sql.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

@ExtendWith(MockitoExtension.class)
class DefaultResultSetHandlerTest {

@Mock
private Statement stmt;
@Mock
private ResultSet rs;
@Mock
private ResultSetMetaData rsmd;
@Mock
private Connection conn;
@Mock
private DatabaseMetaData dbmd;

/**
* Contrary to the spec, some drivers require case-sensitive column names when getting result.
*
* @see <a href="http://code.google.com/p/mybatis/issues/detail?id=557">Issue 557</a>
*/
@Test
void shouldRetainColumnNameCase() throws Exception {

final MappedStatement ms = getMappedStatement();

final Executor executor = null;
final ParameterHandler parameterHandler = null;
final ResultHandler resultHandler = null;
final BoundSql boundSql = null;
final RowBounds rowBounds = new RowBounds(0, 100);
final DefaultResultSetHandler fastResultSetHandler = new DefaultResultSetHandler(executor, ms, parameterHandler, resultHandler, boundSql, rowBounds);

when(stmt.getResultSet()).thenReturn(rs);
when(rs.getMetaData()).thenReturn(rsmd);
when(rs.getType()).thenReturn(ResultSet.TYPE_FORWARD_ONLY);
when(rs.next()).thenReturn(true).thenReturn(false);
when(rs.getInt("CoLuMn1")).thenReturn(100);
when(rsmd.getColumnCount()).thenReturn(1);
when(rsmd.getColumnLabel(1)).thenReturn("CoLuMn1");
when(rsmd.getColumnType(1)).thenReturn(Types.INTEGER);
when(rsmd.getColumnClassName(1)).thenReturn(Integer.class.getCanonicalName());
when(stmt.getConnection()).thenReturn(conn);
when(conn.getMetaData()).thenReturn(dbmd);
when(dbmd.supportsMultipleResultSets()).thenReturn(false); // for simplicity.

final List<Object> results = fastResultSetHandler.handleResultSets(stmt);
assertEquals(1, results.size());
assertEquals(100, ((HashMap) results.get(0)).get("cOlUmN1"));
}

@Test
void shouldThrowExceptionWithColumnName() throws Exception {
final MappedStatement ms = getMappedStatement();
final RowBounds rowBounds = new RowBounds(0, 100);

final DefaultResultSetHandler defaultResultSetHandler = new DefaultResultSetHandler(null/*executor*/, ms,
null/*parameterHandler*/, null/*resultHandler*/, null/*boundSql*/, rowBounds);

final ResultSetWrapper rsw = mock(ResultSetWrapper.class);
when(rsw.getResultSet()).thenReturn(mock(ResultSet.class));

final ResultMapping resultMapping = mock(ResultMapping.class);
final TypeHandler typeHandler = mock(TypeHandler.class);
when(resultMapping.getColumn()).thenReturn("column");
when(resultMapping.getTypeHandler()).thenReturn(typeHandler);
when(typeHandler.getResult(any(ResultSet.class), any(String.class))).thenThrow(new SQLException("exception"));
List<ResultMapping> constructorMappings = Collections.singletonList(resultMapping);

try {
defaultResultSetHandler.createParameterizedResultObject(rsw, null/*resultType*/, constructorMappings,
null/*constructorArgTypes*/, null/*constructorArgs*/, null/*columnPrefix*/);
Assertions.fail("Should have thrown ExecutorException");
} catch (Exception e) {
Assertions.assertTrue(e instanceof ExecutorException, "Expected ExecutorException");
Assertions.assertTrue(e.getMessage().contains("mapping: " + resultMapping.toString()));
}
}

MappedStatement getMappedStatement() {
final Configuration config = new Configuration();
final TypeHandlerRegistry registry = config.getTypeHandlerRegistry();
return new MappedStatement.Builder(config, "testSelect", new StaticSqlSource(config, "some select statement"), SqlCommandType.SELECT).resultMaps(
new ArrayList<ResultMap>() {
{
add(new ResultMap.Builder(config, "testMap", HashMap.class, new ArrayList<ResultMapping>() {
{
add(new ResultMapping.Builder(config, "cOlUmN1", "CoLuMn1", registry.getTypeHandler(Integer.class)).build());
}
}).build());
}
}).build();
}

}

0 comments on commit 58af292

Please sign in to comment.