文档章节

扩展Mybatis的能力Mapper使用记录

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

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

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

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

qq_35246620
2017/02/02
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
Mybatis 通用 Mapper 3.3.1 发布

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

Liuzh_533
2015/12/11
3.9K
10

没有更多内容

加载失败,请刷新页面

加载更多

OSX | SafariBookmarksSyncAgent意外退出解决方法

1. 启动系统, 按住⌘-R不松手2. 在实用工具(Utilities)下打开终端,输入csrutil disable, 然后回车; 你就看到提示系统完整性保护(SIP: System Integrity Protection)已禁用3. 输入reboot回车...

云迹
今天
3
0
面向对象类之间的关系

面向对象类之间的关系:is-a、has-a、use-a is-a关系也叫继承或泛化,比如大雁和鸟类之间的关系就是继承。 has-a关系称为关联关系,例如企鹅在气候寒冷的地方生活,“企鹅”和“气候”就是关...

gackey
今天
4
0
读书(附电子书)|小狗钱钱之白色的拉布拉多

关注公众号,在公众号中回复“小狗钱钱”可免费获得电子书。 一、背景 之前写了一篇文章 《小狗钱钱》 理财小白应该读的一本书,那时候我才看那本书,现在看了一大半了,发现这本书确实不错,...

tiankonguse
今天
4
0
Permissions 0777 for ‘***’ are too open

异常显示: @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @ WARNING: UNPROTECTED PRIVATE KEY FILE! @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ......

李玉长
今天
5
0
区块链10年了,还未落地,它失败了吗?

导读 几乎每个人,甚至是对通证持怀疑态度的人,都对区块链的技术有积极的看法,因为它有可能改变世界。然而,区块链技术问世已经10年了,我们仍然没有真正的用上区块链技术。 几乎每个人,甚...

问题终结者
今天
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部