spring之手写mybatis-spring

什么是 MyBatis

MyBatis 是一款优秀的持久层框架,它支持自定义 SQL、存储过程以及高级映射。MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。

BeanFactory 和 FactoryBean

BeanFactory
1 负责生产和管理bean的一个工厂
2 是IOC容器的核心接口,它的职责包括:实例化、定位、配置应用程序中的对象及建立这些对象的依赖
3 多种实现:如 DefaultListableBeanFactory、XmlBeanFactory、ApplicationContext等,其中XmlBeanFactory就是常用的一个,该实现将以XML方式描述组成应用的对象及对象间的依赖关系

FactoryBean
1 FactoryBean 也是一个工厂,但只创建一个对象。
2 FactoryBean是一个接口,当在IOC容器中的Bean实现了FactoryBean后,通过getBean(String BeanName)获取到的Bean对象并不是FactoryBean的实现类对象,而是这个实现类中的getObject()方法返回的对象。要想获取FactoryBean的实现类,就要getBean(&BeanName),在BeanName之前加上&。

定义我们自己的FactoryBean

/**
 * Mapper的创建工厂
 * @author yangyanping
 * @date 2020-09-21
 */
public class MyMapperFactoryBean implements FactoryBean {
    /**
     * 接口
     */
    private Class<?> mapperInterface;

    public MyMapperFactoryBean(Class<?> mapperInterface) {
        this.mapperInterface = mapperInterface;
    }

    @Override
    public Object getObject() throws Exception {
        return Proxy.newProxyInstance(this.getClass().getClassLoader(), new Class<?>[]{mapperInterface}, (Object proxy, Method method, Object[] args) -> {
            MySelect annotation = AnnotationUtils.findAnnotation(method, MySelect.class);
            String sql = annotation.value();
            System.out.println(sql);

            return null;
        });
    }

    @Override
    public Class<?> getObjectType() {
        return mapperInterface;
    }
}

注解类MySelect 定义

/**
 * 注解
 * @author yangyanping
 * @date 2020-09-21
 */
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
public @interface MySelect {
    /**
     * SQL 语句
     */
    String value();
}

ImportBeanDefinitionRegistrar

ImportBeanDefinitionRegistrar类只能通过其他类@Import的方式来加载,
通常是启动类或配置类。
使用@Import,如果括号中的类是ImportBeanDefinitionRegistrar的实现类,
则会调用接口方法,将其中要注册的类注册成bean。
实现该接口的类拥有注册bean的能力。

MyBeanDefinitionRegistrar 类定义如下:

/**
 * BeanDefinition 注册类
 * @author yangyanping
 * @date 2020-09-21
 */
public class MyBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
    @Override
    public void registerBeanDefinitions(AnnotationMetadata annotationMetadata, BeanDefinitionRegistry beanDefinitionRegistry) {
        AnnotationAttributes annoAttrs = AnnotationAttributes.fromMap(annotationMetadata.getAnnotationAttributes(MapperScan.class.getName()));
        MapperScannerRegistrar scanner = new MapperScannerRegistrar(beanDefinitionRegistry);

        String basePackages = annoAttrs.getString("basePackages");

        Set<BeanDefinitionHolder> set =   scanner.doScan(basePackages);

        for (BeanDefinitionHolder holder : set) {

            ScannedGenericBeanDefinition ben = (ScannedGenericBeanDefinition) holder.getBeanDefinition();
            RootBeanDefinition beanDefinition = new RootBeanDefinition(MyMapperFactoryBean.class);
            //类的全名  com.yyp.study.mybatis.mapper.AccountMapper
            String name = ben.getMetadata().getClassName();
            beanDefinition.getConstructorArgumentValues().addGenericArgumentValue(name);
            //类的短名称  AccountMapper
            String simpleName = name.substring(name.lastIndexOf(".") + 1);
            //类名称  accountMapper
            String lowerName = simpleName.substring(0, 1).toLowerCase() + simpleName.substring(1);
            beanDefinitionRegistry.registerBeanDefinition(lowerName, beanDefinition);
        }
    }
}

扫描注解定义:

/**
 * 扫描注解
 * @author yangyanping
 * @date 2020-09-21
 */
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
@Documented
@Import({MyBeanDefinitionRegistrar.class})
public @interface MapperScan {
    @AliasFor("value")
    String basePackages() default "";

    @AliasFor("basePackages")
    String value() default "";
}

@Configuration的使用

从Spring3.0,@Configuration用于定义配置类,可替换xml配置文件,被注解的类内部包含有一个或多个被@Bean注解的方法,这些方法将会被AnnotationConfigApplicationContext或AnnotationConfigWebApplicationContext类进行扫描,并用于构建bean定义,初始化Spring容器

/**
 * 系统配置类
 * @author yangyanping
 * @date 2020-090-21
 */
@Configuration
@Import(MyBeanDefinitionRegistrar.class)
@MapperScan( basePackages = "com.yyp.study.mybatis.mapper")
public class AppConfig {
}

测试mybatis-spring中间件

首先定义2个 Mapper

/**
 * 账号Mapper
 * @author yangyanping
 * @date 2020-09-21
 */
public interface AccountMapper {
    @MySelect("select * from user")
    User findById(Integer id);
}

/**
 * 用户 Mapper
 * @author yangyanping
 * @date 2020-09-21
 */
public interface UserMapper {
    @MySelect("select * from user")
    User findById(Integer id);
}

编写我们的测试类代码,测试我们自己的mybatis-spring

/**
 * mybatis 测试类
 * @author yangyanping
 * @date 2020-09-21
 */
public class MybatisTest {
    public static void main(String[] args) throws Exception {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
        System.out.println(context.getBean(AccountMapper.class).findById(1));

        context.start();
        System.in.read();
    }
}

输出:

select * from user
null
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Mybatis-plus 是一个 Mybatis 的增强工具,提供了很多方便的操作方法,可以使我们的开发效率更高、更简洁。下面是使用 Mybatis-plus 进行增删改查的示例: 1. 添加依赖 在 pom.xml 文件中添加以下依赖: ```xml <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.4.3.1</version> </dependency> ``` 2. 配置数据源 在 application.properties 文件中配置数据源信息: ```properties spring.datasource.url = jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai spring.datasource.username = root spring.datasource.password = 123456 spring.datasource.driver-class-name = com.mysql.cj.jdbc.Driver ``` 3. 创建实体类 创建一个实体类,可以使用注解 @TableName 指定数据库表名,@TableId 指定主键字段。 ```java @Data @TableName("user") public class User { @TableId(type = IdType.AUTO) private Long id; private String name; private Integer age; private String email; } ``` 4. 创建 Mapper 接口 创建一个 Mapper 接口,继承 BaseMapper 类,可以直接使用 Mybatis-plus 提供的方法,无需 SQL。 ```java @Mapper public interface UserMapper extends BaseMapper<User> { } ``` 5. 使用 Mybatis-plus 进行增删改查 使用 Mybatis-plus 提供的方法进行增删改查操作。 ```java @Service public class UserServiceImpl implements UserService { @Autowired private UserMapper userMapper; @Override public void addUser(User user) { userMapper.insert(user); } @Override public void deleteUserById(Long id) { userMapper.deleteById(id); } @Override public void updateUser(User user) { userMapper.updateById(user); } @Override public User getUserById(Long id) { return userMapper.selectById(id); } @Override public List<User> getUserList() { return userMapper.selectList(null); } } ``` 以上就是使用 Mybatis-plus 进行增删改查的示例。当然,Mybatis-plus 还提供了其他很多方便的操作方法,可以根据具体需求进行使用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值