文档章节

扩展Mybatis的能力Mapper使用记录

mahengyang
 mahengyang
发布于 2017/07/21 15:06
字数 1123
阅读 219
收藏 0

配置Mapper

在spring的配置文件中配置Mapper,跟mybatis的配置方式一样

<bean class="tk.mybatis.spring.mapper.MapperScannerConfigurer">
    <property name="basePackage" value="com.qbike.main.common.repository"/>
    <property name="markerInterface" value="tk.mybatis.mapper.common.Mapper"/>
    <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
</bean>

新建Mapper

每个表对应一个mapper类,里面不需要写方法,只要继承了Mapper类,默认就拥有了CRUD

public interface TestRepository extends Mapper<Test> {

}

public interface LeipaiRepository extends Mapper<LeipaiOrder> {

}

新建表对象

每个表对应一个java对象,@Table指定该对象对应的表名称,默认对应的是类名称,以下划线分隔

@Table(name = "qbike_test")
public class Test {
    @ Id
    @GeneratedValue(generator = "JDBC")
    private Long id;
    private Date createTime;
    private TestStatus status;
        ...省略get/set

其中status字段是枚举类型,它的code会写到数据库中

public enum TestStatus implements EnumCode{
    待测试(0),
    测试成功(1),
    测试失败(2);
    private Integer code;

    TestStatus(Integer code) {
        this.code = code;
    }

    public Integer getCode() {
        return code;
    }

EnumCode是所有枚举都要实现的接口,getCode()方法用于返回数据库需要的编码

public interface EnumCode {
    public Integer getCode();
}

创建Service类

service只需要继承自BaseService,设置泛型类为Test,不需要写任何方法即可拥有增删改查

[@Service](https://my.oschina.net/service)
public class TestServiceImpl extends BaseService<Test> {

    }

重要的基础类 BaseService<T>

此类包含了常用的方法:单个查询、列表查询、排序以及增/改,包含一个Mapper<T>的字段,此字段使用了spring4的泛型注入(必须使用@Autowired),可以根据子类泛型的不同而注入不通的子Mapper,如上面的TestServiceImpl 由于设置了泛型是Test ,所以spring在初始化的时候就会给它注入 TestRepository

/**
 * 基础service类,包含了数据库CRUD基本操作
 * Created by mahengyang on 2017/7/19.
 */
[@Service](https://my.oschina.net/service)
public abstract class BaseService<T> {
    /**
     * 数据查询mapper,根据T的不同初始化为不同的子类型
     */
    @Autowired
    protected Mapper<T> mapper;

    private String updateTimeMethod = "setUpdateTime";
    private String createTimeMethod = "setCreateTime";
    private String createTimeField = "createTime";

    /**
     * 写入数据,默认会给create_time和update_time字段赋值(如果T中包含的话)
     *
     * @param t domain对象
     * @return 插入的条数
     */
    public int insert(T t) {
        fill(t, this.createTimeMethod, Calendar.getInstance().getTime());
        fill(t, this.updateTimeMethod, Calendar.getInstance().getTime());
        return mapper.insert(t);
    }

    public int update(T t) {
        fill(t, this.updateTimeMethod, Calendar.getInstance().getTime());
        return mapper.updateByPrimaryKeySelective(t);
    }

    public T query(Long id) {
        return mapper.selectByPrimaryKey(id);
    }

    public T selectOne(T query) {
        return mapper.selectOne(query);
    }

    /**
     * 列表查询,默认按照createTime字段倒序查询
     *
     * @param query    查询条件
     * @param pageNum  页码
     * @param pageSize 页大小
     * @return 分页对象
     */
    public PageInfo<T> queryForPage(T query, int pageNum, int pageSize) {
        return queryForPage(query, pageNum, pageSize, this.createTimeField);
    }

    /**
     * 列表查询,根据指定的字段倒序排序
     *
     * @param query      查询对象
     * @param pageNum    页码
     * @param pageSize   页大小
     * @param orderField 排序字段
     * @return 分页对象
     */
    public PageInfo<T> queryForPage(T query, int pageNum, int pageSize, String orderField) {
        Example example = new Example(query.getClass());
        example.orderBy(orderField).desc();
        Example.Criteria criteria = example.createCriteria();
        try {
            Map<String, Object> describe = PropertyUtils.describe(query);
            for (Map.Entry<String, Object> entry : describe.entrySet()) {
                Object value = entry.getValue();
                if (value == null || StringUtils.isEmpty(value.toString())) continue;
                if (value instanceof Class) continue;
                criteria.andEqualTo(entry.getKey(), value);
            }
        } catch (IllegalAccessException e) {
        } catch (InvocationTargetException e) {
        } catch (NoSuchMethodException e) {
        }
        PageHelper.startPage(pageNum, pageSize);
        List<T> result = mapper.selectByExample(example);
        PageInfo<T> pageInfo = new PageInfo<>(result, pageNum);
        return pageInfo;
    }

    protected void fill(T obj, String fieldName, Object value) {
        Class<?> clazz = obj.getClass();
        try {
            Method method = clazz.getMethod(fieldName, value.getClass());
            if (method == null) return;
            method.invoke(obj, value);
        } catch (NoSuchMethodException e) {
        } catch (IllegalAccessException e) {
        } catch (InvocationTargetException e) {
        }
    }
}

创建controller

controller使用spring mvc的方式,TestService中的方法都是BaseService中的

@RestController
@RequestMapping(value = "test")
public class TestControllerMgr extends BaseController {
    @Resource
    private TestServiceImpl testService;

    @RequestMapping("list")
    @ResponseBody
    public ApiResult list(Test query, int page, int size) {
        if (query == null) query = new Test();
        PageInfo<Test> list = testService.queryForPage(query, page, size);
        return success(list);
    }

    @RequestMapping("detail")
    @ResponseBody
    public ApiResult detail(Test query) {
        Test t = testService.selectOne(query);
        return success(t);
    }

    @RequestMapping("insert")
    @ResponseBody
    public ApiResult insert(Test test) {
        testService.insert(test);
        return success(test.getId(), "成功");
    }

    @RequestMapping("update")
    @ResponseBody
    public ApiResult update(Test test) {
        testService.update(test);
        return success("更新成功");
    }
}

配置mybatis对枚举字段的转换

mybatis从3.4.4版本(2017年4月)开始可以自定义枚举处理类型,按照如下配置mybatis-config.xml即可,此的javaType不可配置为EnumCode接口,否则会导致下面的EnumTypeHandler在使用type.getEnumConstants()获取不到所有的枚举值,有多少个枚举,这里就要配置多少个,目前没有好的办法

<typeHandlers>
    <typeHandler javaType="com.qbike.eum.LeipaiOrderStatus" handler="com.qbike.mybatis.EnumTypeHandler"/>
    <typeHandler javaType="com.qbike.eum.TestStatus" handler="com.qbike.mybatis.EnumTypeHandler"/>
</typeHandlers>

枚举处理类 EnumTypeHandler

此类需要继承自BaseTypeHandler<E>

/**
 * Created by mahengyang on 2017/7/20.
 */
public class EnumTypeHandler<E extends Enum<E> & EnumCode> extends BaseTypeHandler<E> {
    private Class<E> type;
    private EnumCode[] enums;

    public EnumTypeHandler(Class<E> type) {
        this.type = type;
        this.enums = type.getEnumConstants();
    }

    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, E parameter, JdbcType jdbcType) throws SQLException {
        ps.setInt(i, parameter.getCode());
    }

    @Override
    public E getNullableResult(ResultSet rs, String columnName) throws SQLException {
        return find(rs.getInt(columnName));
    }

    @Override
    public E getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
        return find(rs.getInt(columnIndex));
    }

    @Override
    public E getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
        return find(cs.getInt(columnIndex));
    }

    private E find(int status) {
        for (EnumCode enumCode : enums) {
            if (enumCode.getCode() == status) {
                return (E) enumCode;
            }
        }
        return null;
    }
}

如果没有特殊的需求,就不需要创建mybatis的xml文件了

© 著作权归作者所有

共有 人打赏支持
mahengyang
粉丝 56
博文 46
码字总数 32090
作品 0
苏州
程序员
私信 提问
Mybatis 通用 Mapper 3.5.0 发布

Mybatis 通用 Mapper 3.5.0 已发布。MyBatis 通用 Mapper 极其方便的使用 MyBatis 单表的增删改查,支持单表操作,不支持通用的多表联合查询。通用 Mapper 可以极大的方便开发人员。可以随意...

Liuzh_533
01/09
2K
4
史上最简单的 MyBatis 教程(三)

1 前言 在史上最简单的 MyBatis 教程(一、二)中,咱们已经初步体验了 MyBatis 框架的一些优秀的特性,例如在映射文件中书写自定义的 SQL 语句以及便捷的调用方式等等。为了能够更好的掌握 ...

qq_35246620
2017/02/02
0
0
Mybatis 入门案例 2 ---- mapper 代理的方式

我们只需要编写DAO接口和mapper.xml文件即可,DAO接口实现对象由mybatis自动生成代理对象。 如: 一、为什么不使用原始的DAO方式开发呢? 1、dao的实现类中存在重复代码,整个mybatis操作的过...

故新
2017/11/07
0
0
baomidou/mybatis-plus

为简化开发工作、提高生产率而生 简介 | Intro Mybatis 增强工具包 - 只做增强不做改变,简化操作 技术讨论 QQ 群 576493122 优点 | Advantages 无侵入:Mybatis-Plus 在 Mybatis 的基础上进...

baomidou
2016/01/25
0
0
baomidou/mybatisplus-spring-boot-starter

#mybatisplus-spring-boot-starter mybatisplus-spring-boot-starter 为 Mybatis-Plus 快速集成 spring-boot 简化配置而生,不再需拿 MyBatis 和 Hibernate 相比,mybatis-plus 作为 mybati......

baomidou
2017/05/05
0
0

没有更多内容

加载失败,请刷新页面

加载更多

js垃圾回收机制和引起内存泄漏的操作

JS的垃圾回收机制了解吗? Js具有自动垃圾回收机制。垃圾收集器会按照固定的时间间隔周期性的执行。 JS中最常见的垃圾回收方式是标记清除。 工作原理:是当变量进入环境时,将这个变量标记为“...

Jack088
10分钟前
1
0
大数据教程(10.1)倒排索引建立

前面博主介绍了sql中join功能的大数据实现,本节将继续为小伙伴们分享倒排索引的建立。 一、需求 在很多项目中,我们需要对我们的文档建立索引(如:论坛帖子);我们需要记录某个词在各个文...

em_aaron
27分钟前
1
0
"errcode": 41001, "errmsg": "access_token missing hint: [w.ILza05728877!]"

Postman获取微信小程序码的时候报错, errcode: 41001, errmsg: access_token missing hint 查看小程序开发api指南,原来access_token是直接当作parameter的(写在url之后),scene参数一定要...

两广总督bogang
27分钟前
6
0
MYSQL索引

索引的作用 索引类似书籍目录,查找数据,先查找目录,定位页码 性能影响 索引能大大减少查询数据时需要扫描的数据量,提高查询速度, 避免排序和使用临时表 将随机I/O变顺序I/O 降低写速度,占用磁...

关元
45分钟前
7
0
撬动世界的支点——《引爆点》读书笔记2900字优秀范文

撬动世界的支点——《引爆点》读书笔记2900字优秀范文: 作者:挽弓如月。因为加入火种协会的读书活动,最近我连续阅读了两本论述流行的大作,格拉德威尔的《引爆点》和乔纳伯杰的《疯传》。...

原创小博客
57分钟前
18
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部