/**
* Copyright 2009-2019 the original author or authors.
*
* 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 org.apache.ibatis.reflection.factory;
import java.util.List;
import java.util.Properties;
/**
* MyBatis uses an ObjectFactory to create all needed new Objects.
* 在 MyBatis 中,当其 sql 映射配置文件中的 sql 语句所得到的查询结果,
* 被动态映射到 resultType 或其他处理结果集的参数配置对应的 Java 类型,其中就有 JavaBean 等封装类
* 而 objectFactory 对象工厂就是用来创建实体对象的类。
* @author Clinton Begin
*/
public interface ObjectFactory {
/**
* 处理参数
* Sets configuration properties.
* @param properties configuration properties
*/
void setProperties(Properties properties);
/**
* 处理默认构造方法
* Creates a new object with default constructor.
* @param type Object type
* @return
*/
T create(Class type);
/**
* 处理有参构造方法
* Creates a new object with the specified constructor and params.
* @param type Object type
* @param constructorArgTypes Constructor argument types
* @param constructorArgs Constructor argument values
* @return
*/
T create(Class type, List> constructorArgTypes, List
DefaultObjectFactory
/**
* Copyright 2009-2019 the original author or authors.
*
* 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 org.apache.ibatis.reflection.factory;
import java.io.Serializable;
import java.lang.reflect.Constructor;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Properties;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;
import java.util.stream.Collectors;
import org.apache.ibatis.reflection.ReflectionException;
import org.apache.ibatis.reflection.Reflector;
/**
* 默认的ObjectFactory
*
* @author Clinton Begin
*/
public class DefaultObjectFactory implements ObjectFactory, Serializable {
private static final long serialVersionUID = -8855120656740914948L;
@Override
public T create(Class type) {
return create(type, null, null);
}
@SuppressWarnings("unchecked")
@Override
public T create(Class type, List> constructorArgTypes, List
ObjectWrapperFactory
/**
* Copyright 2009-2016 the original author or authors.
*
* 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 org.apache.ibatis.reflection.wrapper;
import org.apache.ibatis.reflection.MetaObject;
/**
* 对象包装工厂
* @author Clinton Begin
*
*/
public interface ObjectWrapperFactory {
/**
* 是否有为(参数object)进行包装
*/
boolean hasWrapperFor(Object object);
/**
* 返回类对象包装类对象
*/
ObjectWrapper getWrapperFor(MetaObject metaObject, Object object);
}
DefaultObjectWrapperFactory
/**
* Copyright 2009-2015 the original author or authors.
*
* 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 org.apache.ibatis.reflection.wrapper;
import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.reflection.ReflectionException;
/**
* 默认对象包装工厂
*
* 默认不会对对象进行包装
*
* @author Clinton Begin
*/
public class DefaultObjectWrapperFactory implements ObjectWrapperFactory {
/**
* 是否有为(参数object)进行包装
*
*/
@Override
public ObjectWrapper getWrapperFor(MetaObject metaObject, Object object) {
//默认对象包装器工厂不应该被称为对象提供一个包装器。;
throw new ReflectionException("The DefaultObjectWrapperFactory should never be called to provide an ObjectWrapper.");
}
}
ObjectWrapper
/**
* Copyright 2009-2019 the original author or authors.
*
* 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 org.apache.ibatis.reflection.wrapper;
import java.util.List;
import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.reflection.factory.ObjectFactory;
import org.apache.ibatis.reflection.property.PropertyTokenizer;
/**
*https://blog.csdn.net/weixin_34075551/article/details/91402679
* @author Clinton Begin
*/
public interface ObjectWrapper {
/**
* 获取对应(参数prop)当前类中属性对象
*/
Object get(PropertyTokenizer prop);
/**
*对 对应(参数prop)当前类中属性的对象 赋上(参数value)
*/
void set(PropertyTokenizer prop, Object value);
/**
* 查找属性并返回
* @param name 属性名
* @param useCamelCaseMapping 是否使用驼峰命名
*/
String findProperty(String name, boolean useCamelCaseMapping);
/***
* 返回类的所有get方法名
*/
String[] getGetterNames();
/**
* 返回类的所有set方法名
*/
String[] getSetterNames();
/**
* 返回对应(参数name)当前类中属性的setter方法的参数类型
*/
Class> getSetterType(String name);
/**
* 返回对应(参数name)当前类中属性的getter方法的参数类型
*/
Class> getGetterType(String name);
/**
* 是否有对应(参数name)的当前类属性的set方法
*/
boolean hasSetter(String name);
/**
* 是否有对应(参数name)的当前类属性的get方法
*/
boolean hasGetter(String name);
/**
* 实例化属性对象
*/
MetaObject instantiatePropertyValue(String name, PropertyTokenizer prop, ObjectFactory objectFactory);
/**
* 是否是集合
* @return
*/
boolean isCollection();
/**
* 添加元素
* @param element
*/
void add(Object element);
/**
* 添加元素
*/
void addAll(List element);
}
BaseWrapper
/**
* Copyright 2009-2017 the original author or authors.
*
* 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 org.apache.ibatis.reflection.wrapper;
import java.util.List;
import java.util.Map;
import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.reflection.ReflectionException;
import org.apache.ibatis.reflection.property.PropertyTokenizer;
/**
* 抽象类,实现ObjectWrapper接口
* 为子类BeanWrapper和MapWrapper提供公共的方法和属性
* @author Clinton Begin
*/
public abstract class BaseWrapper implements ObjectWrapper {
/**
* 无参
*/
protected static final Object[] NO_ARGUMENTS = new Object[0];
/**
* 当前的元类对象
*/
protected final MetaObject metaObject;
protected BaseWrapper(MetaObject metaObject) {
this.metaObject = metaObject;
}
/**
* 处理集合,根据(参数prop)获取对应属性的集合(Array、List、Map)对象,最终调用{@link MetaObject#getValue(String)}获取
*
* @param prop PropertyTokenizer 对象
* @param object 指定 Object 对象
* @return 值
*/
protected Object resolveCollection(PropertyTokenizer prop, Object object) {
if ("".equals(prop.getName())) {//这里加上prop是'[0]',那么其实可以认为他是指object本身,类似于this的用法。
return object;
} else {
return metaObject.getValue(prop.getName());
}
}
/**
* 获取在(参数collection)中对应(参数prop)的属性对象。(处理集合(Array、List、Map)
* @param prop PropertyTokenizer 对象
* @param collection 集合(Array、List、Map)
* @return 对应下标或key的值
*/
protected Object getCollectionValue(PropertyTokenizer prop, Object collection) {
if (collection instanceof Map) {
// 如果是Map类型,则index为key
return ((Map) collection).get(prop.getIndex());
} else {
// 如果是其他集合类型,则index为下标
int i = Integer.parseInt(prop.getIndex());
if (collection instanceof List) {
return ((List) collection).get(i);
} else if (collection instanceof Object[]) {
return ((Object[]) collection)[i];
} else if (collection instanceof char[]) {
return ((char[]) collection)[i];
} else if (collection instanceof boolean[]) {
return ((boolean[]) collection)[i];
} else if (collection instanceof byte[]) {
return ((byte[]) collection)[i];
} else if (collection instanceof double[]) {
return ((double[]) collection)[i];
} else if (collection instanceof float[]) {
return ((float[]) collection)[i];
} else if (collection instanceof int[]) {
return ((int[]) collection)[i];
} else if (collection instanceof long[]) {
return ((long[]) collection)[i];
} else if (collection instanceof short[]) {
return ((short[]) collection)[i];
} else {
// 不是集合对象抛ReflectionException异常
throw new ReflectionException("The '" + prop.getName() + "' property of " + collection + " is not a List or Array.");
}
}
}
/**
* 获取在(参数collection)中对应(参数prop)的属性对象,并对象赋上(参数value),(处理集合(Array、List、Map)
* @param prop PropertyTokenizer 对象
* @param collection 集合(Array、List、Map)
* @param value 值
*/
protected void setCollectionValue(PropertyTokenizer prop, Object collection, Object value) {
if (collection instanceof Map) {
((Map) collection).put(prop.getIndex(), value);
} else {
int i = Integer.parseInt(prop.getIndex());
if (collection instanceof List) {
((List) collection).set(i, value);
} else if (collection instanceof Object[]) {
((Object[]) collection)[i] = value;
} else if (collection instanceof char[]) {
((char[]) collection)[i] = (Character) value;
} else if (collection instanceof boolean[]) {
((boolean[]) collection)[i] = (Boolean) value;
} else if (collection instanceof byte[]) {
((byte[]) collection)[i] = (Byte) value;
} else if (collection instanceof double[]) {
((double[]) collection)[i] = (Double) value;
} else if (collection instanceof float[]) {
((float[]) collection)[i] = (Float) value;
} else if (collection instanceof int[]) {
((int[]) collection)[i] = (Integer) value;
} else if (collection instanceof long[]) {
((long[]) collection)[i] = (Long) value;
} else if (collection instanceof short[]) {
((short[]) collection)[i] = (Short) value;
} else {
throw new ReflectionException("The '" + prop.getName() + "' property of " + collection + " is not a List or Array.");
}
}
}
}
BeanWrapper
/**
* Copyright 2009-2017 the original author or authors.
*
* 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 org.apache.ibatis.reflection.wrapper;
import java.util.List;
import org.apache.ibatis.reflection.*;
import org.apache.ibatis.reflection.factory.ObjectFactory;
import org.apache.ibatis.reflection.invoker.Invoker;
import org.apache.ibatis.reflection.property.PropertyTokenizer;
/**
* 普通Java类包装
* @author Clinton Begin
*/
public class BeanWrapper extends BaseWrapper {
/**
* 当前的类对象
*/
private final Object object;
/**
* 当前元类
*/
private final MetaClass metaClass;
public BeanWrapper(MetaObject metaObject, Object object) {
super(metaObject);
this.object = object;
this.metaClass = MetaClass.forClass(object.getClass(), metaObject.getReflectorFactory());
}
/**
* 假设是prop是order[0],prop的index!=null,调用resolveCollection(prop,object)方法:resolveCollection(prop,object)里
* 又会重新调用MetaObject.getValue(String)方法,String参数值为order。MetaObject.getValue(String)又会调用BeanWrapper.
* get(PropertyTokenizer),此时PropertyTokenizer的参数为order,这个时候PropertyTokenizer的index为空,就会调用
* getBeanProperty(PropertyTokenizer,Object)获取object的order属性的getter方法的返回值,此时resolveCollection(prop,object)
* 方法就执行完了,返回结果就是取当前对象object的order属性的getter方法的返回值,再简单的说就是当前对象object中的order属性的对象,再调用
* getCollectionValue(PropertyTokenizer,Object),这里的PropertyTokenizer参数为'order[0]',index='0',name='order',
* Object参数是当前对象object中的order属性的对象,getCollectionValue(PropertyTokenizer,Object)方法会,将order对象
* 转换成成Map,或者集合,或者数组(前提是order对象时能转换成Map,或者集合,或者数组,否则会抛出异常),然后以'order[0]'的index
* 作为数组下班取其元素并返回给get(PropertyTokenizer)方法,get(PropertyTokenizer)返回其结果出去。
* 此时以prop为’order[0]‘为参数的get(PropertyTokenizer)方法的执行程过就到此结束了。
*
*/
@Override
public Object get(PropertyTokenizer prop) {
if (prop.getIndex() != null) {
Object collection = resolveCollection(prop, object);
return getCollectionValue(prop, collection);
} else {
return getBeanProperty(prop, object);
}
}
/**
* 对对应(参数prop)的当前类对象object的属性附上(参数value)的值
*
*
* @param object 带有对应与prop.getName的返回值的属性名,一般是当前对象
* @param value 对应属性的值、对象
*/
private void setBeanProperty(PropertyTokenizer prop, Object object, Object value) {
try {
Invoker method = metaClass.getSetInvoker(prop.getName());
Object[] params = {value};
try {
method.invoke(object, params);
} catch (Throwable t) {
throw ExceptionUtil.unwrapThrowable(t);
}
} catch (Throwable t) {
throw new ReflectionException("Could not set property '" + prop.getName() + "' of '" + object.getClass() + "' with value '" + value + "' Cause: " + t.toString(), t);
}
}
/**
* 普通Java类不可能是集合,永远返回false
*/
@Override
public boolean isCollection() {
return false;
}
/**
* 普通Java类并不知add方法,会抛出异常
*/
@Override
public void add(Object element) {
throw new UnsupportedOperationException();
}
/**
* 普通Java类并不知addAll方法,会抛出异常
*/
@Override
public void addAll(List list) {
throw new UnsupportedOperationException();
}
}
MapWrapper
/**
* Copyright 2009-2018 the original author or authors.
*
* 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 org.apache.ibatis.reflection.wrapper;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.reflection.ReflectorFactory;
import org.apache.ibatis.reflection.SystemMetaObject;
import org.apache.ibatis.reflection.factory.ObjectFactory;
import org.apache.ibatis.reflection.property.PropertyTokenizer;
/**
* Map包装类
*
* 对Map对象进行包装
*
*
* @author Clinton Begin
*/
public class MapWrapper extends BaseWrapper {
private final Map map;
public MapWrapper(MetaObject metaObject, Map map) {
super(metaObject);
this.map = map;
}
/**
* 获取对应(参数prop)当前类中属性的对象
*
*/
@Override
public MetaObject instantiatePropertyValue(String name, PropertyTokenizer prop, ObjectFactory objectFactory) {
HashMap map = new HashMap<>();
set(prop, map);
return MetaObject.forObject(map, metaObject.getObjectFactory(), metaObject.getObjectWrapperFactory(), metaObject.getReflectorFactory());
}
/**
* Map肯定不是集合,所以写死返回false
*/
@Override
public boolean isCollection() {
return false;
}
/**
* Map肯定不存在集合的添加方法,所以这里一旦调用就会抛出异常
*/
@Override
public void add(Object element) {
throw new UnsupportedOperationException();
}
/**
* Map肯定不存在集合的添加方法,所以这里一旦调用就会抛出异常
*/
@Override
public void addAll(List element) {
throw new UnsupportedOperationException();
}
}
CollectionWrapper
/**
* Copyright 2009-2017 the original author or authors.
*
* 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 org.apache.ibatis.reflection.wrapper;
import java.util.Collection;
import java.util.List;
import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.reflection.factory.ObjectFactory;
import org.apache.ibatis.reflection.property.PropertyTokenizer;
/**
* 集合包装类,这里注意了,除了isCollection(),add(Object),addAll(List)以外,调用其他方法都会抛出UnsupportedOperationException
* @author Clinton Begin
*/
public class CollectionWrapper implements ObjectWrapper {
private final Collection object;
public CollectionWrapper(MetaObject metaObject, Collection object) {
this.object = object;
}
@Override
public Object get(PropertyTokenizer prop) {
throw new UnsupportedOperationException();
}
@Override
public void set(PropertyTokenizer prop, Object value) {
throw new UnsupportedOperationException();
}
@Override
public String findProperty(String name, boolean useCamelCaseMapping) {
throw new UnsupportedOperationException();
}
@Override
public String[] getGetterNames() {
throw new UnsupportedOperationException();
}
@Override
public String[] getSetterNames() {
throw new UnsupportedOperationException();
}
@Override
public Class> getSetterType(String name) {
throw new UnsupportedOperationException();
}
@Override
public Class> getGetterType(String name) {
throw new UnsupportedOperationException();
}
@Override
public boolean hasSetter(String name) {
throw new UnsupportedOperationException();
}
@Override
public boolean hasGetter(String name) {
throw new UnsupportedOperationException();
}
@Override
public MetaObject instantiatePropertyValue(String name, PropertyTokenizer prop, ObjectFactory objectFactory) {
throw new UnsupportedOperationException();
}
@Override
public boolean isCollection() {
return true;
}
@Override
public void add(Object element) {
object.add(element);
}
@Override
public void addAll(List element) {
object.addAll(element);
}
}
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml&q
// for循环的进化
// 菜鸟
for (var i = 0; i < Things.length ; i++) {
// Things[i]
}
// 老鸟
for (var i = 0, len = Things.length; i < len; i++) {
// Things[i]
}
// 大师
for (var i = Things.le
the idea is from:
http://blog.csdn.net/zhanxinhang/article/details/6731134
public class MaxSubMatrix {
/**see http://blog.csdn.net/zhanxinhang/article/details/6731134
* Q35
求一个矩阵中最大的二维
使用cordova可以很方便的在手机sdcard中读写文件。
首先需要安装cordova插件:file
命令为:
cordova plugin add org.apache.cordova.file
然后就可以读写文件了,这里我先是写入一个文件,具体的JS代码为:
var datas=null;//datas need write
var directory=&
SELECT cust_id,
SUM(price) as total
FROM orders
WHERE status = 'A'
GROUP BY cust_id
HAVING total > 250
db.orders.aggregate( [
{ $match: { status: 'A' } },
{
$group: {