理解mybatis 里的mapper 实现原理
目的
主要想搞明白,mybatis 是如何通过只通过声明一个mapper 接口,就能实现crud 操作了
实现注解
@Retention(RetentionPolicy.RUNTIME)
public @interface Mapper {
}
@Retention(RetentionPolicy.RUNTIME)
public @interface Insert {
String value();
}
代理
public class MapperProxy implements InvocationHandler {
public MapperProxy() throws Exception {
// 创建数据库连接(此处使用示例数据库信息)
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// 这里可以拦截不同的方法来实现不同的crud操作
if (method.isAnnotationPresent(Insert.class)) {
// 获取注解中的 SQL
Insert insert = method.getAnnotation(Insert.class);
String sql = insert.value();
// 从参数中获取 User 对象,这里可以执行SQL
User user = (User) args[0];
sql = sql.replace("#{name}", "'" + user.getName() + "'");
System.out.println(sql);
}
return null;
}
}
public class MapperProxyFactory<T> implements FactoryBean<T> {
private Class<T> mapperInterface;
public MapperProxyFactory(Class<T> mapperInterface) {
this.mapperInterface = mapperInterface;
}
@Override
public T getObject() throws Exception {
MapperProxy proxy = new MapperProxy();
//生成代理类
return (T) Proxy.newProxyInstance(mapperInterface.getClassLoader(),
new Class<?>[]{mapperInterface},
proxy);
}
@Override
public Class<?> getObjectType() {
return mapperInterface;
}
}
声明mapper
@Mapper
public interface UserMapper {
@Insert("INSERT INTO User (name) VALUES (#{name})")
void insertUser(User user);
}
扫描类
public class MapperScannerConfigurer implements BeanDefinitionRegistryPostProcessor {
private String basePackage;
public void setBasePackage(String basePackage) {
this.basePackage = basePackage;
}
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
// 扫描包路径下的 Mapper 接口,注册到容器
ClassPathScanningCandidateComponentProvider scanner = new ClassPathScanningCandidateComponentProvider(false) {
@Override
protected boolean isCandidateComponent(AnnotatedBeanDefinition metadataReader) {
return true;
}
};
scanner.addIncludeFilter(new AnnotationTypeFilter(Mapper.class));
for (BeanDefinition beanDefinition : scanner.findCandidateComponents(basePackage)) {
GenericBeanDefinition definition = (GenericBeanDefinition) beanDefinition;
String beanClassName = definition.getBeanClassName();
// 设置为 MapperFactoryBean 代理类
definition.getConstructorArgumentValues().addGenericArgumentValue(beanClassName);
definition.setBeanClass(MapperProxyFactory.class);
// 注册 Bean 到 Spring 容器
registry.registerBeanDefinition(beanClassName, definition);
}
}
@Override
public void postProcessBeanFactory(org.springframework.beans.factory.config.ConfigurableListableBeanFactory beanFactory) throws BeansException {
// 不需要实现这个方法
}
}
启动类
@Configuration
public class AppConfig {
@Bean
public MapperScannerConfigurer mapperScannerConfigurer() {
MapperScannerConfigurer configurer = new MapperScannerConfigurer();
configurer.setBasePackage("com.demo.ma.mapper"); // 设置扫描包路径
return configurer;
}
}
public class Application {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
UserMapper userMapper = context.getBean(UserMapper.class);
// 测试调用
userMapper.insertUser(new User(1,"aa"));
context.close();
}
}
public class User {
private Integer id;
private String name;
public User(Integer id, String name) {
this.id = id;
this.name = name;
}
// Getters and Setters
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
原文地址:https://blog.csdn.net/qq_22222499/article/details/143824858
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!