GoFrame增删改查需求设计

请添加图片描述

查询

需求:输入为一个必选参数与任意多个可选参数,返回查询结果

新需求:

1. 关键字匹配(输入单个、部分或者整体字符,可查询出结果)

**思路:**模糊查询 + SQL拼接


	object := g.Model("library").WhereLike("name", "%"+name+"%")
	if PublisherId != 0 {
		object = object.Where("publisher_id", PublisherId)
	}
	if ISBN != "" {
		object = object.WhereOrLike("ISBN", "%"+ISBN+"%")
	}
	all, err := object.All()

请添加图片描述

请添加图片描述

2. 搜索字段在表数据中出现重复怎么办,即多条返回信息

如果想解决上述问题,需要返回多条信息

// 目前是这样的
{
    "code": 0,
    "message": "",
    "data": {
        "DeleteInformation": {
            "id": 2,
            "book_name": "*****",
            "Book_ISBN": "*****",
            "translator": "*****",
            "publish_date": "2023-07-17 16:53:06",
            "publisher_Id": 910
        },
        "message": "上述信息已删除"
    }
}
// 想要的是这样的
{
  "message": "",
  "Data": [
    {
      "aa": "bb",
      "cc": "dd"
    },
    {
      "aa": "bb",
      "cc": "dd"
    }
  ]
}

怎么办?

分为三种情况解决:

  1. 查询结果为单数,直接返回

  2. 查询结果为多条信息,整体返回

  3. 查询结果为空

首先,设置对象类型的切片分层存储每一条数据,便于统计查询结果的数量。

Arr := make([]map[string]interface{}, 0)
	for _, element := range all {
		// 创建map数组存储每一个map,如arr1[ISBN]=78654132的元素
		arr1 := make(map[string]interface{}, 0)
		for key, value := range element {
			arr1[gconv.String(key)] = value
		}
		Arr = append(Arr, arr1)
	}

**其次,**如果查询结果为单数,直接返回:

if len(Arr) == 1 {
		// 取出一个全局变量
		globalVariable = gconv.Int(Arr[0]["id"])
		BookSingle := v1.BookInformation{
				
           ....
            
			Publisher_id: gconv.Int(Arr[0]["publisher_id"]),
		}
		arrResult = append(arrResult, BookSingle)
		out = &v1.Q_Res{
			Message: "图书信息如下",
			Date:    arrResult,
			Flag:    true,
		}
	}

**再次,**如果查询结果为多条数据,整体返回:

type UpdateRes struct {
   Message string          `json:"message"`
    // 在返回值这做文章,把返回值作为数组
   Date    []BookInformation `json:"Updated_information"`
else { // 多条记录
		for _, res := range Arr {
			BookMulti := v1.BookInformation{
				Id:           gconv.Int(res["id"]),
				
                ...
               
				Date:         gconv.String(res["date"]),
				Publisher_id: gconv.Int(res["publisher_id"]),
			}
			arrResult = append(arrResult, BookMulti)
		}
		out = &v1.Q_Res{
			Message: "图书信息如下",
			Date:    arrResult,
			Flag:    true,
		}
	}

**最后,**查询结果为空:

if len(Arr) == 0 {
		g.RequestFromCtx(ctx).Response.ResponseWriter.WriteHeader(500)
		out = &v1.Q_Res{
			Message: "查询结果为空",
			Date:    []v1.BookInformation{},
			Flag:    false,
		}
		return
	}

3. 搜索字段在表中出现重复数据,用户通过添加约束条件,逐步锁定查询目标

请添加图片描述
请添加图片描述

请添加图片描述

请添加图片描述

利用SQL中"and"与"or"的优先级来解决

// all, err := g.Model("library").Ctx(ctx).Where("name", name).WhereOr("ISBN", ISBN).Where("publisher_id", PublisherId).All()

	// 是0就不执行AND (`publisher_id`=PublisherId),
	// 只执行WHERE (`name`='name') OR (`ISBN`='')
	// 不是0的话,就把这句加上,并且在Where("name", "许三观卖血记")与Where("publisher_id", pub)之间构造and
	object := g.Model("library").Where("name", name)
	if PublisherId != 0 {
		object = object.Where("publisher_id", PublisherId)
	}
	object = object.WhereOr("ISBN", ISBN)
	all, err := object.All()

增加

需要完整的图书信息,也要事先判断是否已经存在该记录(先查询),如果已经存在,则不能重复添加

首先,判断表中是否已经存在该数据

flag, err := g.Model("library").Ctx(ctx).Fields("count(1)", "id").Where("name", in.Date.Name).Where("ISBN", in.Date.ISBN).Where(
		"translator", in.Date.Translator).Where("date", in.Date.Date).WhereOr("publisher_id", in.Date.Publisher_id).Group("id").All()
	if err != nil {
		return out, err
	}

存在,则直接返回

// 要插入的数据已经存在于表中
	if flag != nil {
		out = &v1.InsertRes{
			Message: "数据已存在,不可添加",
			Date:    v1.BookInformation{},
		}
		return
	}

否则,插入

请添加图片描述

增加操作(插入、新建)比较简单了,但是需要提前判断**当前添加信息的所有字段,在原有库中是否有完全匹配的**,如果有则无法插入,否则正常插入即可。

修改

总体:先查询出要修改的信息,然后再修改

— 1. 根据书名或者ISBN进行查询(输入)

---- 1.1 查询结果存在
----- 1.1.1 查询结果为单条:设置全局变量保存主键值,返回该图书完整的信息和message提示

----- 1.1.2 查询结果为多条:返回各个图书完整的信息和message提示

---- 1.2 查询结果不存在
----- 1.2.1 返回查询失败的message提示

— 2. 对查询到的信息进行“有选择地”修改

// 开启事务
	// 当给定的闭包方法返回的error为nil时,闭包执行结束后当前事务自动执行Commit提交操作;否则自动执行Rollback回滚操作。
	dao.GfUser.Transaction(ctx, func(ctx context.Context, tx gdb.TX) error {
		// 为了防止空字段覆盖原始字段,提前设置一个map对象备份(倒腾)
		data := gmap.New()
		// 不为"",即证明有值,也就是需要修改,其余的不用修改,晕了
		if gconv.String(in.Information.Name) != "" {
			data.Set("name", in.Information.Name)
		}
		if gconv.String(in.Information.ISBN) != "" {
			data.Set("ISBN", in.Information.ISBN)
		}
		if gconv.String(in.Information.Translator) != "" {
			data.Set("translator", in.Information.Translator)
		}
		if gconv.String(in.Information.Date) != "" {
			data.Set("date", in.Information.Date)
		}
		if gconv.Int(in.Information.Publisher_id) != 0 {
			data.Set("publisher_id", in.Information.Publisher_id)
		}
		_, err = g.Model("library").Data(data.Map()).Where("id", val).Update()
		if err != nil {
			return err
		} else {
			return nil
		}
	})
---- 2.1 修改成功
----- 2.1.1 针对单条查询结果,可直接修改

----- 2.1.2 针对多条查询结果,需指定要修改图书的ID信息

// update library set name = '背影',ISBN = '132456789',translator = 'qiqi', date = now(),publisher_id = '110' where id = 4;
	all2, err2 := g.Model("library").Ctx(ctx).Where("id", val).All()
	if err2 != nil {
		err = err2
		return
	}
	outUpdated = &v1.UpdateRes{
		Message: "修改后的信息如下",
		Date: v1.BookInformation{
			Id:           gconv.Int(all2[0]["id"]),
			Name:         gconv.String(all2[0]["name"]),
			ISBN:         gconv.String(all2[0]["ISBN"]),
			Translator:   gconv.String(all2[0]["translator"]),
			Date:         gconv.String(all2[0]["date"]),
			Publisher_id: gconv.Int(all2[0]["publisher_id"]),
		},
	}
	return
返回修改后的该图书完整信息和message提示
---- 2.2 修改失败
----- 2.2.1 返回修改的message提示
Map类型的输出不明白?一次搞懂:
count, err := g.Model("library").Fields("count(1),id").Where("name", s1).WhereOr("ISBN", s2).Group("id").All()
if err != nil {
   return
}
// 直接输出
fmt.Println(count)
// 输出
// [map[count(1):1 id:1]]  分析:输出的是一个数组[],里面包了一个map,map有两个key-value,第一个key是count(1),value是1;第二个key是id,value是1。

fmt.Println(count[0])	//取数组第一个元素
// 输出
// map[count(1):1 id:1]

fmt.Println(count[0]["count(1)"])	// 取数组第一个元素的map里的第一个key所对应的值
// 输出
// 1

fmt.Println(count[0]["id"]) // 取数组第一个元素的map里的第二个key所对应的值
// 输出
// 1

删除

—需求:

// 只需要提供其中一个name或者ISBN(唯一)即可查询到数据并进行删除

— 1. 根据书名或者ISBN进行查询(输入)

---- 1.1 查询结果存在
----- 1.1.1 查询结果为单条信息

返回该图书完整的信息,直接删除

flag, err := s.Query(ctx, in.Name, in.ISBN, in.PublisherID)

if flag.Flag {
		ArrResult2 := make([]v1.BookInformation, 0)
		// 如果为一条图书信息
		if len(flag.Date) == 1 {
			_, err2 := g.Model("library").Where("publisher_id", flag.Date[0].Publisher_id).Delete()
			if err2 != nil {
				return
			}
			bookSingle := v1.BookInformation{
				Id:           flag.Date[0].Id,
				Name:         flag.Date[0].Name,
				ISBN:         flag.Date[0].ISBN,
				Translator:   flag.Date[0].Translator,
				Date:         flag.Date[0].Date,
				Publisher_id: flag.Date[0].Publisher_id,
			}
			ArrResult2 = append(ArrResult2, bookSingle)
			OutDeleted = &v1.DeleteRes{
				Message: "删除信息如下",
				Date:    ArrResult2,
			}
		}

----- 1.1.2 查询结果为多条信息

------ 1.1.2.1 指定了PublisherID(问题是,你指定了PublisherID,查询结果就不可能是多条了)所以这一条省略。

根据PublisherID返回该图书完整的信息,并对图书信息进行删除操作,最后返回Message提示:图书信息已删除

// 如果图书信息为多条
		if len(flag.Date) > 1 {
			// flag.Date已经是一个数组了,那就直接返回可以吗
			OutDeleted = &v1.DeleteRes{
				Message: "请指定图书publisher_id,再次进行删除",
				Date:    flag.Date,
			}
		}
执行删除操作,成功后返回message提示:“已删除”
---- 1.2 查询结果不存在
----- 1.2.1 返回删除失败的message提示:图书信息不存在,无法删除
// 如果图书信息不存在
	if !flag.Flag {
		OutDeleted = &v1.DeleteRes{
			Date:    []v1.BookInformation{},
			Message: "图书信息不存在",
		}
		return
	}

直接返回可以吗
OutDeleted = &v1.DeleteRes{
Message: “请指定图书publisher_id,再次进行删除”,
Date: flag.Date,
}
}




#### **执行删除操作,成功后返回message提示:“已删除”**

#### 			---- 1.2 查询结果不存在

##### 			 		 		----- 1.2.1 返回删除失败的message提示:图书信息不存在,无法删除

```go
// 如果图书信息不存在
	if !flag.Flag {
		OutDeleted = &v1.DeleteRes{
			Date:    []v1.BookInformation{},
			Message: "图书信息不存在",
		}
		return
	}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值