gorm is an ORM framework written in Go language. Complete documentation, developer friendly, support mainstream databases.
I recently supplemented the knowledge of various basic frameworks and operation bases of Go language, and finally reached the database stage. When searching data, I basically recommended this framework, which shows its popularity. After constantly trying to practice, I summarized some experience and ways of use for beginners' reference.
When using the Java language before, I used two kinds of JDBC and mybatis. One is to operate the database locally, and the other is to use them in the Springboot project. Both of them are customarily based on MySQL statements, which are spelled at the operation level. However, there are almost no complete SQL statements in gorm framework, which are all through methods and parameters
go.mod
github.com/jinzhu/gorm v1.9.16
When you execute Go Mod Tidy, you will automatically add the required dependencies (this term may not be correct) to the mod file.
go.mod I'm not very familiar with now. I also finished copying ability launch + IDE prompt. Generally speaking, it's relatively smooth.
The dependencies in my code are as follows:
import ( "fmt" "funtester/base" "funtester/futil" "github.com/jinzhu/gorm" _ "github.com/jinzhu/gorm/dialects/mysql" "log" "testing" "time" )
initialization
The content of this Demo is basic. I can't use high-level Demo, and I can't use it at present. The demonstration is divided into two categories: initializing the connection and initializing the database. Because gorm has its own database initialization function, it will create the database table corresponding to the Model (this needs to be opened manually), so this is still commonly used in the test. If supplemented by the method of data initialization, it can basically meet the needs of our daily development and test services.
func init() { var err error drive, err = gorm.Open("mysql", "root:root123456@(localhost:3306)/funtester?charset=utf8&parseTime=true") if err != nil { fmt.Println(err) log.Fatalln("mysql conntect err") } drive.DB().SetMaxOpenConns(200) drive.DB().SetConnMaxLifetime(10 * time.Second) drive.DB().SetConnMaxIdleTime(10 * time.Second) drive.DB().SetMaxIdleConns(20) // Migrate schema drive.AutoMigrate(&Funtester{}) //Note: AutoMigrate will create tables, missing foreign keys, constraints, columns and indexes, and will change the type of existing columns (if their size, precision and whether they are empty can be changed). Unused columns are not deleted to protect your data. //db.AutoMigrate(&User{}, &Product{}, &Order{}) //drive. Set("gorm:table_options", "ENGINE=InnoDB"). Automigrate (& funtester {}) / / migration with parameters }
Model
type Funtester struct { gorm.Model Name string Age int }
Here we share the table structure of MySQL database:
DROP TABLE IF EXISTS `funtesters`; CREATE TABLE `funtesters` ( `id` int unsigned NOT NULL AUTO_INCREMENT, `name` varchar(255) DEFAULT NULL, `age` int unsigned DEFAULT NULL, `created_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, `created_at` datetime DEFAULT NULL, `updated_at` datetime DEFAULT NULL, `deleted_at` datetime DEFAULT NULL, PRIMARY KEY (`id`), KEY `idx_funtesters_deleted_at` (`deleted_at`) ) ENGINE=InnoDB AUTO_INCREMENT=241861 DEFAULT CHARSET=utf8mb3; SET FOREIGN_KEY_CHECKS = 1;
Here you should clearly see the logic when gorm initializes the database. Let's share gorm Model source code:
type Model struct { ID uint `gorm:"primary_key"` CreatedAt time.Time UpdatedAt time.Time DeletedAt *time.Time `sql:"index"` }
select
The following is a demonstration of the common syntax of select, which is divided into two parts: one is partial basis and the other is partial complexity (mainly multi query condition concatenation). It is obvious here that the idea of gorm splicing query conditions is to classify the query conditions, then write different conditions separately, and use gorm framework to splice SQL statements.
func TestSelect1(t *testing.T) { var f Funtester drive.First(&f, 34)//Default id last := drive.Last(&f, "age != 1")//Add condition fmt.Printf("Number of records queried %d "+base.LINE, last.RowsAffected) fmt.Println(f) take := drive.Take(&f) //Do not specify order fmt.Println(take.RowsAffected) } // TestSelect2 // @Description: common query and processing results // @param t func TestSelect2(t *testing.T) { var fs []Funtester var f Funtester drive.Where("id = ?", 45).First(&f)//Another way of writing //fmt.Println(f) find := drive.Where("name like ?", "fun%").Find(&fs).Limit(10).Order("id")//Concatenation of multiple query conditions rows, _ := find.Rows()//Get results defer rows.Close() for rows.Next() { var ff Funtester drive.ScanRows(rows, &ff) fmt.Println(ff.Age, ff.Name) } //Another way of writing var f1 Funtester drive.Where("name LIKE ?", "fun").Or("id = ?", 123).First(&f1) fmt.Println(f1) }
update
With the foundation of select, it's easier to look at update.
// TestUpdate // @Description: update // @param t func TestUpdate(t *testing.T) { drive.Model(&Funtester{}).Where("id = ?", 241860).Update("name", base.FunTester+"3") }
insert
gorm official documents support batch insertion, but there is no relevant support in this dependency package. If you use the same dependency as me,
// TestInsert // @Description: add // @param t func TestInsert(t *testing.T) { value := &Funtester{Name: "FunTester" + futil.RandomStr(10)} drive.Create(value) drive.Select("name", "age").Create(value) //Only the values of the name and age fields are created futil.Sleep(1) drive.Omit("age", "name").Create(&Funtester{Name: "fds",Age: 122}) //Filter the creation of age and name fields fs := []Funtester{{Name: "fs" + futil.RandomStr(10), Age: 12}, {Name: "fs" + futil.RandomStr(10), Age: 12}} drive.Create(&fs)//This operation is not supported here }
delete
The deletion operation is the same as the above two operations.
func TestDelete(t *testing.T) { db := drive.Where("id = ?", 241859).Delete(&Funtester{}) fmt.Println(db.RowsAffected) }
SQL execution
Of course, gorm also supports the direct execution of SQL statements. One special is that the query results need to be parsed when executing query statements.
// TestSql // @Description: execute SQL directly // @param t func TestSql(t *testing.T) { var funtester []Funtester scan := drive.Raw("select * from funtesters where id > 333 limit 10").Scan(&funtester) fmt.Println(scan.RowsAffected) fmt.Println(funtester) }
Transaction & rollback
In the use of gorm advanced syntax, I think this is very practical and suitable for the execution of some test statements.
// TestRollBack // @Description: transaction & rollback // @param t func TestRollBack(t *testing.T) { funtester := Funtester{Name: base.FunTester, Age: 32232} begin := drive.Begin() err := begin.Create(&funtester).Error if err != nil { begin.Rollback() } begin.Commit() }
The basic use of gorm has been shared. Next time, share the practice of using gorm for performance testing.