Foxnic-SQL (7) —— DAO 特性 : 执行 SQL 语句

LeeFJ
• 阅读 401

Foxnic-SQL (7) —— DAO 特性 : 执行 SQL 语句

概述

  Foxnic-SQL 支持多种语句执行方式,包括直接执行SQL字符串、执行SQL对象,SQL对象自执行,多语句执行与批量执行。Foxnic-SQL 显著的特征是 DAO 对象既可以执行字符串的 SQL 语句,也可以执行对象化的SQL语句。
本文中的示例代码均可在 https://gitee.com/LeeFJ/foxnic-samples 项目中找到。

执行SQL字符串

  SQL 执行最快捷、最能上手的方式,就是直接执行 SQL 字符串。DAO 对象可以执行不带参数或带参数的 SQL 字符串。如下代码所示:

/**
* 1、直接传入字符串的 SQL 语句,并执行
* */
public static void  demo1() {
    // 通过 DBInstance 拿到 DAO 对象
    DAO dao= DBInstance.DEFAULT.dao();
    // 生成 ID
    String id= IDGenerator.getNanoId(8);
    // 插入
    String insert="insert into example_address (id, name, phone_number, address, region_type, region_location, create_by, " +
        "create_time, update_by, update_time, deleted, delete_by, delete_time, version) " +
        "VALUES (?, ?, ?, ?, ?, NULL, NULL, ?, ?, ?, 0, NULL, NULL, 1)";
    int i=dao.execute(insert,id,"leefj","13852562523","宁波","国内",new Date(),"110", new Date());
    Logger.info("插入 : "+i);
    // 更新
    i=dao.execute("update example_address set address=? where id=?","上海",id);
    Logger.info("更新 : "+i);
    // 删除
    i=dao.execute("delete from example_address where id=?",id);
    Logger.info("删除 : "+i);
}

执行 SQL 对象

  DAO 对象同样支持对象话的SQL语句执行。SQL对象化的好处在之前的章节中已经介绍,感兴趣的读者可以查看 Foxnic-SQL 之前的文章《SQL表达式(Expr)》。示例代码如下所示:

import com.github.foxnic.commons.busi.id.IDGenerator;
import com.github.foxnic.dao.data.Rcd;
import com.github.foxnic.sql.expr.Delete;
import com.github.foxnic.sql.expr.Insert;
import com.github.foxnic.sql.expr.Select;
import com.github.foxnic.sql.expr.Update;
import com.leefj.foxnic.sql.demo.config.DBInstance;

import java.util.Date;

public class CRUDBySQLDemo {

    public static void main(String[] args) {
        // 插入数据
        String id=insertAddress("137771041252");
        System.out.println("addressId(Insert) = "+id);
        // 按ID查询数据
        Rcd address=queryAddress(id);
        if(address!=null) {
            System.out.println(address.toJSONObject());
        }
        // 更新
        if(id!=null) {
            id=updateAddress(id,"13852562523");
            System.out.println("addressId(Update) = "+id);
        }
        // 删除
        if(id!=null) {
            id=deleteAddress(id);
            System.out.println("addressId(Delete) = "+id);
        }
    }

    /**
    * 插入数据
    * */
    public static String insertAddress(String phone) {
        // 创建语句对象
        Insert insert=new Insert("example_address");
        String id= IDGenerator.getSnowflakeIdString();
        // 设置值
        insert.set("id",id)
            .set("name","leefj")
            // 如果是 null 则不连入SQL语句
            .setIf("phone_number",phone)
            .set("address","宁波")
            .set("region_type","国内")
            .set("create_time",new Date())
            // 设置数据库表达式
            .setExpr("update_time","now()");
        // 输出语句
        System.out.println(insert.getSQL());
        // 执行语句
        Integer suc=DBInstance.DEFAULT.dao().execute(insert);
        // 如果执行成功,返回ID,否则返回 null
        if(suc==1) {
            return id;
        } else {
            return null;
        }
    }

    /**
    * 查询
    * */
    public static Rcd queryAddress(String id) {

        // 创建语句对象
        Select select=new Select("example_address");
        // 设置值
        select.where().and("id=?",id);
        // 输出语句
        System.out.println(select.getSQL());
        // 执行语句
        Rcd address=DBInstance.DEFAULT.dao().queryRecord(select);
        // 如果执行成功,返回记录对象,否则返回 null
        return address;
    }

    /**
    * 更新
    * */
    public static String updateAddress(String id,String phone) {
        // 创建语句对象
        Update update=new Update("example_address");
        // 设置值
        update.setIf("phone_number",phone)
            // 设置数据库表达式
            .setExpr("update_time","now()")
            .set("update_by","110")
            .where().and("id=?",id);
        // 输出语句
        System.out.println(update.getSQL());
        // 执行语句
        Integer suc=DBInstance.DEFAULT.dao().execute(update);
        // 如果执行成功,返回ID,否则返回 null
        if(suc==1) {
            return id;
        } else {
            return null;
        }
    }

    /**
    * 删除
    * */
    public static String deleteAddress(String id) {
        // 创建语句对象
        Delete delete=new Delete("example_address");
    // 设置条件
    delete.where().and("id=?",id);
    // 输出语句
    System.out.println(delete.getSQL());
    // 执行语句
    Integer suc=DBInstance.DEFAULT.dao().execute(delete);
    // 如果执行成功,返回ID,否则返回 null
    if(suc==1) {
        return id;
    } else {
        return null;
    }
  }
}

ExecutableSQL 方式执行

  ExecutableSQL 是一个接口,所有实现 ExecutableSQL 接口的 SQL 类都具备语句的执行能力。各种类型的 ExecutableSQL 可以通过 DAO 对象直接创建。示例如下:

/**
* 3、利用SQL对象的  ExecutableSQL 特性执行
* */
public static void  demo3() {

    // 通过 DBInstance 拿到 DAO 对象
    DAO dao= DBInstance.DEFAULT.dao();
    // 生成 ID
    String id= IDGenerator.getNanoId(8);

    // 插入:通过 DAO 创建一个与 DAO 绑定的 Insert 语句对象
    int i=dao.insert("example_address")
        .set("id",id)
        .set("name","leefj")
        // 如果是 null 则不连入SQL语句
        .setIf("phone_number","13852562523")
        .set("address","宁波")
        .set("region_type","国内")
        .set("create_time",new Date())
        // 设置数据库表达式
        .setExpr("update_time","now()")
        // 执行语句
        .execute();
    Logger.info("插入 : "+i);

    // 更新
    i=dao.update("example_address").set("address","上海")
        .where("id=?",id)
        // 返回至顶层的 Update 语句对象
        .top()
        .execute();
    Logger.info("更新 : "+i);

    // 删除
    i=dao.delete("example_address")
        .where("id=?",id)
        // 返回至顶层的 Update 语句对象
        .top()
        .execute();
    Logger.info("删除 : "+i);
}

多语句执行

  多语句执行顾名思义就是将多个语句放在一起执行,它们将在一个事务内执行,在不调用事务接口时,可以使用该方法以支持事务。示例代码如下:

/**
* 多个语句一起执行,这些语句在一个事务内
* */
public static void demo1() {

    // 通过 DBInstance 拿到 DAO 对象
    DAO dao= DBInstance.DEFAULT.dao();
    // 生成 ID
    String id= IDGenerator.getNanoId(8);
    // 插入
    Expr insert=new Expr("insert into example_address (id, name, phone_number, address, region_type, region_location, create_by, create_time, update_by, update_time, deleted, delete_by, delete_time, version) " +
                         "VALUES (?, ?, ?, ?, ?, NULL, NULL, ?, ?, ?, 0, NULL, NULL, 1)",
                         id,"leefj","13852562523","宁波","国内",new Date(),"110", new Date());
    Expr update=new Expr("update example_address set address=? where id=?","上海",id);
    Expr delete=new Expr("delete from example_address where id=?",id);
    // 事务内同时执行多个语句,多参数并列
    Integer result=dao.multiExecute(insert,update,delete);
    // 把多个语句单独执行时影响的行数累加后返回
    Logger.info("result = "+result);

    // 产生一个 SQL 对象与字符串混合的 List
    String sqlstr="delete from example_address where id='"+id+"'";
    List sqls= Arrays.asList(insert,update,delete,sqlstr);
    // 事务内同时执行多个语句,传入列表,
    result=dao.multiExecute(sqls);
    // 把多个语句单独执行时影响的行数累加后返回
    Logger.info("result = "+result);

}

批量执行

  批量执行是在大量插入或更新数据是使用的一种高性能的执行方式,这种方式可以显著提高SQL的执行效率。下面这个示例同时用常规方法和批量执行插入数据,批量的时间只有占常规的1/3。

/**
* 批量执行
* */
public static void demo1() {

    // 通过 DBInstance 拿到 DAO 对象
    DAO dao= DBInstance.DEFAULT.dao();

    // 准备插入的 SQL 语句
    String insert="insert into example_address " +
        "(id, name, phone_number, address, region_type, region_location, create_by, create_time, " +
        "update_by, update_time, deleted, delete_by, delete_time, version) " +
        "values (?, ?, ?, ?, ?, null, null, ?, ?, ?, 0, null, null, 1)";
    // 性能日志对象
    PerformanceLogger logger=new PerformanceLogger();
    // 性能采集埋点
    logger.collect("常规插入开始");
    for (int i = 0; i < 100; i++) {
        String id="batch-"+IDGenerator.getNanoId(6);
        dao.execute(insert,id,"leefj","13852562523","宁波","国内",new Date(),"110", new Date());
    }
    // 性能采集埋点
    logger.collect("常规插入结束");
    // 性能采集埋点
    logger.collect("批量插入开始");
    BatchParamBuilder paramBuilder=new BatchParamBuilder();
    for (int i = 0; i < 100; i++) {
        String id="batch-"+IDGenerator.getNanoId(6);
        paramBuilder.add(id,"leefj","13852562523","宁波","国内",new Date(),"110", new Date());
    }
    int[] result=dao.batchExecute(insert,paramBuilder.getBatchList());
    // 性能采集埋点
    logger.collect("批量插入结束");
    // 打印性能对比
    logger.info("执行效率对比");
    // 输出结果
    for (int i : result) {
        System.out.println("结果:"+ i);
    }
}

  性能对比日志:

┏━━━ PERFORMANCE [ 执行效率对比 , total = 4240 ] ━━━ ┣ point : 常规插入开始 ┣━ cost : 2961 ┣ point : 常规插入结束 ┣━ cost : 0 ┣ point : 批量插入开始 ┣━ cost : 1279 ┣ point : 批量插入结束 ┗━━━ PERFORMANCE [ 执行效率对比 , total = 4240 ] ━━━

小结

  本节主要介绍了如何使用 Foxnic-SQL 的 DAO 对象使用不同的姿势执行 SQL 语句。本节中展示的例子主要目的是抛砖引玉,为了方便不同场景的调用,DAO 还提供了若干重载方法,以不同的参数形式去执行语句。

相关项目

  https://gitee.com/LeeFJ/foxnic
  https://gitee.com/LeeFJ/foxnic-web
  https://gitee.com/lank/eam
  https://gitee.com/LeeFJ/foxnic-samples

官方文档

  http://foxnicweb.com/docs/doc.html

点赞
收藏
评论区
推荐文章
Wesley13 Wesley13
3年前
mysqldump导出数据时,如何调整每个insert语句的values值的数量?
当我们对一个包含1千万行记录的表history执行导出时,假设只用的备份语句如下:  mysqldumpurootp'123456' setgtidpurgedOFFtdbhistoryhistory.sql当我们执行表的恢复时,执行如下语句:mysqlsourcehistory.sql。。。Query
Wesley13 Wesley13
3年前
mysql数据库delete数据时不支持表别名
  今天在帮同事查看一条删除的SQL语句执行出错的问题  SQL语句如下:1DELETEFROMLEAD_SYSTEM_MENU_ORG_REFastWHEREt.resourceid'4028812348f28b890148f29253a80000'这条SQL语句放到Oracle数据库中去执行是可以正常执行的,但是放到M
Stella981 Stella981
3年前
Python Django 之 直接执行自定义SQL语句(一)
一、执行自定义SQL方法1、ExecutingcustomSQLdirectly   直接执行自定义SQL,这种方式可以完全避免数据模型,而是直接执行原始的SQL语句。2、Manager.raw()   执行原始查询并返回模型实例二、ExecutingcustomSQLdire
Stella981 Stella981
3年前
Hibernate原生SQL查询
Hibernate除了支持HQL查询外,还支持原生SQL查询。对原生SQL查询执行的控制是通过SQLQuery接口进行的,通过执行Session.createSQLQuery()获取这个接口。该接口是Query接口的子接口。执行SQL查询步骤如下:1、获取HibernateSession对象2、编写SQL语句3、通过Session的createS
Wesley13 Wesley13
3年前
thinkPHP框架中执行原生SQL语句的方法
这篇文章主要介绍了thinkPHP框架中执行原生SQL语句的方法,结合实例形式分析了thinkPHP中执行原生SQL语句的相关操作技巧,并简单分析了query与execute方法的使用区别,需要的朋友可以参考下本文实例讲述了thinkPHP框架中执行原生SQL语句的方法。分享给大家供大家参考,具体如下:怎样在thinkphp里面执行原生的sql语句?
Wesley13 Wesley13
3年前
Mysql的学习6____事物,索引,备份,视图,触发器
1.Mysql事务:就是将一组的SQL语句放在一个批次去执行,要是一条语句出错,该批次的SQL语句都会取消执行。Mysql事物处理只支持InnoDB和BDB数据表类型。1.1事物的ACID原则:原子性(Atomic):事物中的SQL语句要么全部执行,要么全不执行,不可能停滞在中间的某个状态,若在执行中发生了错误,会进行事物的回滚(Rol
3A网络 3A网络
2年前
输入的查询 SQL 语句,是如何执行的?
输入的查询SQL语句,是如何执行的?执行如下SQL,我们看到的只是输入一条语句,返回一个结果,却不知道这条语句在MySQL内部的执行过程。textselectfromwhereid'1';上图给出的是MySQL的基本架构示意图,从中你可以清楚地看到SQL语句在MySQL的各个功能模块中的执行过程。大体来说,MySQL可以分为
LeeFJ LeeFJ
2年前
Foxnic-SQL (1) —— 快速入门(QuickStart)
<aname"k9Sn5"</aFoxnicSQL(1)——简介<aname"XffCP"</a概述FoxnicSQL是基于SpringJDBC开发的SQL语句执行与数据处理框架。她扩展
LeeFJ LeeFJ
2年前
Foxnic-SQL (5) —— 创建与初始化DAO
DAO对象是FoxnicSQL执行语句并返回结果的核心对象。它包含了众多方法,包括语句的执行、查询、序列、存储过程,元数据等。本文中的示例代码均可在https://gitee.com/LeeFJ/foxnicsamples项目中找到。
LeeFJ LeeFJ
1年前
Foxnic-SQL (13) —— 外部SQL与SQL模版
首先,大多数时候,我们的第一反应是用字符串去拼接SQL语句,这说明字符串拼接方式其实是最直观的。其次,使用对象化的方式拼接SQL,还是有其局限性,大量的SQL文本也不宜直接写在Java类中。所以,FoxnicSQL将原本要写在Java类中的SQL语句放到一个外部文件中,每个语句用一个ID去标识,在SQL执行时,只要指定ID就可以了。在此基础上,FoxnicSQL加入了模板引擎、SQL语句置换、热加载等特性,使其变得更加好用。