自定义整合Mybatis
- 整个过程是为
service注入mapper的代理对象,让mybatis生成的代理对象成为一个Bean
Mybatis解析注解上的sql语句,并生成实际的调用业务
自定义业务类
public interface OrderMapper {
@Select("select name from bank where money = #{money}")
public String getUserName(int money);
}
public interface UserMapper {
@Select("select name from bank where money = #{money}")
public String getUserName(int money);
}
@Component
public class UserService {
@Autowired
private UserMapper userMapper;
@Autowired
private OrderMapper orderMapper;
public void test() {
System.out.println(userMapper.getUserName(2200));
System.out.println(orderMapper.getUserName(1500));
}
}
自定义工厂类
InitFactoryBean,实际负责生成mapper的代理类
public class InitFactoryBean implements FactoryBean {
private SqlSession sqlSession;
private Class mapperClass;
public InitFactoryBean(Class mapperClass) {
this.mapperClass = mapperClass;
}
@Autowired
public void setSqlSession(SqlSessionFactory sqlSessionFactory) {
sqlSessionFactory.getConfiguration().addMapper(mapperClass);
this.sqlSession = sqlSessionFactory.openSession();
}
@Override
public Object getObject() throws Exception {
return sqlSession.getMapper(mapperClass);
}
@Override
public Class<?> getObjectType() {
return mapperClass;
}
}
BeanDifinition注册器
InitImportBeanDefinitionRegistrar
public class InitImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry, BeanNameGenerator importBeanNameGenerator) {
Map<String, Object> annotationAttributes = importingClassMetadata.getAnnotationAttributes(InitScan.class.getName());
String path = (String) annotationAttributes.get("value");
InitScanner initScanner = new InitScanner(registry);
initScanner.addIncludeFilter(new TypeFilter() {
@Override
public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException {
return true;
}
});
initScanner.scan(path);
}
}
自定义注解
InitScan配合扫描器InitScanner,获取Mapper的包名
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Import(InitImportBeanDefinitionRegistrar.class)
public @interface InitScan {
String value() default "";
}
扫描器
public class InitScanner extends ClassPathBeanDefinitionScanner {
public InitScanner(BeanDefinitionRegistry registry) {
super(registry);
}
@Override
protected boolean isCandidateComponent(AnnotatedBeanDefinition beanDefinition) {
return beanDefinition.getMetadata().isInterface();
}
@Override
protected Set<BeanDefinitionHolder> doScan(String... basePackages) {
Set<BeanDefinitionHolder> beanDefinitionHolders = super.doScan(basePackages);
for (BeanDefinitionHolder beanDefinitionHolder : beanDefinitionHolders) {
BeanDefinition beanDefinition = beanDefinitionHolder.getBeanDefinition();
beanDefinition.getConstructorArgumentValues().addGenericArgumentValue(beanDefinition.getBeanClassName());
beanDefinition.setBeanClassName(InitFactoryBean.class.getName());
}
return beanDefinitionHolders;
}
}
配置类
@ComponentScan("com.java")
@InitScan("com.java.mapper")
public class AppConfig {
@Bean
public SqlSessionFactory sqlSessionFactory() throws IOException {
InputStream is = Resources.getResourceAsStream("mybatis.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
return sqlSessionFactory;
}
}
使用
public class Test {
public static void main(String[] args) {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);
UserService userService = (UserService) applicationContext.getBean("userService");
userService.test();
}
}