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注解是附加在代码中的一些元信息,用于一些工具在编 ...
随机推荐
- mysql TOP语句 语法
mysql TOP语句 语法 作用:用于规定要返回的记录的数目. 语法:SELECT column_name(s) FROM table_name LIMIT number 说明:对于拥有数千条记录的 ...
- JDK1.8 LinkedList双向链表源码
序言 LinkedList是一个双向链表 也就是说list中的每个元素,在存储自身值之外,还 额外存储了其前一个和后一个元素的地址,所以也就可以很方便地根据当前元素获取到其前后的元素 链表的尾部元素的 ...
- Mysql索引深入理解
一. 引言 Mysql 我们平常用的很多,了解的很多,今天别的不说,直接说mysql的底层是什么,说到底层,就想到数据结构,那么,mysql的数据结构是什么呢? 是B + tree .那么数据库中的 ...
- H. The Game of Life
题目链接:http://exam.upc.edu.cn/problem.php?id=5206 题意:邻居为八个方向.若一个活人有2或3个邻居,遗传一代,否则死亡:若一个死人有3个邻居,则下一代复活. ...
- git pull失误提交
git pull 提示错误,Your local changes to the following files would be overwritten by merge 到公司后本来打算git pu ...
- spring- junit测试事务回滚
http://blog.csdn.net/molingduzun123/article/details/49383235
- SpringBoot与数据源
1.JDBC <dependency> <groupId>org.springframework.boot</groupId> <artifactId> ...
- linux的find和grep区别?
为什么会把 grep和find 这两个命令拿在一起来讨论? 是因为他们之间有一个容易混淆的地方, [在我的记忆中] : -name ? 它是find的选项! 不是grep的选项! 实际上, find基 ...
- How to derive mean and variance of a Gaussian?
PRML exercise 1.8: To derive mean: change of variable z = x - u, use symmetry To derive variance: di ...
- 监听整个页面上的DOM树变化
在线预览 方法 使用<Web API 接口>的<MutationObserver> MutationObserver 网上查到的很多都是使用Mutation events的,但 ...