mybatis对java自定义注解的使用

java

 转自:https://www.cnblogs.com/sonofelice/p/4980161.html

最近在学习spring和ibatis框架。

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

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

 1 public interface IBaseDaoiBatis {

2 Object get(String statementName);

3 }

4 public class BaseDaoiBatis implements IBaseDaoiBatis {

5 public Object get(String statementName) {

6 return getSqlMapClientTemplate().queryForObject(statementName);

7 }

8 }

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

10 <sqlMap>

11 <typeAlias alias="sonarBean" type="com.**--**.SonarScanDataDisplayBean" />

12 <select id="getSonarScanData" parameterClass="java.lang.Integer" resultClass="java.lang.String">

13 <![CDATA[

14 SELECT name FROM mm_test where id=#id#;

15 ]]>

16 </select>

17 </sqlMap>

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

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

1 @Mapper

2 public interface TestDao {

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

4 List<MmTest> selectAll();

5

6 @Insert("insert into mm_test(id, name) values(#{id}, #{name})")

7 public void insertUser(MmTest mmtTestS);

8 }

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

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

 1 import org.springframework.stereotype.Component;

2

3 import java.lang.annotation.*;

4 @Target({ ElementType.TYPE })

5 @Retention(RetentionPolicy.RUNTIME)

6 @Documented

7 @Component

8 public @interface Mapper {

9 String value() default "";

10 }

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

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

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

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

 1 <!--mybatis-->

2 <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">

3 <property name="dataSource" ref="dataSource" />

4 <property name="configLocation">

5 <value>classpath:myBatis/mapper.xml</value>

6 </property>

7 </bean>

8 <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">

9 <property name="basePackage" value="com.**.**.**.dao" />

10 <property name="annotationClass" value="com.nuomi.crm.annotation.Mapper"/>

11 <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />

12 </bean>

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

 

 1 <configuration>

2 <settings>

3 <!-- 将下划线字段名称映射为驼峰变量 -->

4 <setting name="mapUnderscoreToCamelCase" value="true" />

5 <!-- 进制mybatis进行延迟加载 -->

6 <setting name="lazyLoadingEnabled" value="false"/>

7 </settings>

8 <mappers>

9 </mappers>

10 </configuration>

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

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

 1 public class MapperScannerConfigurer implements BeanDefinitionRegistryPostProcessor, InitializingBean, ApplicationContextAware, BeanNameAware {

2 private Class<? extends Annotation> annotationClass;

3 public void setAnnotationClass(Class<? extends Annotation> annotationClass) {

4 this.annotationClass = annotationClass;

5 }/**

6 * {@inheritDoc}

7 *

8 * @since 1.0.2

9 */

10 public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {

11 if (this.processPropertyPlaceHolders) {

12 processPropertyPlaceHolders();

13 }

14

15 ClassPathMapperScanner scanner = new ClassPathMapperScanner(registry);

16 scanner.setAddToConfig(this.addToConfig);

17 scanner.setAnnotationClass(this.annotationClass);

18 scanner.setMarkerInterface(this.markerInterface);

19 scanner.setSqlSessionFactory(this.sqlSessionFactory);

20 scanner.setSqlSessionTemplate(this.sqlSessionTemplate);

21 scanner.setSqlSessionFactoryBeanName(this.sqlSessionFactoryBeanName);

22 scanner.setSqlSessionTemplateBeanName(this.sqlSessionTemplateBeanName);

23 scanner.setResourceLoader(this.applicationContext);

24 scanner.setBeanNameGenerator(this.nameGenerator);

25 scanner.registerFilters();

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

27 }

28

29 /*

30 * BeanDefinitionRegistries are called early in application startup, before

31 * BeanFactoryPostProcessors. This means that PropertyResourceConfigurers will not have been

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

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

34 * definition. Then update the values.

35 */

36 private void processPropertyPlaceHolders() {

37 Map<String, PropertyResourceConfigurer> prcs = applicationContext.getBeansOfType(PropertyResourceConfigurer.class);

38

39 if (!prcs.isEmpty() && applicationContext instanceof GenericApplicationContext) {

40 BeanDefinition mapperScannerBean = ((GenericApplicationContext) applicationContext)

41 .getBeanFactory().getBeanDefinition(beanName);

42

43 // PropertyResourceConfigurer does not expose any methods to explicitly perform

44 // property placeholder substitution. Instead, create a BeanFactory that just

45 // contains this mapper scanner and post process the factory.

46 DefaultListableBeanFactory factory = new DefaultListableBeanFactory();

47 factory.registerBeanDefinition(beanName, mapperScannerBean);

48

49 for (PropertyResourceConfigurer prc : prcs.values()) {

50 prc.postProcessBeanFactory(factory);

51 }

52

53 PropertyValues values = mapperScannerBean.getPropertyValues();

54

55 this.basePackage = updatePropertyValue("basePackage", values);

56 this.sqlSessionFactoryBeanName = updatePropertyValue("sqlSessionFactoryBeanName", values);

57 this.sqlSessionTemplateBeanName = updatePropertyValue("sqlSessionTemplateBeanName", values);

58 }

59 }

60

61 }

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

scanner.setAnnotationClass(this.annotationClass);
这里会去扫描配置的那个注解类。

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

以上是 mybatis对java自定义注解的使用 的全部内容, 来源链接: utcz.com/z/390502.html

回到顶部