DELETE Statement

这篇具有很好参考价值的文章主要介绍了DELETE Statement。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

DELETE Statement

DELETE 应该是增删改查里最简单的语句了

语法分析

由于不同类型 db 包括 SQLite3、 MySQL、PostgreSQL 的 DELETE 最简单形态的语法是一样的,本文只以实现最简单的形态为目标,所以,这里只拿 MySQL 举例
MYSQL 的 DELETE 语句也有两种形态:

  • 删除单表的: 额外支持了 ORDER BY 和 LIMIT

image.png

  • 删除多表的:只支持 WHERE 条件

    image.png

开源实例

Beego ORM

image.png
Beego 的 DELETE API 定义和 UPDATE 一样,如果 cols 没有传,默认是根据主键进行删除。

GORM

DELETE Statement
DELETE 相关方法只有一个, 具体实现思路是,删除一条记录时,删除对象需要指定主键,否则会触发批量Delete,例如:

// Email 的 ID 是 `10`
db.Delete(&email)
// DELETE from emails where id = 10;

// 带额外条件的删除
db.Where("name = ?", "jinzhu").Delete(&email)
// DELETE from emails where id = 10 AND name = "jinzhu";

db.Delete(&users, []int{1,2,3})
// DELETE FROM users WHERE id IN (1,2,3);

API 设计

与 Update 类似, 需要结构体 Deletor 结构体去实现 QueryBuilder 与 Executor 接口。以及需要包含条件语句的拼接。

type Deleter[T any] struct {
}

func (d *Deleter[T]) Build() (*Query, error) {
	panic("implement me")
}

// From accepts model definition
func (d *Deleter[T]) From(table string) *Deleter[T] {
	panic("implement me ")
}

// Where accepts predicates
func (d *Deleter[T]) Where(predicates ...Predicate) *Deleter[T] {
	panic("implement me")
}

具体实现

Build 方法

// Deleter builds DELETE query
type Deleter[T any] struct {
	builder
	table string
	where []Predicate
}

// Build returns DELETE query
func (d *Deleter[T]) Build() (*Query, error) {
	_, _ = d.sb.WriteString("DELETE FROM ")

	if d.table == "" {
		var t T
		d.sb.WriteByte('`')
		d.sb.WriteString(reflect.TypeOf(t).Name())
		d.sb.WriteByte('`')
	} else {
		d.sb.WriteString(d.table)
	}
	if len(d.where) > 0 {
		d.sb.WriteString(" WHERE ")
		err := d.buildPredicates(d.where)
		if err != nil {
			return nil, err
		}
	}
	d.sb.WriteByte(';')
	return &Query{SQL: d.sb.String(), Args: d.args}, nil
}

// From accepts model definition
func (d *Deleter[T]) From(table string) *Deleter[T] {
	d.table = table
	return d
}

// Where accepts predicates
func (d *Deleter[T]) Where(predicates ...Predicate) *Deleter[T] {
	d.where = predicates
	return d
}

与 Update 一样需要实现一个 Excute方法

func (d *Deleter[T]) Exec(ctx context.Context) Result {
	q, err := d.Build()
	if err != nil {
		return Result{err: err}
	}
	res, err := d.db.db.ExecContext(ctx, q.SQL, q.Args...)
	return Result{err: err, res: res}
}

单元测试

func TestDeleter_Build(t *testing.T) {
	testCases := []struct {
		name      string
		builder   QueryBuilder
		wantErr   error
		wantQuery *Query
	}{
		{
			name:    "no where",
			builder: (&Deleter[TestModel]{}).From("`test_model`"),
			wantQuery: &Query{
				SQL: "DELETE FROM `test_model`;",
			},
		},
		{
			name:    "where",
			builder: (&Deleter[TestModel]{}).Where(C("Id").EQ(16)),
			wantQuery: &Query{
				SQL: "DELETE FROM `TestModel` WHERE `Id` = ?;",
				Args: []any{16},
			},
		},
		{
			name:    "from",
			builder: (&Deleter[TestModel]{}).From("`test_model`").Where(C("Id").EQ(16)),
			wantQuery: &Query{
				SQL: "DELETE FROM `test_model` WHERE `Id` = ?;",
				Args: []any{16},
			},
		},
	}

	for _, tc := range testCases {
		c := tc
		t.Run(c.name, func(t *testing.T) {
			query, err := c.builder.Build()
			assert.Equal(t, c.wantErr, err)
			if err != nil {
				return
			}
			assert.Equal(t, tc.wantQuery, query)
		})
	}
}

只要了解前面几个模块的设计,就会发现最简单的 delete 的构造基本没有难点,也没啥好总结的。文章来源地址https://www.toymoban.com/news/detail-405887.html

到了这里,关于DELETE Statement的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 执行计划缓存,Prepared Statement性能跃升的秘密

    摘要: 一起看一下GaussDB(for MySQL)是如何对执行计划进行缓存并加速Prepared Statement性能的。 本文分享自华为云社区《执行计划缓存,Prepared Statement性能跃升的秘密》,作者: GaussDB 数据库。 在数据库系统中,SQL(Structured Query Language)语句输入到系统后,一般要经历:词法语法

    2024年02月07日
    浏览(33)
  • JDBC详讲Connection与 jdbc-Statement

     目录 DriverManager:驱动管理对象 功能: Connection:数据库连接对象 功能: 代码实现:  jdbc-Statement  statement作用:  函数介绍: 代码实现:       功能:         (1)注册驱动: 告诉程序该使用那种数据库 代码中常使用:Class.forName(\\\"com.mysql.cj.jdbc.Driver\\\"); 会被加载进内存,

    2024年02月02日
    浏览(29)
  • BindingException:Invalid bound statement (not found)异常

    本文的mybatis是与springboot整合时出现的异常,若使用的不是基于springboot,解决思路也大体一样的。 但在这之前,我们先要知道整合mybatis的三个重要的工作,如此才能排查,且往下看。 我们打开pom文件如下: 这部分代码的作用是指定需要编译到taget目录下的资源文件。我们的

    2024年02月04日
    浏览(38)
  • Invalid bound statement (not found) 原因和解决方法

    在我springboot项目,启动的时候,报了 Invalid bound statement (not found) :绑定语句无效(未找到) mapper接口和mapper.xml文件没有映射起来 1.查看mapper.xml中的namespace和接口mapper文件一致吗 2.看一下 target 里面有没有编译的mapper.xml文件 没有的话,打开maven点击clean一下,重新运行就ok了

    2024年02月14日
    浏览(32)
  • 【Java 进阶篇】JDBC Statement:执行 SQL 语句的重要接口

    在Java应用程序中,与数据库进行交互是一项常见的任务。为了执行数据库操作,我们需要使用JDBC(Java Database Connectivity)来建立与数据库的连接并执行SQL语句。 Statement 接口是JDBC中的一个重要接口,它用于执行SQL语句并与数据库进行交互。本文将详细介绍 Statement 接口的使用

    2024年02月05日
    浏览(46)
  • Invalid bound statement (not found)的原因以及解决方法

    相信我们在学习Mybatis的时候都出现过 Invalid bound statement (not found) 这个错误,一般由以下几种可能导致这个错误 例如: mapper:  对应的mapper.xml 这里建议小伙伴们下载一个插件,方便查看你的xml是否对应了你想对应的mapper接口 有了这个插件,你的接口mapper和对应的mapper.xml都

    2024年02月15日
    浏览(42)
  • mybatis plus报错:Invalid bound statement (not found)

    有的同学,在搭建mybatis plus项目时,遇到Invalid bound statement (not found)的问题,实质上是mapper接口和mapper.xml没有映射起来。 这种情况,常见的问题有以下几个: 1、mapper.xml 里面的 namespace与实际的mapper类路径不一致。 这个有个快捷的检测办法就是按住ctrl键,然后点击namespace里

    2024年02月04日
    浏览(47)
  • Invalid bound statement (not found)出现原因和解决方法

    出现的原因:mapper接口和mapper.xml文件没有映射起来。 解决方法: 1、 .mapper.xml中的namespace和实际的mapper文件是否一致 2、 检查mapper接口中的方法名与mapper.xml文件中的id是否一致 推荐大家去下载MyBatisX插件,可以自动实现mapper接口到mapper.xml之间的映射,既能提高效率,又能避

    2024年02月11日
    浏览(55)
  • Invalid bound statement (not found):常见报错原因解决

    在SpringMVC项目中,通过mapper接口加载映射文件,完成数据库的操作。 报错:Invalid bound statement (not found): 1、xml文件的namespace不正确 2、XxxMapper.java的方法在XxxMapper.xml中没有,运行则会报此错误 3、XxxMapper.java的方法返回值是List,但是没有正确配置ResultMap,或者只配置ResultType 4、

    2023年04月27日
    浏览(39)
  • Prepared statement needs to be re-prepared

    查看打开的表 Opened_tables数值大,说明cache太小,导致要频繁地open table,可以查看下当前的table_open_cache设置 2.查看 table_open_cache 量 mysql 的两个全局变量(打开表的缓存数量,表定义缓存数量)的设置值过小,而你的数据库表数量较多的情况。 此原因是因为 mysql 的变量值设置

    2024年01月18日
    浏览(26)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包