Mybatis通用Mapper的实现

栏目: Java · 发布时间: 6年前

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

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

传统 Mybatis 开发使用XML的方式编写SQL脚本进行数据库操作,

Mybatis 允许使用 动态SQL 但是即使如此, 依然存在许多重复性工作, 因为每个基本表的增删改查语句模式其实都是相同的

Mybatis 也可以使用Dao接口上以注解的形式编写SQL, 但是也是一样, 必须重复编写, 非常不方便

其实 Mybatis 已经考虑到了这点, 为我们提供了自定义通用Mapper的实现机制

项目地址

https://github.com/GitHub-Laziji/commons-mybatis

实现

实现方法分为两步

声明引用的方法

在Dao接口的方法上以注解的形式声明, 使用哪个类的哪个方法, 如下

public interface DODao<T extends DO> extends Dao<T> {

    @SelectProvider(type = SqlProvider.class, method = "selectById")
    T selectById(Long id);

    @InsertProvider(type = SqlProvider.class, method = "insert")
    @Options(useGeneratedKeys = true, keyColumn = "id")
    int insert(T bean);

    @UpdateProvider(type = SqlProvider.class, method = "update")
    int update(T bean);

    @DeleteProvider(type = SqlProvider.class, method = "delete")
    int delete(Long id);
}

方法实现

在实现方法中可以接收Dao接口中传来的参数, 最后返回一个SQL字符串, 这个SQL可以是动态的, 例如可以使用 id=#{id} 这样的语法

T selectById(Long id) 实现如下

public String selectById(ProviderContext context) {
    Class clazz = getEntityClass(context);
    assert clazz != null;
    return new SQL()
            .SELECT(getColumns(clazz))
            .FROM(getTableName(clazz))
            .WHERE("`id`=#{id}")
            .toString();
}

我们可以通过 context 获取Dao的泛型类, 也就是实体类

private Class getEntityClass(ProviderContext context) {
    for (Type type : context.getMapperType().getGenericInterfaces()) {
        ResolvableType resolvableType = ResolvableType.forType(type);
        if (resolvableType.getRawClass() == Dao.class
                || resolvableType.getRawClass() == DODao.class
                || resolvableType.getRawClass() == VODao.class) {
            return resolvableType.getGeneric(0).getRawClass();
        }
    }
    return null;
}

通过反射我们可以拿到对应的字段名, 类名, 字段名获取如下, Ignore 是自定义注解, 用于忽略一些字段

private String[] getVariables(Class clazz, String[] prefixes) {
    List<String> variables = new ArrayList<>();
    for (Method method : clazz.getMethods()) {
        Ignore annotation = method.getAnnotation(Ignore.class);
        if (annotation != null) {
            continue;
        }
        String name = method.getName();
        for (String prefix : prefixes) {
            int length = prefix.length();
            if (name.length() > length && name.startsWith(prefix)
                    && name.charAt(length) >= 'A' && name.charAt(length) <= 'Z') {
                String variableName = (char) (name.charAt(length) - 'A' + 'a') + name.substring(length + 1);
                variables.add(variableName);
                break;
            }
        }

    }
    return variables.toArray(new String[]{});
}

private String[] getReadVariables(Class clazz) {
    return getVariables(clazz, new String[]{"is", "get"});
}

小结

使用通用 Mapper 无需编写任何SQL 只需创建空Dao 继承通用的 Dao<T> 即可


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

The Intersectional Internet

The Intersectional Internet

Safiya Umoja Noble、Brendesha M. Tynes / Peter Lang Publishing / 2016

From race, sex, class, and culture, the multidisciplinary field of Internet studies needs theoretical and methodological approaches that allow us to question the organization of social relations that ......一起来看看 《The Intersectional Internet》 这本书的介绍吧!

CSS 压缩/解压工具
CSS 压缩/解压工具

在线压缩/解压 CSS 代码

RGB转16进制工具
RGB转16进制工具

RGB HEX 互转工具

MD5 加密
MD5 加密

MD5 加密工具