Tigon MyBatis 0.0.4 发布,快来看呀,又有人重新发明轮子了

来源: 投稿
2020-12-09

2020年,再来点更惊奇的事情也不是什么惊奇的事情。

MyBatis是个很神奇的框架,能让各种神奇的人玩出更神奇的事情,您懂我的意思,随便到代码托管平台搜索,一大堆龙啊虎啊的都出来了。

为什么又要再发明一个MyBatis的衍生框架,主要是这么些年下来,自己总结的一些实践经验,和大家分享一下。

早几年就想开源了,奈何一直拖延爽。

Tigon MyBatis

简介

Tigon MyBatis为Spring工程中MyBatis的Mapper提供增强,主要有以下特点

  • 代码又少又壮,绝不做多余的事情
  • 仅需Mapper继承接口,实现   ,无额外配置,爽到没女朋友
  • 用完即走,毫不留恋

开始使用

  • 引入Maven依赖
<dependency>
  <groupId>me.chyxion.tigon</groupId>
  <artifactId>tigon-mybatis</artifactId>
  <version>0.0.4</version>
</dependency>

使用示例

下面是使用示例,可以在源代码中找到更详细的单元测试。Talk is cheep,read the fine source code.

定义Entity

package me.chyxion.tigon.mybatis.entity;

import lombok.Getter;
import lombok.Setter;
import java.util.Date;
import lombok.ToString;
import java.io.Serializable;
import me.chyxion.tigon.mybatis.Table;
import me.chyxion.tigon.mybatis.NotUpdate;

@Getter
@Setter
@ToString
@Table("tb_user")
public class User implements Serializable {
    private static final long serialVersionUID = 1L;

    private Integer id;
    @NotUpdate
    private String account;
    private String mobile;
    private String name;
    private Gender gender;
    private String password;
    private Date birthDate;
    private String city;
    private String avatar;

    private Boolean active;
    private String remark;
    private String createdBy;
    private Date createdAt;
    private String updatedBy;
    private Date updatedAt;

    public enum Gender {
        MALE,
        FEMALE
    }
}

定义Mapper

package me.chyxion.tigon.mybatis.mapper;

import java.util.List;
import me.chyxion.tigon.mybatis.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
import me.chyxion.tigon.mybatis.entity.User;

@Mapper
public interface UserMapper extends BaseMapper<Integer, User> {
}

注入Mapper对象

@Autowired
private UserMapper mapper;

I. 插入

final User user = new User();
user.setName("Donghuang");
user.setAccount("donghuang");
user.setMobile("137647788xx");
user.setPassword(RandomStringUtils.randomAlphanumeric(16));
user.setGender(User.Gender.MALE);
user.setBirthDate(DateUtils.parseDate("1994-04-04"));
user.setCity("Shanghai");
user.setActive(true);
user.setRemark("Uncle Donghuang");
user.setCreatedBy("donghuang");
user.setCreatedAt(new Date());

// single insert
mapper.insert(user);

final User user1 = new User();
user1.setName("Gemily");
user1.setAccount("gemily");
user1.setMobile("15770780xxx");
user1.setPassword(RandomStringUtils.randomAlphanumeric(16));
user1.setGender(User.Gender.FEMALE);
user1.setBirthDate(DateUtils.parseDate("1990-06-06"));
user1.setCity("Hangzhou");
user1.setActive(true);
user1.setCreatedBy("donghuang");
user1.setCreatedAt(new Date());

final User user2 = new User();
user2.setName("Luffy");
user2.setAccount("luffy");
user2.setMobile("137647799xx");
user2.setPassword(RandomStringUtils.randomAlphanumeric(16));
user2.setGender(User.Gender.MALE);
user2.setBirthDate(DateUtils.parseDate("1997-07-07"));
user2.setCity("East sea");
user2.setActive(true);
user2.setRemark("Luffy");
user2.setCreatedBy("donghuang");
user2.setCreatedAt(new Date());

// batch insert
mapper.insert(Arrays.asList(user1, user2));

II. 查询

根据ID查询单个对象

final Integer id = 1154;
final User user = mapper.find(id);

根据属性查询单个对象

final User user = mapper.find(
    new Search("account", "donghuang")
        .eq("mobile", "137647788xx"));

根据属性查询列表

final List<User> users = mapper.list(new Search()
    .between("birth_date",
        DateUtils.parseDate("1982-04-04"),
        DateUtils.parseDate("1994-04-04")
    )
    .eq("gender", User.Gender.MALE)
    .asc("birth_date")
    .limit(42));

Search对象支持的API

  • and And another Search
  • asc Order ASC
  • between Between two values
  • build Build query criterion
  • contains Value contains string
  • desc Order DSC
  • endsWith Value ends with string
  • eq Eqauls
  • gt Greater than
  • gte Eqauls or greater than
  • in In values
  • isNull Value is null
  • like Value like
  • limit Return rows limit
  • lt Less than
  • lte Eqauls or less than
  • ne Not equals
  • notIn Not in values
  • notNull Value is not null
  • offset Return rows offset
  • or Or another Search
  • orderBy Order by
  • startsWith Value starts with string

III. 更新

通过Entity根据ID更新

final User user = mapper.find(1);

user.setName("东皇大叔");
user.setUpdatedBy("SYS");
user.setUpdatedAt(new Date());

mapper.update(user);

通过Map<String, Object>更新

final Map<String, Object> update = new HashMap<>(6);
update.put("name", "东皇大叔");
update.put("updatedBy", "SYS");
update.put("updatedAt", new Date());

mapper.update(update, 1);
// OR
// mapper.update(update, new Search("id", 1));
// mapper.update(update, new Search(1));

更新列为NULL

// Update remark to NULL of id 274229
mapper.setNull("remark", 274229);
// Update remark to NULL of id 1154L
mapper.setNull("remark", new Search("id", 1154));
// Update all remarks to NULL. BE CAREFUL!!!
mapper.setNull("remark", new Search());

IV. 删除

通过ID删除数据

mapper.delete(1);

通过Search对象删除数据

mapper.delete(new Search("id", 1));

V. 杂项

除了上面说到的一些基础增删改查操作,还有一些实用功能,如@Transient @UseGeneratedKeys @NoPrimaryKey @NotUpdateWhenNull @RawValue等注解,插入、更新前回调,以及支持扩展自定义的方法等。

配置说明

  • SpringBoot项目,无需其他操作,引入依赖即可
  • Spring项目,注册Bean me.chyxion.tigon.mybatis.TigonMyBatisConfiguration
  • 业务Mapper继承me.chyxion.tigon.mybatis.BaseMapper或相关衍生Mapper,Base(Query, Insert, Update, Delete)Mapper

原理

Tigon MyBatis并不改变MyBatis相关功能,所做的只是在程序启动期间检测业务Mapper接口,如果继承了相关BaseMapper.java,则注入相关方法MappedStatement,具体逻辑参见源码,超简单,超幼稚。

其他

在前面使用Search的例子中,我们需要一些User的属性常量字符串,比如

final User user = mapper.find(new Search("account", "donghuang"));

可以将这些常量定义在User类中,如

public static final String ACCOUNT = "account";

使用过程中可以使用属性常量,如

final User user = mapper.find(new Search(User.ACCOUNT, "donghuang"));

也可以使用Lombok@FieldNameConstants注解生成,只是这个注解还处于试验阶段,有一定不稳定风险。

最后

为什么要有这个项目,其实这些代码本人从2014年就陆续在写在用,在自己参与的一些项目里默默奉献。

有想过开源,奈何一直忙着修福报,此外很重要的一点是,觉得方案并不完善,还是比较长比较臭。

开源界已经有很多MyBatis相关的项目了,包括官方出品的mybatis-dynamic-sql,这玩意把我可恶心坏了。最近接触的项目里有在用,看着那一坨一坨的完全没动力碰的垃圾代码,全世界都在看我们的笑话,Java什么时候变成这样了,让玩PHP,玩C#,玩GO,玩Ruby的同学怎么看待我们,哎卧槽。

魔幻2020年就快结束了,熬夜把拖延了好几年的待办事项做个了结,后续如果还有精力,我会考虑把生成代码的逻辑一并释放出来。

展开阅读全文
5 收藏
分享
加载中
精彩评论
这有这个时间喝能力,还不如把贡献在mp上。
2020-12-11 01:25
1
举报
对的,重复发明轮子(Reinventing the wheel),说重复造轮子的都是讹译。
2020-12-10 22:13
1
举报
最新评论 (9)
重新得改为重复才符合业务逻辑。
2021-01-01 10:05
0
回复
举报
这有这个时间喝能力,还不如把贡献在mp上。
2020-12-11 01:25
1
回复
举报
发明?这标题造的...
2020-12-10 20:35
0
回复
举报
对的,重复发明轮子(Reinventing the wheel),说重复造轮子的都是讹译。
2020-12-10 22:13
1
回复
举报
挺好的,我用jfinal ActiveRecored 真香
2020-12-10 14:26
0
回复
举报
环肥燕瘦,各有所好
2020-12-10 22:14
0
回复
举报
与mybatis-plus 颇有些相似。
2020-12-10 14:20
0
回复
举报
思路是一样的, 都是放弃手写sql, 这种轮子我也造过
2020-12-10 15:39
0
回复
举报
证明MyBatis的魅力,大家的想法都差不多。
2020-12-10 16:51
0
回复
举报
更多评论
9 评论
5 收藏
分享
返回顶部
顶部