- 浏览: 984500 次
文章分类
- 全部博客 (428)
- Hadoop (2)
- HBase (1)
- ELK (1)
- ActiveMQ (13)
- Kafka (5)
- Redis (14)
- Dubbo (1)
- Memcached (5)
- Netty (56)
- Mina (34)
- NIO (51)
- JUC (53)
- Spring (13)
- Mybatis (17)
- MySQL (21)
- JDBC (12)
- C3P0 (5)
- Tomcat (13)
- SLF4J-log4j (9)
- P6Spy (4)
- Quartz (12)
- Zabbix (7)
- JAVA (9)
- Linux (15)
- HTML (9)
- Lucene (0)
- JS (2)
- WebService (1)
- Maven (4)
- Oracle&MSSQL (14)
- iText (11)
- Development Tools (8)
- UTILS (4)
- LIFE (8)
最新评论
-
Donald_Draper:
Donald_Draper 写道刘落落cici 写道能给我发一 ...
DatagramChannelImpl 解析三(多播) -
Donald_Draper:
刘落落cici 写道能给我发一份这个类的源码吗Datagram ...
DatagramChannelImpl 解析三(多播) -
lyfyouyun:
请问楼主,执行消息发送的时候,报错:Transport sch ...
ActiveMQ连接工厂、连接详解 -
ezlhq:
关于 PollArrayWrapper 状态含义猜测:参考 S ...
WindowsSelectorImpl解析一(FdMap,PollArrayWrapper) -
flyfeifei66:
打算使用xmemcache作为memcache的客户端,由于x ...
Memcached分布式客户端(Xmemcached)
SqlSessionFactory初始化:http://donald-draper.iteye.com/2331917
Mybatis加载解析Mapper(xml)文件第一讲:http://donald-draper.iteye.com/blog/2333125
Mybatis加载解析Mapper(xml)文件第二讲:http://donald-draper.iteye.com/blog/2333191
Mybatis 解析Mapper(class):http://donald-draper.iteye.com/blog/2333293
Mybatis的Environment解析详解:http://donald-draper.iteye.com/blog/2334133
mybatis 动态标签语句的解析(BoundSql):http://donald-draper.iteye.com/blog/2334135
在我们前面几篇文章中,经常出现一个类为MetaObject,今天我们就来看看,MetaObject的作用在讲Environments解析的时候有这么一段代码,设置数据源的属性
我们可以看到有这么几句代码
来看一下SystemMetaObject
从上面的SystemMetaObject,我们可以看出,SystemMetaObject返回对象的MetaObject对象,实际上通过的MetaObject的forObject方法。
//Sql包装类
在Sql包装类,我们可以看到一下几句代码:
下面来看MetaObject
//MetaObject,设置Class实例属性
下面我们先来看forObject方法
从MetaObject的forObject方法,我们可以看出,实际上,MetaObject的构造函数
MetaObject(Object object, ObjectFactory objectFactory, ObjectWrapperFactory objectWrapperFactory)是把原始Obejct包装成ObjectWrapper(ObjectWrapper,MapWrapper,CollectionWrapper,BeanWrapper),
如果ObjectWrapperFactory已经包装了Object,则通过ObjectWrapperFactory的 getWrapperFor(MetaObject metaObject, Object object)返回相应的ObjectWrapper。
在来看获取属性值方法,这里我们来看BeanWrapper
//BeanWrapper
//MetaClass
//Reflector
回到MetaObject,再看获取属性get与setName的属性
再看BeanWrapper的相应方法,并委托给MetaClass对应方法
//BeanWrapper
// MetaClass对应方法委托给Reflector
再看Reflector
实际上返回的是可读与可写属性名字符串组;
回到MetaObject,再看获取对象属性name对应的值
//BeanWrapper
通过MetaClass获取属性对应的get方法,调用相应的方法
//BaseWrapper
// MetaClass的获取属性的Get方法,委托给Reflector
再看Reflector
从get方法Map中,获取对应的Invoker
回到MetaObject,再看给对象属性name设置value值
//BeanWrapper
//获取bean属性对应的set方法,并设置
// MetaClass,获取set方法,委托给Reflector
总结:
从上面可以看出,MetaObject是用于包装Object的,将Object包装成ObjectWrapper,MapWrapper,CollectionWrapper,BeanWrapper等,ObjectWrapper是对应属性及方法的一个包装类,MetaObject获取obejct的属性值,以及给属性设置,是委托给
ObjectWrapper,ObjectWrapper在委托给MetaClass,MetaClass最后交Reflector;Reflector包含Obejct的属性名,set方法,以及get方法的描述,MetaObject获取属性值和设置属性值方法,本质上是,从Reflector获取属性对应方法的Invoker,然后invoke。下面一节,我们讲Reflector。
//PropertyTokenizer
Mybatis加载解析Mapper(xml)文件第一讲:http://donald-draper.iteye.com/blog/2333125
Mybatis加载解析Mapper(xml)文件第二讲:http://donald-draper.iteye.com/blog/2333191
Mybatis 解析Mapper(class):http://donald-draper.iteye.com/blog/2333293
Mybatis的Environment解析详解:http://donald-draper.iteye.com/blog/2334133
mybatis 动态标签语句的解析(BoundSql):http://donald-draper.iteye.com/blog/2334135
在我们前面几篇文章中,经常出现一个类为MetaObject,今天我们就来看看,MetaObject的作用在讲Environments解析的时候有这么一段代码,设置数据源的属性
public void setProperties(Properties properties) { Properties driverProperties = new Properties(); //获取dataSource的对象描述 MetaObject metaDataSource = SystemMetaObject.forObject(dataSource); //获取dataSource的所有属性,并设置 for(Iterator i$ = properties.keySet().iterator(); i$.hasNext();) { Object key = i$.next(); String propertyName = (String)key; if(propertyName.startsWith("driver.")) { String value = properties.getProperty(propertyName); driverProperties.setProperty(propertyName.substring(DRIVER_PROPERTY_PREFIX_LENGTH), value); } else if(metaDataSource.hasSetter(propertyName)) { String value = (String)properties.get(propertyName); Object convertedValue = convertValue(metaDataSource, propertyName, value); metaDataSource.setValue(propertyName, convertedValue); } } //设置metaDataSource的driverProperties属性 if(driverProperties.size() > 0) metaDataSource.setValue("driverProperties", driverProperties); }
我们可以看到有这么几句代码
MetaObject metaDataSource = SystemMetaObject.forObject(dataSource); metaDataSource.hasSetter(propertyName) metaDataSource.setValue("driverProperties", driverProperties);
来看一下SystemMetaObject
public class SystemMetaObject { public static final ObjectFactory DEFAULT_OBJECT_FACTORY; public static final ObjectWrapperFactory DEFAULT_OBJECT_WRAPPER_FACTORY; public static final MetaObject NULL_META_OBJECT; private static class NullObject { private NullObject() { } } public static MetaObject forObject(Object object) { return MetaObject.forObject(object, DEFAULT_OBJECT_FACTORY, DEFAULT_OBJECT_WRAPPER_FACTORY); } static { DEFAULT_OBJECT_FACTORY = new DefaultObjectFactory(); DEFAULT_OBJECT_WRAPPER_FACTORY = new DefaultObjectWrapperFactory(); NULL_META_OBJECT = MetaObject.forObject(org/apache/ibatis/reflection/SystemMetaObject$NullObject, DEFAULT_OBJECT_FACTORY, DEFAULT_OBJECT_WRAPPER_FACTORY); } }
从上面的SystemMetaObject,我们可以看出,SystemMetaObject返回对象的MetaObject对象,实际上通过的MetaObject的forObject方法。
//Sql包装类
public class BoundSql { public BoundSql(Configuration configuration, String sql, List parameterMappings, Object parameterObject) { this.sql = sql; this.parameterMappings = parameterMappings; this.parameterObject = parameterObject; additionalParameters = new HashMap(); metaParameters = configuration.newMetaObject(additionalParameters); } private String sql; private List parameterMappings; private Object parameterObject; private Map additionalParameters; private MetaObject metaParameters; }
在Sql包装类,我们可以看到一下几句代码:
metaParameters = configuration.newMetaObject(additionalParameters); //Configuration新建MetaObject对象 public MetaObject newMetaObject(Object object) { return MetaObject.forObject(object, objectFactory, objectWrapperFactory); }
下面来看MetaObject
//MetaObject,设置Class实例属性
public class MetaObject { private Object originalObject;//原始Obeject private ObjectWrapper objectWrapper;//包装后的Object private ObjectFactory objectFactory; private ObjectWrapperFactory objectWrapperFactory; private MetaObject(Object object, ObjectFactory objectFactory, ObjectWrapperFactory objectWrapperFactory) { originalObject = object; this.objectFactory = objectFactory; this.objectWrapperFactory = objectWrapperFactory; if(object instanceof ObjectWrapper) objectWrapper = (ObjectWrapper)object; else //如果对应objectWrapperFactory中存在,则返回object if(objectWrapperFactory.hasWrapperFor(object)) objectWrapper = objectWrapperFactory.getWrapperFor(this, object); else if(object instanceof Map) //Map objectWrapper = new MapWrapper(this, (Map)object); else if(object instanceof Collection) //List objectWrapper = new CollectionWrapper(this, (Collection)object); else //bean objectWrapper = new BeanWrapper(this, object); } //构造MetaObject public static MetaObject forObject(Object object, ObjectFactory objectFactory, ObjectWrapperFactory objectWrapperFactory) { if(object == null) return SystemMetaObject.NULL_META_OBJECT; else return new MetaObject(object, objectFactory, objectWrapperFactory); } public String findProperty(String propName, boolean useCamelCaseMapping) { return objectWrapper.findProperty(propName, useCamelCaseMapping); } //获取可读属性名 public String[] getGetterNames() { return objectWrapper.getGetterNames(); } //获取可写属性名 public String[] getSetterNames() { return objectWrapper.getSetterNames(); } //获取对象属性name对应的值 public Object getValue(String name) { PropertyTokenizer prop = new PropertyTokenizer(name); if(prop.hasNext()) { MetaObject metaValue = metaObjectForProperty(prop.getIndexedName()); if(metaValue == SystemMetaObject.NULL_META_OBJECT) return null; else return metaValue.getValue(prop.getChildren()); } else { return objectWrapper.get(prop); } } //给对象属性name设置value值 public void setValue(String name, Object value) { PropertyTokenizer prop = new PropertyTokenizer(name); if(prop.hasNext()) { MetaObject metaValue = metaObjectForProperty(prop.getIndexedName()); if(metaValue == SystemMetaObject.NULL_META_OBJECT) { if(value == null && prop.getChildren() != null) return; metaValue = objectWrapper.instantiatePropertyValue(name, prop, objectFactory); } metaValue.setValue(prop.getChildren(), value); } else { objectWrapper.set(prop, value); } } }
下面我们先来看forObject方法
private MetaObject(Object object, ObjectFactory objectFactory, ObjectWrapperFactory objectWrapperFactory) { originalObject = object; this.objectFactory = objectFactory; this.objectWrapperFactory = objectWrapperFactory; if(object instanceof ObjectWrapper) objectWrapper = (ObjectWrapper)object; else //如果对应objectWrapperFactory中存在,则返回object if(objectWrapperFactory.hasWrapperFor(object)) objectWrapper = objectWrapperFactory.getWrapperFor(this, object); else if(object instanceof Map) //Map objectWrapper = new MapWrapper(this, (Map)object); else if(object instanceof Collection) //List objectWrapper = new CollectionWrapper(this, (Collection)object); else //bean objectWrapper = new BeanWrapper(this, object); } //构造MetaObject public static MetaObject forObject(Object object, ObjectFactory objectFactory, ObjectWrapperFactory objectWrapperFactory) { if(object == null) return SystemMetaObject.NULL_META_OBJECT; else return new MetaObject(object, objectFactory, objectWrapperFactory); } //DefaultObjectWrapperFactory public class DefaultObjectWrapperFactory implements ObjectWrapperFactory { public boolean hasWrapperFor(Object object) { return false; } public ObjectWrapper getWrapperFor(MetaObject metaObject, Object object) { throw new RuntimeException("The DefaultObjectWrapperFactory should never be called to provide an ObjectWrapper."); } }
从MetaObject的forObject方法,我们可以看出,实际上,MetaObject的构造函数
MetaObject(Object object, ObjectFactory objectFactory, ObjectWrapperFactory objectWrapperFactory)是把原始Obejct包装成ObjectWrapper(ObjectWrapper,MapWrapper,CollectionWrapper,BeanWrapper),
如果ObjectWrapperFactory已经包装了Object,则通过ObjectWrapperFactory的 getWrapperFor(MetaObject metaObject, Object object)返回相应的ObjectWrapper。
在来看获取属性值方法,这里我们来看BeanWrapper
public String findProperty(String propName, boolean useCamelCaseMapping) { return objectWrapper.findProperty(propName, useCamelCaseMapping); }
//BeanWrapper
public class BeanWrapper extends BaseWrapper { private Object object; private MetaClass metaClass;//Object对应的Class public BeanWrapper(MetaObject metaObject, Object object) { super(metaObject); this.object = object; metaClass = MetaClass.forClass(object.getClass()); } //获取属性name对应的属性名 public String findProperty(String name, boolean useCamelCaseMapping) { return metaClass.findProperty(name, useCamelCaseMapping); } }
//MetaClass
public class MetaClass { private Reflector reflector; public static MetaClass forClass(Class type) { return new MetaClass(type); } private MetaClass(Class type) { //获取type类型对应的Reflector reflector = Reflector.forClass(type); } //获取name对应的属性名,useCamelCaseMapping是否是驼峰命名 public String findProperty(String name, boolean useCamelCaseMapping) { if(useCamelCaseMapping) name = name.replace("_", ""); return findProperty(name); } public String findProperty(String name) { StringBuilder prop = buildProperty(name, new StringBuilder()); return prop.length() <= 0 ? null : prop.toString(); } private StringBuilder buildProperty(String name, StringBuilder builder) { 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; } }
//Reflector
public class Reflector { private static boolean classCacheEnabled = true; private static final String EMPTY_STRING_ARRAY[] = new String[0]; private static final Map REFLECTOR_MAP = new ConcurrentHashMap(); private Class type; private String readablePropertyNames[]; private String writeablePropertyNames[]; private Map setMethods; private Map getMethods; private Map setTypes; private Map getTypes; private Constructor defaultConstructor; private Map caseInsensitivePropertyMap; //构造Class对应的Reflector public static Reflector forClass(Class clazz) { if(classCacheEnabled) { //如果缓存状态开启,则从REFLECTOR_MAP获取对应的Reflector,没有则重新构建 Reflector cached = (Reflector)REFLECTOR_MAP.get(clazz); if(cached == null) { cached = new Reflector(clazz); REFLECTOR_MAP.put(clazz, cached); } return cached; } else { return new Reflector(clazz); } } private Reflector(Class clazz) { readablePropertyNames = EMPTY_STRING_ARRAY;//可读属性名 writeablePropertyNames = EMPTY_STRING_ARRAY;//可写属性名 setMethods = new HashMap();//Set方法Map getMethods = new HashMap();//Get方法Map setTypes = new HashMap(); getTypes = new HashMap(); caseInsensitivePropertyMap = new HashMap();//大小写不敏感属性Map type = clazz; addDefaultConstructor(clazz); addGetMethods(clazz); addSetMethods(clazz); addFields(clazz); readablePropertyNames = (String[])getMethods.keySet().toArray(new String[getMethods.keySet().size()]); writeablePropertyNames = (String[])setMethods.keySet().toArray(new String[setMethods.keySet().size()]); //将可读属性添加大小写不敏感属性Map String arr$[] = readablePropertyNames; int len$ = arr$.length; for(int i$ = 0; i$ < len$; i$++) { String propName = arr$[i$]; caseInsensitivePropertyMap.put(propName.toUpperCase(Locale.ENGLISH), propName); } //将可写属性添加大小写不敏感属性Map arr$ = writeablePropertyNames; len$ = arr$.length; for(int i$ = 0; i$ < len$; i$++) { String propName = arr$[i$]; caseInsensitivePropertyMap.put(propName.toUpperCase(Locale.ENGLISH), propName); } } public String findPropertyName(String name) { return (String)caseInsensitivePropertyMap.get(name.toUpperCase(Locale.ENGLISH)); } }
回到MetaObject,再看获取属性get与setName的属性
public String[] getGetterNames() { return objectWrapper.getGetterNames(); } public String[] getSetterNames() { return objectWrapper.getSetterNames(); }
再看BeanWrapper的相应方法,并委托给MetaClass对应方法
//BeanWrapper
public String[] getGetterNames() { return metaClass.getGetterNames(); } public String[] getSetterNames() { return metaClass.getSetterNames(); }
// MetaClass对应方法委托给Reflector
public String[] getGetterNames() { return reflector.getGetablePropertyNames(); } public String[] getSetterNames() { return reflector.getSetablePropertyNames(); }
再看Reflector
public String[] getGetablePropertyNames() { return readablePropertyNames; } public String[] getSetablePropertyNames() { return writeablePropertyNames; }
实际上返回的是可读与可写属性名字符串组;
回到MetaObject,再看获取对象属性name对应的值
public Object getValue(String name) { PropertyTokenizer prop = new PropertyTokenizer(name); if(prop.hasNext()) { MetaObject metaValue = metaObjectForProperty(prop.getIndexedName()); if(metaValue == SystemMetaObject.NULL_META_OBJECT) return null; else return metaValue.getValue(prop.getChildren()); } else { return objectWrapper.get(prop); } }
//BeanWrapper
public Object get(PropertyTokenizer prop) { if(prop.getIndex() != null) { Object collection = resolveCollection(prop, object); return getCollectionValue(prop, collection); } else { //获取bean对应的属性 return getBeanProperty(prop, object); } }
通过MetaClass获取属性对应的get方法,调用相应的方法
private Object getBeanProperty(PropertyTokenizer prop, Object object) { Invoker method = metaClass.getGetInvoker(prop.getName()); return method.invoke(object, NO_ARGUMENTS); throw ExceptionUtil.unwrapThrowable(t); throw new ReflectionException((new StringBuilder()).append("Could not get property '").append(prop.getName()).append("' from ").append(object.getClass()).append(". Cause: ").append(t.toString()).toString(), t); }
//BaseWrapper
protected Object getCollectionValue(PropertyTokenizer prop, Object collection) { if(collection instanceof Map) return ((Map)collection).get(prop.getIndex()); int i = Integer.parseInt(prop.getIndex()); if(collection instanceof List) return ((List)collection).get(i); if(collection instanceof Object[]) return ((Object[])(Object[])collection)[i]; if(collection instanceof char[]) return Character.valueOf(((char[])(char[])collection)[i]); if(collection instanceof boolean[]) return Boolean.valueOf(((boolean[])(boolean[])collection)[i]); if(collection instanceof byte[]) return Byte.valueOf(((byte[])(byte[])collection)[i]); if(collection instanceof double[]) return Double.valueOf(((double[])(double[])collection)[i]); if(collection instanceof float[]) return Float.valueOf(((float[])(float[])collection)[i]); if(collection instanceof int[]) return Integer.valueOf(((int[])(int[])collection)[i]); if(collection instanceof long[]) return Long.valueOf(((long[])(long[])collection)[i]); if(collection instanceof short[]) return Short.valueOf(((short[])(short[])collection)[i]); else throw new ReflectionException((new StringBuilder()).append("The '").append(prop.getName()).append("' property of ").append(collection).append(" is not a List or Array.").toString()); }
// MetaClass的获取属性的Get方法,委托给Reflector
public Invoker getGetInvoker(String name) { return reflector.getGetInvoker(name); }
再看Reflector
从get方法Map中,获取对应的Invoker
public Invoker getGetInvoker(String propertyName) { Invoker method = (Invoker)getMethods.get(propertyName); if(method == null) throw new ReflectionException((new StringBuilder()).append("There is no getter for property named '").append(propertyName).append("' in '").append(type).append("'").toString()); else return method; }
回到MetaObject,再看给对象属性name设置value值
public void setValue(String name, Object value) { PropertyTokenizer prop = new PropertyTokenizer(name); if(prop.hasNext()) { MetaObject metaValue = metaObjectForProperty(prop.getIndexedName()); if(metaValue == SystemMetaObject.NULL_META_OBJECT) { if(value == null && prop.getChildren() != null) return; metaValue = objectWrapper.instantiatePropertyValue(name, prop, objectFactory); } metaValue.setValue(prop.getChildren(), value); } else { objectWrapper.set(prop, value); } }
//BeanWrapper
public void set(PropertyTokenizer prop, Object value) { if(prop.getIndex() != null) { Object collection = resolveCollection(prop, object); setCollectionValue(prop, collection, value); } else { //设置bean属性 setBeanProperty(prop, object, value); } }
//获取bean属性对应的set方法,并设置
private void setBeanProperty(PropertyTokenizer prop, Object object, Object value) { try { Invoker method = metaClass.getSetInvoker(prop.getName()); Object params[] = { value }; try { method.invoke(object, params); } } }
// MetaClass,获取set方法,委托给Reflector
public Invoker getSetInvoker(String name) { return reflector.getSetInvoker(name); } 再看Reflector,从setMethods方法Map中,获取Invoker public Invoker getSetInvoker(String propertyName) { Invoker method = (Invoker)setMethods.get(propertyName); if(method == null) throw new ReflectionException((new StringBuilder()).append("There is no setter for property named '").append(propertyName).append("' in '").append(type).append("'").toString()); else return method; }
总结:
从上面可以看出,MetaObject是用于包装Object的,将Object包装成ObjectWrapper,MapWrapper,CollectionWrapper,BeanWrapper等,ObjectWrapper是对应属性及方法的一个包装类,MetaObject获取obejct的属性值,以及给属性设置,是委托给
ObjectWrapper,ObjectWrapper在委托给MetaClass,MetaClass最后交Reflector;Reflector包含Obejct的属性名,set方法,以及get方法的描述,MetaObject获取属性值和设置属性值方法,本质上是,从Reflector获取属性对应方法的Invoker,然后invoke。下面一节,我们讲Reflector。
//PropertyTokenizer
public class PropertyTokenizer implements Iterable, Iterator { private String name; private String indexedName; private String index; private String children; public PropertyTokenizer(String fullname) { int delim = fullname.indexOf('.'); if(delim > -1) { name = fullname.substring(0, delim); children = fullname.substring(delim + 1); } else { name = fullname; children = null; } indexedName = name; delim = name.indexOf('['); if(delim > -1) { index = name.substring(delim + 1, name.length() - 1); name = name.substring(0, delim); } } public String getName() { return name; } public String getIndex() { return index; } public String getIndexedName() { return indexedName; } public String getChildren() { return children; } public boolean hasNext() { return children != null; } public PropertyTokenizer next() { return new PropertyTokenizer(children); } public void remove() { throw new UnsupportedOperationException("Remove is not supported, as it has no meaning in the context of properties."); } public Iterator iterator() { return this; } public volatile Object next() { return next(); } }
发表评论
-
Mybatis缓存实现
2016-12-07 10:36 983SqlSessionFactory初始化:http://don ... -
DefaultSqlSession第三讲-事务提交,回滚,关闭SqlSession,清除缓存
2016-11-20 11:07 5714上面两篇讲过query和update及flushStateme ... -
DefaultSqlSession第二讲-更新,刷新Statement
2016-11-20 11:06 635上一篇文章中,我们讲到DefaultSqlSession的查询 ... -
DefaultSqlSession第一讲query解析
2016-11-20 11:06 1631上一篇文章:我们说过DefaultSqlSession,Def ... -
Mybatis的SqlSession解析
2016-11-20 11:02 2566在前文中,Mybatis使用教程中,有下面一段代码: Sql ... -
Mybatis的Reflector解析
2016-11-18 12:53 2165Mybatis的MetaObject解析:http://don ... -
mybatis 动态标签语句的解析(BoundSql)
2016-10-30 09:48 5765SqlSessionFactory初始化:http://don ... -
Mybatis的Environment解析详解
2016-10-29 18:28 1998SqlSessionFactory初始化:http://don ... -
Mybatis 解析Mapper(class)
2016-10-26 11:44 3365SqlSessionFactory初始化:http://don ... -
Mybatis加载解析Mapper(xml)文件第二讲
2016-10-25 21:30 4805SqlSessionFactory初始化:http://don ... -
Mybatis加载解析Mapper(xml)文件第一讲
2016-10-25 16:51 6199SqlSessionFactory初始化:http://don ... -
SqlSessionFactory初始化
2016-10-20 15:38 2460mybatis 使用教程:http://donald-drap ... -
mybatis 使用教程
2016-10-14 09:03 914Myeclispe下mybatis generator的使 ... -
Spring+Mybatis多数据源的实现
2016-09-21 18:15 3095浅谈Spring事务隔离级别:http://www.cnblo ... -
mybaitis CDATA 防止字符被解析
2016-08-17 18:45 727在使用mybatis 时我们sql是写在xml 映射文件中,如 ... -
Myeclispe下mybatis generator的使用
2016-07-05 18:05 1379准备:下载附件包解压到myeclispe的dropins文件夹 ...
相关推荐
MetaObject 是 MyBatis 中的元对象,该对象负责将 Java 对象转换成 SQL 语句中可用的类型。 3.8 对象工厂 对象工厂是 MyBatis 中的核心对象之一,该对象负责将 Java 对象转换成 SQL 语句中可用的类型。 3.13 ...
Mybatis提供了一个名为`MetaObject`的工具类,可以帮助我们方便地完成这些操作。例如,可以使用`MetaObject`来获取和修改`ResultSetHandler`的某些属性。 ```java MetaObject metaObject = MetaObject.forObject...
下面我们将深入探讨MyBatis中的反射组件,包括MetaClass、ObjectWrapper和MetaObject这三个模块。 首先,让我们了解什么是反射。在Java中,反射是一种强大的机制,它允许程序在运行时检查和修改自身的行为。通过...
`MetaObject`是Mybatis提供的一个工具类,用于方便地访问和修改对象的私有属性,即使没有getter和setter方法。它支持使用OGNL表达式来获取和设置属性值。在分页插件中,`MetaObject`被用来遍历和操作`...
public String handler(String tableName, MetaObject metaObject) { // 获取当前租户ID,这里假设是从请求上下文中获取 String tenantId = getCurrentTenantId(); // 根据租户ID生成表名,如 "table_" + ...
- 如果参数对象是一个复杂的对象,则通过MetaObject获取其属性值。 - 如果参数对象为空,则设置参数值为null。 5. **类型处理**: - ParameterHandler依赖于TypeHandlerRegistry来处理不同类型的参数,确保参数...
让我们逐一解析这些框架及其在项目中的作用。 1. Maven: Maven是Apache软件基金会开发的项目管理和综合工具,它通过POM(Project Object Model)文件管理项目的依赖关系,简化构建过程。在本实例中,Maven负责...
MyBatis与Spring结合使用时,可以实现DAO(Data Access Object)层的事务管理、自动装配和SqlSessionFactory的创建,使得数据库操作更加便捷。 **集成过程** 在"maven+springmvc+mybatis"的项目中,集成这三个框架...
SpringMVC通过DispatcherServlet接收请求,利用HandlerMapping找到合适的Controller,然后调用Controller处理逻辑,最后由ViewResolver解析视图并返回给客户端。 3. **MyBatis**:MyBatis是一个优秀的持久层框架,...
通过定义POM(Project Object Model)文件,Maven可以自动下载所需的库,编译源代码,运行测试,打包项目,甚至部署到服务器。Maven的插件体系使得扩展功能变得简单,极大地方便了项目管理。 在这个"springmvc +...
MetaObjectParameterHandler,利用MetaObject系统进行参数处理。 8. **ResultSetHandler** ResultSetHandler负责处理SQL查询的结果。它将结果集转换为Java对象。DefaultResultSetHandler是默认实现,通过反射和...
然后,MyBatis是一个轻量级的ORM(Object-Relational Mapping,对象关系映射)框架,它允许开发者用Java代码直接操作数据库。在SSM整合中,MyBatis与Spring结合,可以实现SQL的动态执行和结果映射。我们需要配置...
通过使用POI,我们可以解析Excel工作簿、工作表、单元格等元素,进而提取数据或填充数据。例如,你可以使用`HSSFWorkbook`来处理.xls文件,`XSSFWorkbook`来处理.xlsx文件。 在SSM框架中,我们通常会创建一个服务层...
它为开发者提供了构建web应用程序的灵活框架,包括依赖注入(Dependency Injection, DI)、面向切面编程(Aspect-Oriented Programming, AOP)以及一系列控制器、视图解析器和模型对象的工具。Spring MVC的核心功能...
6. **META-INF**目录:虽然在这个特定的示例中可能没有具体的内容,但在Maven项目中,这个目录通常用于存放MANIFEST.MF文件,该文件包含了关于JAR包的元数据,如作者、版本等信息。 要运行这个Demo,你需要在本地...
它通过DispatcherServlet接收请求,然后利用HandlerMapping找到对应的处理器,再由ModelAndView封装数据和视图,最后由ViewResolver解析并渲染视图。这样就实现了模型-视图-控制器的设计模式,使代码结构清晰,易于...
2. **配置SpringMVC**:创建SpringMVC的配置文件,如servlet-context.xml,定义DispatcherServlet、视图解析器、拦截器等。同时,配置Controller,实现请求的映射和处理。 3. **配置MyBatis**:编写MyBatis的主配置...
在本项目中,开发者可能通过创建一个简单的数据模型(Entity),编写对应的DAO(Data Access Object)和Service,实现对数据库中数据的CRUD操作。 7. **项目构建**:SSM项目的构建通常包括以下步骤: - 创建数据库...
Spring支持多种数据库访问技术,包括JDBC、ORM(Object-Relational Mapping)框架如Hibernate和MyBatis。通过声明式事务管理,可以在不编写繁琐的事务控制代码的情况下,实现事务的正确处理。 5. **Spring Boot** ...
1. `Ognl.java`: 这个文件很可能是使用了Object-Graph Navigation Language (OGNL)库的一个实现或接口。OGNL是一种强大的表达式语言,常用于Java应用中,特别是那些基于MVC(模型-视图-控制器)架构的框架,如Struts...