文档章节

扩展Mybatis的能力Mapper使用记录

mahengyang
 mahengyang
发布于 2017/07/21 15:06
字数 1123
阅读 96
收藏 0
点赞 0
评论 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
粉丝 52
博文 46
码字总数 32090
作品 0
苏州
程序员
Mybatis 通用 Mapper 3.5.0 发布

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

Liuzh_533 ⋅ 01/09 ⋅ 4

史上最简单的 MyBatis 教程(三)

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

qq_35246620 ⋅ 2017/02/02 ⋅ 0

baomidou/mybatis-plus

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

baomidou ⋅ 2016/01/25 ⋅ 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

springmvc学习笔记(7)-springmvc整合mybatis之mapper

springmvc学习笔记(7)-springmvc整合mybatis之mapper 标签: springmvc mybatis [TOC] 本文记录springmvc整合dao的配置 整合dao 首先在resource文件夹下添加两个文件:数据库配置文件和日志配...

brianway ⋅ 2016/03/11 ⋅ 0

Mybatis 通用 Mapper 3.3.1 发布

MyBatis通用Mapper3,极其方便的使用MyBatis单表的增删改查 3.3.1更新日志 增加enableMethodAnnotation参数,可以控制是否支持方法上的JPA注解,默认false。设置enableMethodAnnotation = tr...

Liuzh_533 ⋅ 2015/12/11 ⋅ 10

Mybatis 入门案例 2 ---- mapper 代理的方式

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

故新 ⋅ 2017/11/07 ⋅ 0

Mybatis 通用 Mapper--Mapper

Mybatis 通用 Mapper 极其方便的使用 Mybatis 单表的增删改查,支持单表操作,不支持通用的多表联合查询 优点: 通用 Mapper 可以极大的方便开发人员。 为了让您更方便的了解通用 Mapper,下面...

Liuzh_533 ⋅ 2014/11/22 ⋅ 11

MyBatis 实践 -Mapper与DAO

标签: Java与存储 MyBatis简介 MyBatis前身是iBatis,是一个基于Java的数据持久层/对象关系映射(ORM)框架. MyBatis是对JDBC的封装,使开发人员只需关注SQL本身,而不需花费过多的精力去处理如注...

hanqing280441589 ⋅ 2016/02/28 ⋅ 0

Mybatis Generator Plus

MBP,即 Mybatis Generator Plus,基于 mybatis generator core v.1.3.2 源码扩展,增加一些特性,具体如下: 功能特性: 修改 org.mybatis.generator.api.dom.java.Interface 类,新增 privat...

handsome_w ⋅ 2017/01/20 ⋅ 2

没有更多内容

加载失败,请刷新页面

加载更多

下一页

CENTOS7防火墙命令记录

安装Firewall命令: yum install firewalld firewalld-config Firewall开启常见端口命令: firewall-cmd --zone=public --add-port=80/tcp --permanent firewall-cmd --zone=public --add-po......

cavion ⋅ 今天 ⋅ 0

【C++】【STL】利用chromo来测量程序运行时间与日志时间打印精确到微秒

直接上代码吧,没啥好说的。头疼。 #include <iostream>#include <string>#include <ctime>#include <sstream>#include <iomanip>#include <thread>#include <chrono>using ......

muqiusangyang ⋅ 今天 ⋅ 0

Mac环境下svn的使用

在Windows环境中,我们一般使用TortoiseSVN来搭建svn环境。在Mac环境下,由于Mac自带了svn的服务器端和客户端功能,所以我们可以在不装任何第三方软件的前提下使用svn功能,不过还需做一下简...

故久呵呵 ⋅ 今天 ⋅ 0

破解公司回应苹果“USB限制模式”:已攻破

本周四,苹果发表声明称 iOS 中加入了一项名为“USB 限制模式”的功能,可以防止 iPhone 在连接其他设备的时候被破解,并且强调这一功能并不是针对 FBI 等执法部门,为的是保护用户数据安全。...

六库科技 ⋅ 今天 ⋅ 0

MyBtais整合Spring Boot整合,TypeHandler对枚举类(enum)处理

概要 问题描述 我想用枚举类来表示用户当前状态,枚举类由 code 和 msg 组成,但我只想把 code 保存到数据库,查询处理,能知道用户当前状态,这应该怎么做呢?在 Spring 整合MyBatis 的时候...

Wenyi_Feng ⋅ 今天 ⋅ 0

synchronized与Lock的区别

# <center>王梦龙的读书笔记第一篇</center> ## <center>-synchronized与Lock的区别</centre> ###一、从使用场景来说 + synchronized 是能够注释代码块、类、方法但是它的加锁是和解锁使用一......

我不想加班 ⋅ 今天 ⋅ 0

VConsole的使用

手机端控制台打印输出,方便bug的排查。 首先需要引入vconsole.min.js 文件,然后在文件中创造实例。就能直接使用了。 var vConsole = new VConsole(); vConsole的文件地址...

大美琴 ⋅ 今天 ⋅ 0

Java NIO之字符集

1 字符集和编解码的概念 首先,解释一下什么是字符集。顾名思义,就是字符的集合。它的初衷是把现实世界的符号映射为计算机可以理解的字节。比如我创造一个字符集,叫做sex字符集,就包含两个...

士别三日 ⋅ 今天 ⋅ 0

Spring Bean基础

1、Bean之间引用 <!--如果Bean配置在同一个XML文件中,使用local引用--><ref bean="someBean"/><!--如果Bean配置在不同的XML文件中,使用ref引用--><ref local="someBean"/> 其实两种......

霍淇滨 ⋅ 今天 ⋅ 0

05、基于Consul+Upsync+Nginx实现动态负载均衡

1、Consul环境搭建 下载consul_0.7.5_linux_amd64.zip到/usr/local/src目录 cd /usr/local/srcwget https://releases.hashicorp.com/consul/0.7.5/consul_0.7.5_linux_amd64.zip 解压consu......

北岩 ⋅ 今天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部