# 使用指南

# 概述

# 什么是dbapi-spring-boot-starter

  • dbapi-spring-boot-starter 是一款极低代码的ORM框架,可以极大的降低代码量,类似于mybatis-plus框架,不需要再编写mapper接口、resultMap、resultType、javaBean(数据库表对应的java实体)
  • 通过xml编写sql和数据库配置,可以快速开发接口,支持多数据源,支持动态sql,支持所有数据源(jdbc协议),比如mysql/postgresql/hive/sqlserver/oracle/impala/doris
  • dbapi-spring-boot-starter 是DBAPI开源框架 (opens new window) 的spring boot集成

# 对比mybatis优劣

  • 如果使用mybatis框架的话,我们要编写 mapper java接口、mapper.xml、数据库表对应的javaBean实体类。当join查询的时候还要封装resultMap(xml)和java dto实体类。
  • 如果使用本框架,相当于只需要编写mapper.xml中的sql脚本,参数类型、返回类型都是自动的。极大的减少代码量。

# 适用场景

  • 接口中没有复杂逻辑,都是sql执行,尤其适用于报表类应用开发
  • 需要灵活的对接多种数据源

# 快速开始

# 引入依赖

<dependency>
    <groupId>com.gitee.freakchicken</groupId>
    <artifactId>dbapi-spring-boot-starter</artifactId>
    <version>1.1.0</version>
</dependency>

# 使用案例

  • 新建一个springboot的web项目,pom.xml中引入依赖
<dependency>
    <groupId>com.gitee.freakchicken</groupId>
    <artifactId>dbapi-spring-boot-starter</artifactId>
    <version>1.1.0</version>
</dependency>
<!--需要引入数据库的jdbc驱动-->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.15</version>
</dependency>
  • resources目录下创建数据库地址配置文件ds.xml
<datasources>
    <datasource id="test_mysql">
        <url>jdbc:mysql://localhost:3306/test?useSSL=false&amp;characterEncoding=UTF-8</url>
        <username>root</username>
        <password>root</password>
        <driver>com.mysql.cj.jdbc.Driver</driver>
    </datasource>

    <datasource id="log_mysql">
        <url>jdbc:mysql://localhost:3306/dbapi_log?useSSL=false&amp;characterEncoding=UTF-8</url>
        <username>root</username>
        <password>root</password>
        <driver>com.mysql.cj.jdbc.Driver</driver>
    </datasource>

</datasources>
  • resources目录下创建sql目录,并在sql目录下新建两个文件user.xml log.xml
  • user.xml
<sqls>
    <defaultDB>test_mysql</defaultDB>

    <sql id="getAllUser">
        select * from student
    </sql>

    <sql id="getUserIn" db="test_mysql">
        select * from user where id in
        <foreach collection="ids" open="(" close=")" separator=",">
            #{item}
        </foreach>

    </sql>

    <sql id="getUserById">
        select * from student where id = #{id}
    </sql>

    <sql id="createStudent">
        insert into student (name,age) values (#{name},#{age})
    </sql>

    <sql id="deleteAll">
        delete from student
    </sql>

</sqls>
  • log.xml
<sqls>
    <defaultDB>log_mysql</defaultDB>

    <sql id="getAllLog">
        select * from access_log
    </sql>

</sqls>
  • application.properties中配置xml地址
dbapi.config.datasource=classpath:ds.xml
dbapi.config.sql=classpath:sql/*.xml
  • 新建controller,注入DBAPI,通过DBAPI就可以执行sql
package com.demo.controller;


import com.alibaba.fastjson.JSONObject;
import com.demo.entity.Student;
import com.gitee.freakchicken.DBAPI;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Slf4j
@RequestMapping("/student")
@RestController
public class HomeController {

    @Autowired
    DBAPI dbapi;

    @RequestMapping("/getAll")
    public List<JSONObject> getAllStudent() {
        List<JSONObject> jsonObjects = dbapi.executeQuery("user", "getAllUser");
        return jsonObjects;
    }

    @RequestMapping("/getUserById")
    public List<JSONObject> getStudentById(Integer id) {
        Map<String, Object> map = new HashMap<>();
        map.put("id", id);
        List<JSONObject> jsonObjects = dbapi.executeQuery("user", "getUserById", map);
        return jsonObjects;
    }

    @RequestMapping("/getUserById/entity")
    public List<Student> getStudentById2(Integer id) {
        Map<String, Object> map = new HashMap<>();
        map.put("id", id);
        List<Student> list = dbapi.executeQueryEntity("user", "getUserById", map, Student.class);
        return list;
    }

    @RequestMapping("/add")
    public Integer add(String name, Integer age) {
        Map<String, Object> map = new HashMap<>();
        map.put("name", name);
        map.put("age", age);
        int i = dbapi.executeUpdate("user", "createStudent", map);
        return i;
    }

    @RequestMapping("/deleteAll")
    public Integer deleteAll(String name, Integer age) {
        int i = dbapi.executeUpdate("user", "deleteAll");
        return i;
    }

    @RequestMapping("/getAllLog")
    public List<JSONObject> getAllLog() {
        List<JSONObject> list = dbapi.executeQuery("log", "getAllLog");
        return list;
    }

}

# xml配置详解

# 数据库配置

  • 使用datasource标签来指定, datasource标签有个id属性,值是任意字符串,这个id必须全局唯一,sql配置的时候会指定db属性,也就是指向这个id
  • 如果有多个数据库账号,可以写多个
<datasources>
    <datasource id="test_mysql">
        <url>jdbc:mysql://localhost:3306/test?useSSL=false&amp;characterEncoding=UTF-8</url>
        <username>root</username>
        <password>root</password>
        <driver>com.mysql.cj.jdbc.Driver</driver>
    </datasource>

</datasources>

# sql配置

  • 类似mybatis的语法,使用<sql>标签, 标签上有id和db两个属性,id必须在当前xml文件内全局唯一,执行的时候根据这个id查找到sql内容,sql内容是动态sql,语法和mybatis一样。 db属性指定了数据库地址的id,必须在数据库配置的xml中能找到,也就是这个sql使用db对应的数据库来执行
  • <defaultDB>配置默认db,如果配置了该选项,那么<sql>标签可以不用加db属性
<sqls>
    <defaultDB>xxx</defaultDB>
    <sql id="xxx" db="xxx">
        xxx
    </sql>
    
    <sql id="xxx" db="xxx">
        xxx
    </sql>
   
</sqls>

# API

  • springboot 项目中使用需要先注入DBAPI对象
@Autowired
DBAPI dbapi;

# 执行查询类SQL

执行查询类SQL有以下4个方法:

# 带参数的默认查询

public List<JSONObject> executeQuery(String namespace, String sqlId, Map<String, Object> data)

  • 其中第1个参数namespace就是xml文件的名称,第2个参数就是<sql>标签上的id,第3个参数是SQL执行需要的参数
  • 返回结果是List<JSONObject>
  • 例如以下,表示去user.xml文件寻找到id为getUserById对应的 <sql>标签中的sql来执行
Map<String, Object> map = new HashMap<>();
map.put("id", id);
List<JSONObject> list = dbapi.executeQuery("user", "getUserById", map);

# 不带参数的默认查询

public List<JSONObject> executeQuery(String namespace, String sqlId)

  • 其中第1个参数namespace就是xml文件的名称,第2个参数就是<sql>标签上的id
  • 返回结果是List<JSONObject>
  • 例如以下,表示去user.xml文件寻找到id为getAllUser对应的 <sql>标签中的sql来执行
List<JSONObject> list = dbapi.executeQuery("user", "getAllUser");;

# 带参数的查询,并返回JAVA实体类

public <T> List<T> executeQueryEntity(String namespace, String sqlId, Map<String, Object> data, Class<T> clazz)

  • 其中第1个参数namespace就是xml文件的名称,第2个参数就是<sql>标签上的id,第3个参数是SQL执行需要的参数,第4个参数是返回结果需要映射成的java实体类
  • 返回结果是java实体类对应的List
  • 例如以下,表示去user.xml文件寻找到id为getUserById对应的 <sql>标签中的sql来执行,并把结果映射成Student实体类
Map<String, Object> map = new HashMap<>();
map.put("id", id);
List<Student> list = dbapi.executeQueryEntity("user", "getUserById", map, Student.class);

# 不带参数的查询,并返回JAVA实体类

public <T> List<T> executeQueryEntity(String namespace, String sqlId, Class<T> clazz)

  • 其中第1个参数namespace就是xml文件的名称,第2个参数就是<sql>标签上的id,第3个参数是返回结果需要映射成的java实体类
  • 返回结果是java实体类对应的List
  • 例如以下,表示去user.xml文件寻找到id为getAllUser对应的 <sql>标签中的sql来执行,并把结果映射成Student实体类
List<Student> list = dbapi.executeQuery("user", "getAllUser", Student.class);;

# 执行非查询类SQL

# 带参数的非查询

public int executeUpdate(String namespace, String sqlId, Map<String, Object> data)

  • 其中第1个参数namespace就是xml文件的名称,第2个参数就是<sql>标签上的id,第3个参数是SQL执行需要的参数
  • 返回结果是更新的数据行数
  • 例如以下,表示去user.xml文件寻找到id为createStudent对应的 <sql>标签中的sql来执行
Map<String, Object> map = new HashMap<>();
map.put("name", name);
map.put("age", age);
int i = dbapi.executeUpdate("user", "createStudent", map);

# 不带参数的非查询

public int executeUpdate(String namespace, String sqlId)

  • 其中第1个参数namespace就是xml文件的名称,第2个参数就是<sql>标签上的id
  • 返回结果是更新的数据行数
  • 例如以下,表示去user.xml文件寻找到id为deleteAll对应的 <sql>标签中的sql来执行
int i = dbapi.executeUpdate("user", "deleteAll");