mybatis java类注解式_mybatis对java自定义注解的使用——入门篇

最近在学习spring和ibatis框架。

以前在天猫实习时做过的一个小项目用到的mybatis,在其使用过程中,不加思索的用了比较原始的一种持久化方式:

在一个包中写一个DAO的接口,在另一个包里面写DAO的实现,使用sqlMapClient来从***-sql.xml中读取相应的sql。

public interfaceIBaseDaoiBatis {

Object get(String statementName);

}public class BaseDaoiBatis implementsIBaseDaoiBatis {publicObject get(String statementName) {returngetSqlMapClientTemplate().queryForObject(statementName);

}

}//对应的mybatis配置文件里面的sql:

SELECT name FROM mm_test where id=#id#;

]]>

最近搭建了一个spring+ibatis的项目,发现了一种新的持久化方式:

只写一个dao的接口,在接口的方法中直接注解上用到的sql语句,觉得蛮巧妙的。借来用一下。注意,接口上方多了一个@Mapper注解。而每个方法上都是@Select() 注解,值为对应的sql。

@Mapperpublic interfaceTestDao {

@Select("select id, name, name_pinyin from mm_test; ")

ListselectAll();

@Insert("insert into mm_test(id, name) values(#{id}, #{name})")public voidinsertUser(MmTest mmtTestS);

}

那么这个@Mapper注解究竟是个什么东西,是怎么起到注解的作用的?ibatis是怎么来识别这种注解的呢?对我这个java小白来说,注解,是spring特有的东西嘛?自学java的时候好像很少接触注解啊。不过竟然有java.lang.annotation 这个包,这到底是怎么回事?

那我们先来看一下Mapper这个自定义注解的定义:

import org.springframework.stereotype.Component;import java.lang.annotation.*;

@Target({ ElementType.TYPE })

@Retention(RetentionPolicy.RUNTIME)

@Documented

@Componentpublic @interfaceMapper {

String value()default "";

}

关于自定义注解:(查的别人的博客:http://www.cnblogs.com/mandroid/archive/2011/07/18/2109829.html)博客里面写的非常详细,并且注解的使用机制很容易理解。

拿上述的@Mapper来说,Retention选择的是RUNTIME策略,就是运行时注入。那么要在运行时获得注入的值,必然要用到java的反射机制。通过反射,拿到一个类运行时的方法变量等,来进行一系列的操作。

那我要考虑的下一个问题是,我定义的@Mapper,在我的工程里面是怎么识别的呢?

来看一下我spring的配置文件中关于mybatis的配置

classpath:myBatis/mapper.xml

在org.mybatis.spring.mapper.MapperScannerConfigurer这个类里面,应该是会去扫描我自定义的com.nuomi.crm.annotation.Mapper这个类的。

在我的mapper.xml里面只需要进行这一简单的配置就可以了(配置的含义后续补充)

接下来看一下mybatis自带的这个MapperScannerConfigurer究竟怎么实现的,来使用我这个自定义的注解@Mapper呢。

public class MapperScannerConfigurer implementsBeanDefinitionRegistryPostProcessor, InitializingBean, ApplicationContextAware, BeanNameAware {private Class extends Annotation>annotationClass;

public void setAnnotationClass(Class extends Annotation>annotationClass) {this.annotationClass =annotationClass;

}/*** {@inheritDoc}

*

*@since1.0.2*/

public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throwsBeansException {if (this.processPropertyPlaceHolders) {

processPropertyPlaceHolders();

}

ClassPathMapperScanner scanner= newClassPathMapperScanner(registry);

scanner.setAddToConfig(this.addToConfig);

scanner.setAnnotationClass(this.annotationClass);

scanner.setMarkerInterface(this.markerInterface);

scanner.setSqlSessionFactory(this.sqlSessionFactory);

scanner.setSqlSessionTemplate(this.sqlSessionTemplate);

scanner.setSqlSessionFactoryBeanName(this.sqlSessionFactoryBeanName);

scanner.setSqlSessionTemplateBeanName(this.sqlSessionTemplateBeanName);

scanner.setResourceLoader(this.applicationContext);

scanner.setBeanNameGenerator(this.nameGenerator);

scanner.registerFilters();

scanner.scan(StringUtils.tokenizeToStringArray(this.basePackage, ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS));

}/** BeanDefinitionRegistries are called early in application startup, before

* BeanFactoryPostProcessors. This means that PropertyResourceConfigurers will not have been

* loaded and any property substitution of this class' properties will fail. To avoid this, find

* any PropertyResourceConfigurers defined in the context and run them on this class' bean

* definition. Then update the values.*/

private voidprocessPropertyPlaceHolders() {

Map prcs = applicationContext.getBeansOfType(PropertyResourceConfigurer.class);if (!prcs.isEmpty() && applicationContext instanceofGenericApplicationContext) {

BeanDefinition mapperScannerBean=((GenericApplicationContext) applicationContext)

.getBeanFactory().getBeanDefinition(beanName);//PropertyResourceConfigurer does not expose any methods to explicitly perform//property placeholder substitution. Instead, create a BeanFactory that just//contains this mapper scanner and post process the factory.

DefaultListableBeanFactory factory = newDefaultListableBeanFactory();

factory.registerBeanDefinition(beanName, mapperScannerBean);for(PropertyResourceConfigurer prc : prcs.values()) {

prc.postProcessBeanFactory(factory);

}

PropertyValues values=mapperScannerBean.getPropertyValues();this.basePackage = updatePropertyValue("basePackage", values);this.sqlSessionFactoryBeanName = updatePropertyValue("sqlSessionFactoryBeanName", values);this.sqlSessionTemplateBeanName = updatePropertyValue("sqlSessionTemplateBeanName", values);

}

}}

上面只是截取的关于annotation的代码片段.

scanner.setAnnotationClass(this.annotationClass);

这里会去扫描配置的那个注解类。

mybatis的内部实现会使用java反射机制来在运行时去解析相应的sql。

(上面写的还不是很完全,后续补充。)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值