这是我参与「第五届青训营 」笔记创作活动的第7天
Gorm及XML库的使用|青训营笔记——将数据从XML文件写到数据库(改进)
改进将数据从XML文件到数据库
-
第一步仍然是读入文件并反序列化
//读入文件并反序列化 file, err := ioutil.ReadFile(filePath) if err != nil { return err } var c = Contacts{} err1 := xml.Unmarshal(file, &c) if err1 != nil { return err1 } -
进行数据的检验
这里将读入文件中含有相同电话号码视为数据有错误,读入的数据和数据库中数据有相同的电话号码视为修改
-
检验读入文件中的数据
将一个个数据放在map中,如果该电话号码没有被标记为true则标记为true,如果被标记过则直接返回error
//校验文件 m := make(map[string]bool) for _, v := range c.C { phone := v.Phone if m[phone] == true { return fmt.Errorf("输入的数据有误") } m[phone] = true } -
对比读入文件中的数据与数据库中的数据
执行到了这一步,在上面的检验中,所有的phone都被记录到map中并标记为true,现在我们只需要拿到数据库中的数据,如果数据中的phone字段在map中被标记为true,则将该电话标记改为false用来和需要重新创建的数据作为区别
//校验数据库中是否有相同的电话号码 fromDB := FromDB(db)//从数据库中读取文件 for _, v := range fromDB { //复用m if m[v.Phone] == true { //这里将需要改变的标记为false m[v.Phone] = false } }
-
-
将需要创建的值和更改的值放到不同的slice中
逐个对比从XMl文件中读入的数据与map中的标记
//将需要创建的值和更改的值放到不同的slice中 //这里还需要将从XML文件中读入的数据转存到数据库对应的结构体中 createSlice := make([]ContactsModel, 0) updateSlice := make([]ContactsModel, 0) for _, v := range c.C { if m[v.Phone] == true { createSlice = append(createSlice, struct { gorm.Model Name string Sex string Phone string }{Name: v.Name, Sex: v.Sex, Phone: v.Phone}) continue } updateSlice = append(updateSlice, struct { gorm.Model Name string Sex string Phone string }{Name: v.Name, Sex: v.Sex, Phone: v.Phone}) } -
利用gorm执行创建和修改操作
//利用gorm执行创建和修改操作 if len(createSlice) != 0 { db.Model(&ContactsModel{}).Create(&createSlice) } for _, v := range updateSlice { db.Model(&ContactsModel{}).Where("phone=?", v.Phone).Updates(v) } -
在上一步中可能在执行数据库操作的某一部出错,有的数据已经执行了操作,有的没有正确执行,我们可以打开数据库事务来保证数据的一致性
db.Transaction(func(tx *gorm.DB) error { if len(createSlice) != 0 { result := tx.Model(&ContactsModel{}).Create(&createSlice) if result.Error != nil { return result.Error } } for _, v := range updateSlice { result := tx.Model(&ContactsModel{}).Where("phone=?", v.Phone).Updates(v) if result.Error != nil { return result.Error } } return nil })如果返回的不是nil,gorm会自动执行数据库回滚操作
-
我们执行一遍操作得到的output.xml文件中有乱码
<Contacts> <contact sex="M"> <name>
 张三
 </name> <phone>11111111111</phone> </contact> <contact sex="W"> <name>
 李四
 </name> <phone>22222222222</phone> </contact> <contact sex="M"> <name>
 王五
 </name> <phone>44444444444</phone> </contact> </Contacts>这是由于写入的时候没有处理空格和换行符引起的,这里我们添加一个函数作为处理
//去除字符串中的空格和换行符 func replaceString(s string) (newString string) { s = strings.Replace(s, "\n", "", -1) newString = strings.Replace(s, " ", "", -1) return }并将“将需要创建的值和更改的值放到不同的slice中”这一步操作修改为
createSlice := make([]ContactsModel, 0) updateSlice := make([]ContactsModel, 0) for _, v := range c.C { temp := ContactsModel{ Name: replaceString(v.Name), Sex: replaceString(v.Sex), Phone: replaceString(v.Phone), } if m[v.Phone] == true { createSlice = append(createSlice, temp) continue } updateSlice = append(updateSlice, temp) }
代码地址
[code] github.com/Tian2002/xm…