zoukankan      html  css  js  c++  java
  • Iris后台管理Demo

    后台管理开发

    1. 商品模型设计开发
    2. 商品增删改查功能开发
    3. 后台商品管理页面开发
    

    结构体的Tag

      在golang中,命名都是推荐都是用驼峰方式,并且在首字母大小写有特殊的语法含义:包外无法引用。但是由经常需要和其它的系统进行数据交互,例如转成json格式,存储到Redis等等。这个时候如果直接用属性名来作为键值会不符合项目要求。

    • tag的作用: tag相当于该字段的一个属性标签, 在Go语言中, 一些包通过tag来做相应的判断
      type Student struct {
          Name string`json:"name"`
      }
      
      v, err := json.Marshal(s1) // json.Marshal方法,json序列化,返回值和报错信息
      if err != nil { // 不为nil代表报错
          fmt.Println(err)
      }
      fmt.Println(string(v))   // []byte转string, json  如果不进行转换json后的key为大写显得鸡肋
      

    GO语言的ORM

    ORM是数据库与程序之间的映射关系的实现,将数据库中的数据转换成程序的实现

    • models.go 为数据画出模子,数据库中的数据最后来填充它,使用tag标签,来区分结构体的不同属性。
      package datamodels
      
      type Product struct {
      	ID            int64  `json:"id" sql:"id" imooc:"id"` // 可以用来映射表字段
      	ProductName   string `json:"ProductName" sql:"productName" imooc:"ProductName"`
      	ProductNum    int64  `json:"ProductNum" sql:"productNum" imooc:"ProductNum"`
      	ProductImgage string `json:"ProductImage" sql:"productImage" imooc:"ProductImage"`
      	ProductUrl    string `json:"ProductUrl" sql:"productUrl" imooc:"ProductImage"`
      }
      
    • comm.go 为填充模子的工具,根据模子中各个属性,将从数据库中取得的数据填充
      package common
      
      import (
      	"errors"
      	"fmt"
      	"reflect"
      	"strconv"
      	"time"
      )
      
      //根据结构体中sql标签映射数据到结构体中并且转换类型
      func DataToStructByTagSql(data map[string]string, obj interface{}) {
      	objValue := reflect.ValueOf(obj).Elem()
      	for key, value := range data {
      		strKey := fmt.Sprintf("data的: %v", key)
      		strValue := fmt.Sprintf("data的val:%v", value)
      		data[strKey] = strValue
      	}
      
      	for i := 0; i < objValue.NumField(); i++ {
      		fmt.Println("i的值为:" + strconv.Itoa(i))
      		fmt.Println("obj 结构体对应的下标为:" + objValue.Type().Field(i).Tag.Get("sql"))
      
      		//获取sql对应的值
      		value := data[objValue.Type().Field(i).Tag.Get("sql")]
      
      		fmt.Println("当前下标回去的Map对应的value值为:" + value)
      		//获取对应字段的名称
      		name := objValue.Type().Field(i).Name
      		//获取对应字段类型
      		structFieldType := objValue.Field(i).Type()
      		//获取变量类型,也可以直接写"string类型"
      		val := reflect.ValueOf(value)
      		var err error
      		if structFieldType != val.Type() {
      			//类型转换
      			val, err = TypeConversion(value, structFieldType.Name()) //类型转换
      			if err != nil {
      
      			}
      		}
      		//设置类型值
      		objValue.FieldByName(name).Set(val)
      	}
      }
      
      //类型转换
      func TypeConversion(value string, ntype string) (reflect.Value, error) {
      	if ntype == "string" {
      		return reflect.ValueOf(value), nil
      	} else if ntype == "time.Time" {
      		t, err := time.ParseInLocation("2006-01-02 15:04:05", value, time.Local)
      		return reflect.ValueOf(t), err
      	} else if ntype == "Time" {
      		t, err := time.ParseInLocation("2006-01-02 15:04:05", value, time.Local)
      		return reflect.ValueOf(t), err
      	} else if ntype == "int" {
      		i, err := strconv.Atoi(value)
      		return reflect.ValueOf(i), err
      	} else if ntype == "int8" {
      		i, err := strconv.ParseInt(value, 10, 64)
      		return reflect.ValueOf(int8(i)), err
      	} else if ntype == "int32" {
      		i, err := strconv.ParseInt(value, 10, 64)
      		return reflect.ValueOf(int64(i)), err
      	} else if ntype == "int64" {
      		i, err := strconv.ParseInt(value, 10, 64)
      		return reflect.ValueOf(i), err
      	} else if ntype == "float32" {
      		i, err := strconv.ParseFloat(value, 64)
      		return reflect.ValueOf(float32(i)), err
      	} else if ntype == "float64" {
      		i, err := strconv.ParseFloat(value, 64)
      		return reflect.ValueOf(i), err
      	}
      
      	//else if .......增加其他一些类型的转换
      	return reflect.ValueOf(value), errors.New("未知的类型:" + ntype)
      }
      
    • test.go 模拟数据的转换
      package main
      
      import (
      	"test-produce/common"
      	"test-produce/datamodels"
      )
      
      func main() {
          // 模拟从数据库中取得的数据
      	data := map[string]string{"id":"1","productName":"imooc Test","productNum":"3","productImage":"/image1.jpg","productUrl":"www.baidu.com"}
      
      	product := &datamodels.Product{}
      	common.DataToStructByTagSql(data, product)
      }
      
      /*
       	运行结果:
      	 	i的值为:0
              obj 结构体对应的下标为:id
              当前下标回去的Map对应的value值为:1
              i的值为:1
              obj 结构体对应的下标为:productName
              当前下标回去的Map对应的value值为:imooc Test
              i的值为:2
              obj 结构体对应的下标为:productNum
              当前下标回去的Map对应的value值为:3
              i的值为:3
              obj 结构体对应的下标为:productImage
              当前下标回去的Map对应的value值为:/image1.jpg
              i的值为:4
              obj 结构体对应的下标为:productUrl
              当前下标回去的Map对应的value值为:www.baidu.com
      */
      

    Go语言和Mysql交互

    针对数据库中的数据,使用go语言进行增删改查

    package main
    
    import (
    	"database/sql"
    	"fmt"
    	_ "github.com/go-sql-driver/mysql"
    	"log"
    )
    
    func main() {
    	db, err := sql.Open("mysql", "root:123@tcp(127.0.0.1:3306)/imooc?charset=utf8")
    	defer db.Close()
    	
    	// Query 和 Scan的简单使用
    	rows, err := db.Query("SELECT productName FROM product WHERE id > ?", 0)
    	if err != nil {
    		log.Fatal(err)
    	}
    
    	// rows.Next() 类似于迭代器,返回每条记录, 返回多行数据
    	for rows.Next() {
    		var productName string
    		// 通过Query得到的rows, 需要我们设置一个变量进行接受,通过rows.Scan(指针),将值传递给变量
    		if err := rows.Scan(&productName); err != nil {
    			log.Fatal(err)
    		}
    		fmt.Printf("多行数据: %s
     ", productName)
    	}
    	if err := rows.Err(); err != nil {
    		log.Fatal(err)
    	}
    
    	// QueryRaw 用于返回单行的查询, 如果是*的话,需要使用多个参数进行接受
    	//rows1 := db.QueryRow("SELECT * FROM product WHERE id = ?", 1)
    	rows1 := db.QueryRow("SELECT productNum FROM product WHERE id = ?", 1)
    	var productNum int64
    	if err := rows1.Scan(&productNum); err != nil {
    		log.Fatal(err)
    	}
    	fmt.Printf("单行数据: %d
    ", productNum)
    
    	// 预占位符,db.Prepare()返回一个Stmt。Stmt对象可以执行Exec,Query,QueryRow等操作。
    	stmt, _ := db.Prepare("insert into product (productName, productNum, productImage, productUrl) values (?,?,?,?)")
    
    	// Exec() 执行函数,常用作执行增删该等操作
    	row2, err := stmt.Exec(
    		"娃哈哈",
    		5,
    		"/ha.jpg",
    		"/ha",
    	)
    	idNew, errId := row2.LastInsertId()
    	if errId != nil {
    		fmt.Println(errId)
    	}
    	fmt.Printf("数据插入成功!返回操作的数据的ID: %d", idNew)
    }
    

    源码地址:https://github.com/wuyuz/goProduct

  • 相关阅读:
    数据库进阶系列之二:细说数据库范式
    ORACLE HANDBOOK系列之三:树状结构查询(Hierarchical Queries)
    Tips&Tricks系列八:Fail to convert .vsmid,.testrunconfig
    Java基础系列之四:Remote Debug入门示例
    Java基础系列之五:Spring使用入门示例
    数据库进阶系列之三:使用Logminer解析Oracle日志
    ORACLE HANDBOOK系列之四:批量SQL(BULK SQL)
    Tips&Tricks系列九:数据库外键的两个细节
    Tips&Tricks系列六:ADO.NET OracleConnection.ClearPool(conn)
    Java基础系列之六:CORBA入门示例
  • 原文地址:https://www.cnblogs.com/double-W/p/12594817.html
Copyright © 2011-2022 走看看