mybatis对java自定义注解的使用
转自:https://www.cnblogs.com/sonofelice/p/4980161.html
最近在学习spring和ibatis框架。
以前在天猫实习时做过的一个小项目用到的mybatis,在其使用过程中,不加思索的用了比较原始的一种持久化方式:
在一个包中写一个DAO的接口,在另一个包里面写DAO的实现,使用sqlMapClient来从***-sql.xml中读取相应的sql。
public interface IBaseDaoiBatis {
Object get(String statementName);
}
public class BaseDaoiBatis implements IBaseDaoiBatis {
public Object get(String statementName) {
return getSqlMapClientTemplate().queryForObject(statementName);
}
}
//对应的mybatis配置文件里面的sql:
<sqlMap>
<typeAlias alias="sonarBean" type="com.**--**.SonarScanDataDisplayBean" />
<select id="getSonarScanData" parameterClass="java.lang.Integer" resultClass="java.lang.String">
<![CDATA[
SELECT name FROM mm_test where id=#id#;
]]>
</select>
</sqlMap>
最近搭建了一个spring+ibatis的项目,发现了一种新的持久化方式:
只写一个dao的接口,在接口的方法中直接注解上用到的sql语句,觉得蛮巧妙的。借来用一下。注意,接口上方多了一个@Mapper注解。而每个方法上都是@Select() 注解,值为对应的sql。
@Mapper
public interface TestDao {
@Select("select id, name, name_pinyin from mm_test; ")
List<MmTest> selectAll(); @Insert("insert into mm_test(id, name) values(#{id}, #{name})")
public void insertUser(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
@Component
public @interface Mapper {
String value() default "";
}
关于自定义注解:(查的别人的博客:http://www.cnblogs.com/mandroid/archive/2011/07/18/2109829.html)博客里面写的非常详细,并且注解的使用机制很容易理解。
拿上述的@Mapper来说,Retention选择的是RUNTIME策略,就是运行时注入。那么要在运行时获得注入的值,必然要用到java的反射机制。通过反射,拿到一个类运行时的方法变量等,来进行一系列的操作。
那我要考虑的下一个问题是,我定义的@Mapper,在我的工程里面是怎么识别的呢?
来看一下我spring的配置文件中关于mybatis的配置
<!--mybatis-->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="configLocation">
<value>classpath:myBatis/mapper.xml</value>
</property>
</bean>
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.**.**.**.dao" />
<property name="annotationClass" value="com.nuomi.crm.annotation.Mapper"/>
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />
</bean>
在org.mybatis.spring.mapper.MapperScannerConfigurer这个类里面,应该是会去扫描我自定义的com.nuomi.crm.annotation.Mapper这个类的。
<configuration>
<settings>
<!-- 将下划线字段名称映射为驼峰变量 -->
<setting name="mapUnderscoreToCamelCase" value="true" />
<!-- 进制mybatis进行延迟加载 -->
<setting name="lazyLoadingEnabled" value="false"/>
</settings>
<mappers>
</mappers>
</configuration>
在我的mapper.xml里面只需要进行这一简单的配置就可以了(配置的含义后续补充)
接下来看一下mybatis自带的这个MapperScannerConfigurer究竟怎么实现的,来使用我这个自定义的注解@Mapper呢。
public class MapperScannerConfigurer implements BeanDefinitionRegistryPostProcessor, InitializingBean, ApplicationContextAware, BeanNameAware {
private Class<? extends Annotation> annotationClass;
public void setAnnotationClass(Class<? extends Annotation> annotationClass) {
this.annotationClass = annotationClass;
}/**
* {@inheritDoc}
*
* @since 1.0.2
*/
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
if (this.processPropertyPlaceHolders) {
processPropertyPlaceHolders();
}
ClassPathMapperScanner scanner = new ClassPathMapperScanner(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 void processPropertyPlaceHolders() {
Map<String, PropertyResourceConfigurer> prcs = applicationContext.getBeansOfType(PropertyResourceConfigurer.class);
if (!prcs.isEmpty() && applicationContext instanceof GenericApplicationContext) {
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 = new DefaultListableBeanFactory();
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。
mybatis对java自定义注解的使用的更多相关文章
- mybatis对java自定义注解的使用——入门篇
最近在学习spring和ibatis框架. 以前在天猫实习时做过的一个小项目用到的mybatis,在其使用过程中,不加思索的用了比较原始的一种持久化方式: 在一个包中写一个DAO的接口,在另一个包里面 ...
- java自定义注解类
一.前言 今天阅读帆哥代码的时候,看到了之前没有见过的新东西, 比如java自定义注解类,如何获取注解,如何反射内部类,this$0是什么意思? 于是乎,学习并整理了一下. 二.代码示例 import ...
- java自定义注解实现前后台参数校验
2016.07.26 qq:992591601,欢迎交流 首先介绍些基本概念: Annotations(also known as metadata)provide a formalized way ...
- java自定义注解注解方法、类、属性等等【转】
http://anole1982.iteye.com/blog/1450421 http://www.open-open.com/doc/view/51fe76de67214563b20b385320 ...
- java自定义注解知识实例及SSH框架下,拦截器中无法获得java注解属性值的问题
一.java自定义注解相关知识 注解这东西是java语言本身就带有的功能特点,于struts,hibernate,spring这三个框架无关.使用得当特别方便.基于注解的xml文件配置方式也受到人们的 ...
- Java自定义注解的实现
Java自定义注解的实现,总共三步(eg.@RandomlyThrowsException): 1.首先编写一个自定义注解@RandomlyThrowsException package com.gi ...
- Java自定义注解源码+原理解释(使用Java自定义注解校验bean传入参数合法性)
Java自定义注解源码+原理解释(使用Java自定义注解校验bean传入参数合法性) 前言:由于前段时间忙于写接口,在接口中需要做很多的参数校验,本着简洁.高效的原则,便写了这个小工具供自己使用(内容 ...
- JAVA自定义注解 ------ Annotation
日常开发工作中,合理的使用注解,可以简化代码编写以及使代码结构更加简单,下面记录下,JAVA自定义注解的开发过程. 定义注解声明类. 编写注解处理器(主要起作用部分). 使用注解. 相关知识点介绍, ...
- Java自定义注解和运行时靠反射获取注解
转载:http://blog.csdn.net/bao19901210/article/details/17201173/ java自定义注解 Java注解是附加在代码中的一些元信息,用于一些工具在编 ...
随机推荐
- HDU 4758 Walk Through Squares ( Trie图 && 状压DP && 数量限制类型 )
题意 : 给出一个 n 行.m 列的方格图,现从图左上角(0, 0) 到右下角的 (n, m)走出一个字符串(规定只能往下或者往右走),向右走代表' R ' 向下走则是代表 ' D ' 最后从左上角到 ...
- Java——容器(Auto-boxing/unboxing)
[打包/解包] 在Map中需要增加一个数值时,需要new一个对象出来,输出后又得进行强制类型转换,这就造成不便.在JDK1.5中使用Map接口提供了一种新的机制. 在合适的时机自动打包/解包(在J ...
- [luogu]P3941 入阵曲[前缀和][压行]
[luogu]P3941 入阵曲 题目描述 小 F 很喜欢数学,但是到了高中以后数学总是考不好. 有一天,他在数学课上发起了呆:他想起了过去的一年.一年前,当他初识算法竞赛的 时候,觉得整个世界都焕然 ...
- 特征提取算法(3)——SIFT特征提取算子
目录: 前言 1.高斯尺度空间GSS 2.高斯差分DOG 用DoG检测特征点 GSS尺度选择 3.图像金字塔建立 用前一个octave中的倒数第三幅图像生成下一octave中的第一幅图像 每层octa ...
- eclipse配置Maven——菜鸟篇
首先解释关于webservice: Web service是一个平台独立的,低耦合的,自包含的.基于可编程的web的应用程序, 可使用开放的XML(标准通用标记语言下的一个子集)标准来描述.发布.发现 ...
- 【翻译】详解HTML5 自定义 Data 属性
原标题:HTML5 Custom Data Attributes (data-*) 你是否曾经使用 class 或 rel 来保存任意的元数据,只为了使你的JavaScript更简单?如果你回答是的, ...
- Count on a tree(树上路径第K小)
题目链接:https://www.spoj.com/problems/COT/en/ 题意:求树上A,B两点路径上第K小的数 思路:主席树实际上是维护的一个前缀和,而前缀和不一定要出现在一个线性表上. ...
- vux组件样式大合集
1.Actionsheet 2.Alert 3.badge 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. ...
- Linux超全实用指令大全
参考 Linux超全实用指令大全
- Oracle redo与undo浅析
http://liwenshui322.iteye.com/blog/1488949 一. 什么是redo(用于前滚数据) redo也就是重做日志文件(redo log file),Oracle维护着 ...