使用FluentMybatis实现mybatis动态sql拼装和fluent api语法

开始第一个例子: Hello World

新建Java工程,设置maven依赖

    新建maven工程,设置项目编译级别为Java8及以上,引入fluent mybatis依赖包。

```xml

<dependencies>

    <!-- 引入fluent-mybatis 运行依赖包, scope为compile -->

    <dependency>

        <groupId>com.github.atool</groupId>

        <artifactId>fluent-mybatis</artifactId>

        <version>1.3.1</version>

    </dependency>

    <!-- 引入fluent-mybatis-processor, scope设置为provider 编译需要,运行时不需要 -->

    <dependency>

        <groupId>com.github.atool</groupId>

        <artifactId>fluent-mybatis-processor</artifactId>

        <version>1.3.1</version>

    </dependency>

</dependencies>

```

### 新建演示用的数据库结构

```mysql

create schema fluent_mybatis_tutorial;

create table hello_world

(

    id          bigint unsigned auto_increment primary key,

    say_hello    varchar(100) null,

    your_name    varchar(100) null,

    gmt_create  datetime  DEFAULT NULL COMMENT '创建时间',

    gmt_modified datetime  DEFAULT NULL COMMENT '更新时间',

    is_deleted  tinyint(2) DEFAULT 0 COMMENT '是否逻辑删除'

) ENGINE = InnoDB

  CHARACTER SET = utf8 comment '简单演示表';

```

创建数据库表对应的Entity类

    创建数据库表对应的Entity类: HelloWorldEntity, 你只需要简单的做3个动作:

1. 根据驼峰命名规则命名Entity类和字段

2. HelloWorldEntity继承IEntity接口类

3. 在HelloWorldEntity类上加注解 @FluentMybatis

```java

@FluentMybatis

public class HelloWorldEntity implements IEntity {

    private Long id;

    private String sayHello;

    private String yourName;

    private Date gmtCreate;

    private Date gmtModified;

    private Boolean isDeleted;


    // get, set, toString 方法

}

```

很简单吧,在这里,你即不需要配置任何mybatis xml文件, 也不需要写任何Mapper接口, 但你已经拥有了强大的增删改查的功能,并且是Fluent API,让我们写一个测试来见证一下Fluent Mybatis的魔法力量!

### 运行测试来见证Fluent Mybatis的神奇

为了运行测试, 我们还需要进行JUnit和Spring Test相关配置。

#### 配置spring bean定义

1. 数据源DataSource配置

2. mybatis的mapper扫描路径

3. mybatis的SqlSessionFactoryBean

```java

@ComponentScan(basePackages = "cn.org.atool.fluent.mybatis.demo1")

@MapperScan("cn.org.atool.fluent.mybatis.demo1.entity.mapper")

@Configuration

public class HelloWorldConfig {

    /**

    * 设置dataSource属性

    *

    * @return

    */

    @Bean

    public DataSource dataSource() {

        BasicDataSource dataSource = new BasicDataSource();

        dataSource.setDriverClassName("com.mysql.jdbc.Driver");

        dataSource.setUrl("jdbc:mysql://localhost:3306/fluent_mybatis_tutorial?useUnicode=true&characterEncoding=utf8");

        dataSource.setUsername("root");

        dataSource.setPassword("password");

        return dataSource;

    }

    /**

    * 定义mybatis的SqlSessionFactoryBean

    *

    * @param dataSource

    * @return

    */

    @Bean

    public SqlSessionFactoryBean sqlSessionFactoryBean(DataSource dataSource) {

        SqlSessionFactoryBean bean = new SqlSessionFactoryBean();

        bean.setDataSource(dataSource);

        return bean;

    }

}

```

#### 使用Junit4和Spring-test来执行测试

1. 使用spring-test初始化spring容器

2. 注入HelloWorldEntity对应的Mapper类: HelloWorldMapper, 这个类是fluent mybatis编译时生成的。

3. 使用HelloWorldMapper进行删除、插入、查询、修改操作。

```java

@RunWith(SpringJUnit4ClassRunner.class)

@ContextConfiguration(classes = HelloWorldConfig.class)

public class HelloWorldTest {

    /**

    * fluent mybatis编译时生成的Mapper类

    */

    @Autowired

    HelloWorldMapper mapper;

    @Test

    public void testHelloWorld() {

        /**

        * 为了演示方便,先删除数据

        */

        mapper.delete(mapper.query()

            .where.id().eq(1L).end());

        /**

        * 插入数据

        */

        HelloWorldEntity entity = new HelloWorldEntity();

        entity.setId(1L);

        entity.setSayHello("hello world");

        entity.setYourName("fluent mybatis");

        entity.setIsDeleted(false);

        mapper.insert(entity);

        /**

        * 查询 id = 1 的数据

        */

        HelloWorldEntity result1 = mapper.findOne(mapper.query()

            .where.id().eq(1L).end());

        /**

        * 控制台直接打印出查询结果

        */

        System.out.println("1. HelloWorldEntity:" + result1.toString());

        /**

        * 更新id = 1的记录

        */

        mapper.updateBy(mapper.updater()

            .update.sayHello().is("say hello, say hello!")

            .set.yourName().is("fluent mybatis is powerful!").end()

            .where.id().eq(1L).end()

        );

        /**

        * 查询 id = 1 的数据

        */

        HelloWorldEntity result2 = mapper.findOne(mapper.query()

            .where.sayHello().like("hello")

            .and.isDeleted().eq(false).end());

        /**

        * 控制台直接打印出查询结果

        */

        System.out.println("2. HelloWorldEntity:" + result2.toString());

    }

}

```

执行Junit4测试方法,控制台输出

```text

1. HelloWorldEntity:HelloWorldEntity{id=1, sayHello='hello world', yourName='fluent mybatis', gmtCreate=null, gmtModified=null, isDeleted=false}

2. HelloWorldEntity:HelloWorldEntity{id=1, sayHello='say hello, say hello!', yourName='fluent mybatis is powerful!', gmtCreate=null, gmtModified=null, isDeleted=false}

```

神奇吧! 我们再到数据库中查看一下结果

![-w300](https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/1c6fbb06a162465aba70ffbf400fbff1~tplv-k3u1fbpfcp-zoom-1.image)

现在,我们已经通过一个简单例子演示了fluent mybatis的强大功能,

在进一步介绍fluent mybatis更强大功能前,我们揭示一下为啥我们只写了一个数据表对应的Entity类,

却拥有了一系列增删改查的数据库操作方法。

fluent mybatis根据Entity类上@FluentMybatis注解在编译时,

会在target目录class目录下自动编译生成一系列文件:

![-w300](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/c07c4b6ddcda4b2d899c2aa89889304c~tplv-k3u1fbpfcp-zoom-1.image)

- 核心接口类, 使用时需要了解

1. mapper/*Mapper: mybatis的Mapper定义接口, 定义了一系列通用的数据操作接口方法。

2. dao/*BaseDao: Dao实现基类, 所有的DaoImpl都继承各自基类

  根据分层编码的原则,我们不会在Service类中直接使用Mapper类,而是引用Dao类。我们在Dao实现类中根据条件实现具体的数据操作方法。

3. wrapper/*Query: fluent mybatis核心类, 用来进行动态sql的构造, 进行条件查询。

4. wrapper/*Updater: fluent mybatis核心类, 用来动态构造update语句。

5. *EntityHelper: Entity帮助类, 实现了Entity和Map的转换方法

- 辅助实现时, 实现fluent mybatis动态sql拼装和fluent api时内部用到的类,使用时无需了解

在使用上,我们主要会接触到上述5个生成的java类。Fluent Mybatis为了实现动态拼接和Fluent API功能,还生成了一系列辅助类。

1. helper/*Mapping: 表字段和Entity属性映射定义类

2. helper/*SqlProviderP: Mapper接口动态sql提供者

3. helper/*WrapperHelper: Query和Updater具体功能实现, 包含几个实现:select, where, group by, having by, order by, limit

[Fluent Mybatis源码, gitee](https://gitee.com/fluent-mybatis/fluent-mybatis)

[Fluent Mybatis文档&示例](https://gitee.com/fluent-mybatis/fluent-mybatis-docs)

[Fluent Mybatis源码, github](https://github.com/atool/fluent-mybatis)

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,772评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,458评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,610评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,640评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,657评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,590评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,962评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,631评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,870评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,611评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,704评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,386评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,969评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,944评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,179评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,742评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,440评论 2 342