百度360必应搜狗淘宝本站头条
当前位置:网站首页 > IT知识 > 正文

Golang之Gorm学习笔记

liuian 2025-03-04 13:04 32 浏览



一、模型定义

1. 模型定义

模型是标准的 struct,由 Go 的基本数据类型、实现了 Scanner 和 Valuer 接口的自定义类型及其指针或别名组成,如:

type User struct {
  ID           uint
  Name         string
  Email        *string
  Age          uint8
  Birthday     *time.Time
  MemberNumber sql.NullString
  ActivedAt    sql.NullTime
  CreatedAt    time.Time
  UpdatedAt    time.Time
}

gorm默认情况下约定使用结构体的名字作为表名,结构体字段名作为列名,使用ID作为主键。

gorm.Model是gorm定义的一个结构体,它包含了几个常见的字段名。

// gorm.Model 的定义
type Model struct {
  ID        uint           `gorm:"primaryKey"`
  CreatedAt time.Time
  UpdatedAt time.Time
  DeletedAt gorm.DeletedAt `gorm:"index"`
}

2. 字段级权限控制

对于可导出的字段,可以使用结构体标签来控制字段的权限。

type User struct {
  Name string `gorm:"<-:create"` // 允许读和创建
  Name string `gorm:"<-:update"` // 允许读和更新
  Name string `gorm:"<-"`        // 允许读和写(创建和更新)
  Name string `gorm:"<-:false"`  // 允许读,禁止写
  Name string `gorm:"->"`        // 只读(除非有自定义配置,否则禁止写)
  Name string `gorm:"->;<-:create"` // 允许读和写
  Name string `gorm:"->:false;<-:create"` // 仅创建(禁止从 db 读)
  Name string `gorm:"-"`  // 读写操作均会忽略该字段
}

3. 创建 / 更新时间追踪

GORM 约定使用 CreatedAtUpdatedAt 追踪创建 / 更新时间。如果您定义了这种字段,GORM 在创建、更新时会自动填充当前时间。

type User struct {
  CreatedAt time.Time // 在创建时,如果该字段值为零值,则使用当前时间填充
  UpdatedAt int       // 在创建时该字段值为零值或者在更新时,使用当前时间戳秒数填充
  Updated   int64 `gorm:"autoUpdateTime:nano"` // 使用时间戳填纳秒数充更新时间
  Updated   int64 `gorm:"autoUpdateTime:milli"` // 使用时间戳毫秒数填充更新时间
  Created   int64 `gorm:"autoCreateTime"`      // 使用时间戳秒数填充创建时间
}

4. 嵌入结构体

当一个结构体中嵌入了一个匿名结构体时,匿名结构体的字段也被认为是父结构体的字段。而如果是嵌入了一个普通结构体时,可以使用embedded标签来将其嵌入:

type Author struct {
    Name  string
    Email string
}

type Blog struct {
  ID      int
  Author  Author `gorm:"embedded"`
  Upvotes int32
}
// 等效于
type Blog struct {
  ID      int64
  Name    string
  Email   string
  Upvotes int32
}

5. 字段标签

gorm支持以下tag,tag名大小写不敏感,但建议使用驼峰命名。


二、连接数据库

以连接MySQL数据库为例。

import (
  "gorm.io/driver/mysql"
  "gorm.io/gorm"
)

func main() {
  // 参考 https://github.com/go-sql-driver/mysql#dsn-data-source-name 获取详情
  dsn := "user:pass@tcp(127.0.0.1:3306)/dbname?charset=utf8mb4&parseTime=True&loc=Local"
  db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
}

连接数据库的高级配置

db, err := gorm.Open(mysql.New(mysql.Config{    
  DSN: "gorm:gorm@tcp(127.0.0.1:3306)/gorm?charset=utf8&parseTime=True&loc=Local", // DSN data source name
  DefaultStringSize: 256, // string 类型字段的默认长度
  DisableDatetimePrecision: true, // 禁用 datetime 精度,MySQL 5.6 之前的数据库不支持
  DontSupportRenameIndex: true, // 重命名索引时采用删除并新建的方式,MySQL 5.7 之前的数据库和 MariaDB 不支持重命名索引
  DontSupportRenameColumn: true, // 用 `change` 重命名列,MySQL 8 之前的数据库和 MariaDB 不支持重命名列
  SkipInitializeWithVersion: false, // 根据当前 MySQL 版本自动配置
}), &gorm.Config{})

gorm允许通过一个现有的数据库连接来初始化*gorm.DB

import (
  "database/sql"
  "gorm.io/gorm"
)

sqlDB, err := sql.Open("mysql", "mydb_dsn")
gormDB, err := gorm.Open(mysql.New(mysql.Config{
  Conn: sqlDB,
}), &gorm.Config{})

连接池

sqlDB, err := db.DB()

// SetMaxIdleConns 设置空闲连接池中连接的最大数量
sqlDB.SetMaxIdleConns(10)

// SetMaxOpenConns 设置打开数据库连接的最大数量。
sqlDB.SetMaxOpenConns(100)

// SetConnMaxLifetime 设置了连接可复用的最大时间。
sqlDB.SetConnMaxLifetime(time.Hour)

三、CRUD接口

1. 创建记录

(1) 创建记录

user := User{Name: "Jinzhu", Age: 18, Birthday: time.Now()}

result := db.Create(&user) // 通过数据的指针来创建

user.ID             // 返回插入数据的主键
result.Error        // 返回 error
result.RowsAffected // 返回插入记录的条数

(2) 用指定字段创建记录

创建记录并更新给出的字段。用Select,指定你想从数据库中检索出的字段

db.Select("Name", "Age", "CreatedAt").Create(&user)
// INSERT INTO `users` (`name`,`age`,`created_at`) VALUES ("jinzhu", 18, "2020-07-04 11:05:21.775")

创建记录并更新未给出的字段

db.Omit("Name", "Age", "CreatedAt").Create(&user)
// INSERT INTO `users` (`birthday`,`updated_at`) VALUES ("2020-01-01 00:00:00.000", "2020-07-04 11:05:21.775")

(3) 批量插入

要有效地插入大量记录,请将一个 slice 传递给 Create 方法。 将切片数据传递给 Create 方法,GORM 将生成一个单一的 SQL 语句来插入所有数据,并回填主键的值,钩子方法也会被调用。

var users = []User{{Name: "jinzhu1"}, {Name: "jinzhu2"}, {Name: "jinzhu3"}}
db.Create(&users)

for _, user := range users {
  user.ID // 1,2,3
}

使用 CreateInBatches 创建时,你还可以指定创建的数量

var users = []User{name: "jinzhu_1"}, ...., {Name: "jinzhu_10000"}}

db.CreateInBatches(users, len(users))

(4) 根据map创建

GORM 支持根据 map[string]interface{}[]map[string]interface{} 创建记录,例如:

db.Model(&User{}).Create(map[string]interface{}{
  "Name": "jinzhu", "Age": 18,
})

// batch insert from `[]map[string]interface{}{}`
db.Model(&User{}).Create([]map[string]interface{}{
  {"Name": "jinzhu_1", "Age": 18},
  {"Name": "jinzhu_2", "Age": 20},
})

注意: 根据 map 创建记录时,association 不会被调用,且主键也不会自动填充

2. 查询

(1) 检索单个对象

GORM 提供了 First、Take、Last 方法,以便从数据库中检索单个对象。当查询数据库时它添加了 LIMIT 1 条件。若没有找到记录时,它会返回 ErrRecordNotFound 错误

// 获取第一条记录(主键升序)
db.First(&user)
// SELECT * FROM users ORDER BY id LIMIT 1;

// 获取一条记录,没有指定排序字段
db.Take(&user)
// SELECT * FROM users LIMIT 1;

// 获取最后一条记录(主键降序)
db.Last(&user)
// SELECT * FROM users ORDER BY id DESC LIMIT 1;

result := db.First(&user)
result.RowsAffected // 返回找到的记录数
result.Error        // returns error

// 检查 ErrRecordNotFound 错误
errors.Is(result.Error, gorm.ErrRecordNotFound)

FirstLast 方法会根据主键查找到第一个、最后一个记录, 它仅在通过 struct 或提供 model 值进行查询时才起作用。 如果 model 类型没有定义主键,则按第一个字段排序。

var user User

// 可以
db.First(&user)
// SELECT * FROM `users` ORDER BY `users`.`id` LIMIT 1

// 可以
result := map[string]interface{}{}
db.Model(&User{}).First(&result)
// SELECT * FROM `users` ORDER BY `users`.`id` LIMIT 1

// 不行
result := map[string]interface{}{}
db.Table("users").First(&result)

// 但可以配合 Take 使用
result := map[string]interface{}{}
db.Table("users").Take(&result)

// 根据第一个字段排序
type Language struct {
  Code string
  Name string
}
db.First(&Language{})
// SELECT * FROM `languages` ORDER BY `languages`.`code` LIMIT 1

(2) 根据主键检索

db.First(&user, 10)
// SELECT * FROM users WHERE id = 10;

db.First(&user, "10")
// SELECT * FROM users WHERE id = 10;

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

(3) 检索全部对象

// 获取全部记录
result := db.Find(&users)
// SELECT * FROM users;

result.RowsAffected // 返回找到的记录数,相当于 `len(users)`
result.Error        // returns error

(4) 条件

string条件

// 获取第一条匹配的记录
db.Where("name = ?", "jinzhu").First(&user)
// SELECT * FROM users WHERE name = 'jinzhu' ORDER BY id LIMIT 1;

// 获取全部匹配的记录
db.Where("name <> ?", "jinzhu").Find(&users)
// SELECT * FROM users WHERE name <> 'jinzhu';

// IN
db.Where("name IN ?", []string{"jinzhu", "jinzhu 2"}).Find(&users)
// SELECT * FROM users WHERE name IN ('jinzhu','jinzhu 2');

// LIKE
db.Where("name LIKE ?", "%jin%").Find(&users)
// SELECT * FROM users WHERE name LIKE '%jin%';

// AND
db.Where("name = ? AND age >= ?", "jinzhu", "22").Find(&users)
// SELECT * FROM users WHERE name = 'jinzhu' AND age >= 22;

// Time
db.Where("updated_at > ?", lastWeek).Find(&users)
// SELECT * FROM users WHERE updated_at > '2000-01-01 00:00:00';

// BETWEEN
db.Where("created_at BETWEEN ? AND ?", lastWeek, today).Find(&users)
// SELECT * FROM users WHERE created_at BETWEEN '2000-01-01 00:00:00' AND '2000-01-08 00:00:00';

struct或map条件

// Struct
db.Where(&User{Name: "jinzhu", Age: 20}).First(&user)
// SELECT * FROM users WHERE name = "jinzhu" AND age = 20 ORDER BY id LIMIT 1;

// Map
db.Where(map[string]interface{}{"name": "jinzhu", "age": 20}).Find(&users)
// SELECT * FROM users WHERE name = "jinzhu" AND age = 20;

// 主键切片条件
db.Where([]int64{20, 21, 22}).Find(&users)
// SELECT * FROM users WHERE id IN (20, 21, 22);

**注意:**当使用结构体作为条件查询时,GORM 只会查询非零值字段。这意味着如果您的字段值为0''false 或其他零值,该字段不会被用于构建查询条件。

(5) 内联条件

// SELECT * FROM users WHERE id = 23;
// 根据主键获取记录,如果是非整型主键
db.First(&user, "id = ?", "string_primary_key")
// SELECT * FROM users WHERE id = 'string_primary_key';

// Plain SQL
db.Find(&user, "name = ?", "jinzhu")
// SELECT * FROM users WHERE name = "jinzhu";

db.Find(&users, "name <> ? AND age > ?", "jinzhu", 20)
// SELECT * FROM users WHERE name <> "jinzhu" AND age > 20;

// Struct
db.Find(&users, User{Age: 20})
// SELECT * FROM users WHERE age = 20;

// Map
db.Find(&users, map[string]interface{}{"age": 20})
// SELECT * FROM users WHERE age = 20;

(6) not条件

db.Not("name = ?", "jinzhu").First(&user)
// SELECT * FROM users WHERE NOT name = "jinzhu" ORDER BY id LIMIT 1;

// Not In
db.Not(map[string]interface{}{"name": []string{"jinzhu", "jinzhu 2"}}).Find(&users)
// SELECT * FROM users WHERE name NOT IN ("jinzhu", "jinzhu 2");

// Struct
db.Not(User{Name: "jinzhu", Age: 18}).First(&user)
// SELECT * FROM users WHERE name <> "jinzhu" AND age <> 18 ORDER BY id LIMIT 1;

// 不在主键切片中的记录
db.Not([]int64{1,2,3}).First(&user)
// SELECT * FROM users WHERE id NOT IN (1,2,3) ORDER BY id LIMIT 1;

(7) or条件

db.Where("role = ?", "admin").Or("role = ?", "super_admin").Find(&users)
// SELECT * FROM users WHERE role = 'admin' OR role = 'super_admin';

// Struct
db.Where("name = 'jinzhu'").Or(User{Name: "jinzhu 2", Age: 18}).Find(&users)
// SELECT * FROM users WHERE name = 'jinzhu' OR (name = 'jinzhu 2' AND age = 18);

// Map
db.Where("name = 'jinzhu'").Or(map[string]interface{}{"name": "jinzhu 2", "age": 18}).Find(&users)
// SELECT * FROM users WHERE name = 'jinzhu' OR (name = 'jinzhu 2' AND age = 18);

(8) 选择特定字段

db.Select("name", "age").Find(&users)
// SELECT name, age FROM users;

db.Select([]string{"name", "age"}).Find(&users)
// SELECT name, age FROM users;

db.Table("users").Select("COALESCE(age,?)", 42).Rows()
// SELECT COALESCE(age,'42') FROM users;

(9) 排序

db.Order("age desc, name").Find(&users)
// SELECT * FROM users ORDER BY age desc, name;

// 多个 order
db.Order("age desc").Order("name").Find(&users)
// SELECT * FROM users ORDER BY age desc, name;

db.Clauses(clause.OrderBy{
  Expression: clause.Expr{SQL: "FIELD(id,?)", Vars: []interface{}{[]int{1, 2, 3}}, WithoutParentheses: true},
}).Find(&User{})
// SELECT * FROM users ORDER BY FIELD(id,1,2,3)

(10) limit & offset

Limit 指定获取记录的最大数量 Offset 指定在开始返回记录之前要跳过的记录数量

db.Limit(3).Find(&users)
// SELECT * FROM users LIMIT 3;

// 通过 -1 消除 Limit 条件
db.Limit(10).Find(&users1).Limit(-1).Find(&users2)
// SELECT * FROM users LIMIT 10; (users1)
// SELECT * FROM users; (users2)

db.Offset(3).Find(&users)
// SELECT * FROM users OFFSET 3;

db.Limit(10).Offset(5).Find(&users)
// SELECT * FROM users OFFSET 5 LIMIT 10;

// 通过 -1 消除 Offset 条件
db.Offset(10).Find(&users1).Offset(-1).Find(&users2)
// SELECT * FROM users OFFSET 10; (users1)
// SELECT * FROM users; (users2)

(11) group & having

db.Model(&User{}).Select("name, sum(age) as total").Group("name").Having("name = ?", "group").Find(&result)
// SELECT name, sum(age) as total FROM `users` GROUP BY `name` HAVING name = "group"

(12) distinct

db.Distinct("name", "age").Order("name, age desc").Find(&results)

(13) join

type result struct {
  Name  string
  Email string
}
db.Model(&User{}).Select("users.name, emails.email").Joins("left join emails on emails.user_id = users.id").Scan(&result{})
// SELECT users.name, emails.email FROM `users` left join emails on emails.user_id = users.id

rows, err := db.Table("users").Select("users.name, emails.email").Joins("left join emails on emails.user_id = users.id").Rows()
for rows.Next() {
  ...
}

db.Table("users").Select("users.name, emails.email").Joins("left join emails on emails.user_id = users.id").Scan(&results)

// 带参数的多表连接
db.Joins("JOIN emails ON emails.user_id = users.id AND emails.email = ?", "jinzhu@example.org").Joins("JOIN credit_cards ON credit_cards.user_id = users.id").Where("credit_cards.number = ?", "411111111111").Find(&user)

(14) scan

Scan 把查询结果存至 struct,用法与 Find 类似。使用 Scan 方法的时候需要我们显示指定数据库的表名。回调函数注册的不一样,Find 函数支持更多的 Callback 注入。

Scan支持的数据类型仅为struct及struct slice以及它们的指针类型。

type Result struct {
  Name string
  Age  int
}

var result Result
db.Table("users").Select("name", "age").Where("name = ?", "Antonio").Scan(&result)

// 原生 SQL
db.Raw("SELECT name, age FROM users WHERE name = ?", "Antonio").Scan(&result)

4. 高级查询

(1) 子查询

db.Where("amount > (?)", db.Table("orders").Select("AVG(amount)")).Find(&orders)
// SELECT * FROM "orders" WHERE amount > (SELECT AVG(amount) FROM "orders");

subQuery := db.Select("AVG(age)").Where("name LIKE ?", "name%").Table("users")
db.Select("AVG(age) as avgage").Group("name").Having("AVG(age) > (?)", subQuery).Find(&results)
// SELECT AVG(age) as avgage FROM `users` GROUP BY `name` HAVING AVG(age) > (SELECT AVG(age) FROM `users` WHERE name LIKE "name%")

GORM 允许在 Table 方法中通过 FROM 子句使用子查询

db.Table("(?) as u", db.Model(&User{}).Select("name", "age")).Where("age = ?", 18}).Find(&User{})
// SELECT * FROM (SELECT `name`,`age` FROM `users`) as u WHERE `age` = 18

subQuery1 := db.Model(&User{}).Select("name")
subQuery2 := db.Model(&Pet{}).Select("name")
db.Table("(?) as u, (?) as p", subQuery1, subQuery2).Find(&User{})
// SELECT * FROM (SELECT `name` FROM `users`) as u, (SELECT `name` FROM `pets`) as p

(2) find到map

GORM 允许保存查询结果到 map[string]interface{}[]map[string]interface{},此时需要指定 ModelTable

var result map[string]interface{}
db.Model(&User{}).First(&result, "id = ?", 1)

var results []map[string]interface{}
db.Table("users").Find(&results)

(3) 迭代

GORM 支持通过行进行迭代

rows, err := db.Model(&User{}).Where("name = ?", "jinzhu").Rows()
defer rows.Close()

for rows.Next() {
  var user User
  // ScanRows 方法用于将一行记录扫描至结构体
  db.ScanRows(rows, &user)

  // 业务逻辑...
}

(4) count

Count 用于获取匹配的记录数

var count int64
db.Model(&User{}).Where("name = ?", "jinzhu").Or("name = ?", "jinzhu 2").Count(&count)
// SELECT count(1) FROM users WHERE name = 'jinzhu' OR name = 'jinzhu 2'

// Count with Distinct
db.Model(&User{}).Distinct("name").Count(&count)
// SELECT COUNT(DISTINCT(`name`)) FROM `users`

db.Table("deleted_users").Select("count(distinct(name))").Count(&count)
// SELECT count(distinct(name)) FROM deleted_users

5. 更新

(1) 保存所有字段

Save 会保存所有的字段,即使字段是零值

user.Name = "jinzhu 2"
user.Age = 100
db.Save(&user)
// UPDATE users SET name='jinzhu 2', age=100, birthday='2016-01-01', updated_at = '2013-11-17 21:34:10' WHERE id=111;

(2) 更新单个列

当使用 Update 更新单个列时,你需要指定条件,否则会返回 ErrMissingWhereClause 错误。当使用了 Model 方法,且该对象主键有值,该值会被用于构建条件。

// 条件更新
db.Model(&User{}).Where("active = ?", true).Update("name", "hello")
// UPDATE users SET name='hello', updated_at='2013-11-17 21:34:10' WHERE active=true;

// User 的 ID 是 `111`
db.Model(&user).Update("name", "hello")
// UPDATE users SET name='hello', updated_at='2013-11-17 21:34:10' WHERE id=111;

3) 更新多列

Updates 方法支持 structmap[string]interface{} 参数。当使用 struct 更新时,默认情况下,GORM 只会更新非零值的字段,可以使用Select来更新指定指定字段。

// 根据 `struct` 更新属性,只会更新非零值的字段
// 只会更新Model指定的主键值对应的记录
db.Model(&user).Updates(User{Name: "hello", Age: 18, Active: false})
// UPDATE users SET name='hello', age=18, updated_at = '2013-11-17 21:34:10' WHERE id = 111;

// 根据 `map` 更新属性
result := db.Model(&user).Updates(map[string]interface{}{"name": "hello", "age": 18, "actived": false})
// UPDATE users SET name='hello', age=18, actived=false, updated_at='2013-11-17 21:34:10' WHERE id=111;

result.RowsAffected // 更新的记录数
result.Error        // 更新的错误

(4) 使用子查询进行更新

db.Model(&user).Update("company_name", db.Model(&Company{}).Select("name").Where("companies.id = users.company_id"))
// UPDATE "users" SET "company_name" = (SELECT name FROM companies WHERE companies.id = users.company_id);

6. 删除

(1) 删除一条记录

删除一条记录时,删除对象需要指定主键,否则会触发批量删除

// 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";

(2) 根据主键删除

GORM 允许通过内联条件指定主键来检索对象,但只支持整型数值,因为 string 可能导致 SQL 注入。

db.Delete(&User{}, 10)
// DELETE FROM users WHERE id = 10;

db.Delete(&User{}, "10")
// DELETE FROM users WHERE id = 10;

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

四、事务

1. 自动事务

db.Transaction(func(tx *gorm.DB) error {
  // 在事务中执行一些 db 操作(从这里开始,您应该使用 'tx' 而不是 'db')
  if err := tx.Create(&Animal{Name: "Giraffe"}).Error; err != nil {
    // 返回任何错误都会回滚事务
    return err
  }

  if err := tx.Create(&Animal{Name: "Lion"}).Error; err != nil {
    return err
  }

  // 返回 nil 提交事务
  return nil
})

2. 手动事务

// 开始事务
tx := db.Begin()

// 在事务中执行一些 db 操作(从这里开始,您应该使用 'tx' 而不是 'db')
tx.Create(...)

// ...

// 遇到错误时回滚事务
tx.Rollback()

// 否则,提交事务
tx.Commit()

来源
:https://blog.csdn.net/zuzhiang/article/details/122539066

相关推荐

系统引导启动项怎么设置(系统引导按哪个键)

如果您想在计算机启动时添加系统启动引导选项,可以按照以下步骤进行操作:1.打开“运行”窗口,可以通过快捷键Win+R打开“运行”窗口。2.在“运行”窗口中输入“msconfig”命令,并点击“...

win10录屏快捷键ctrl+alt+(win10录屏功能快捷键)

答,笔记本电脑录屏快捷键是ctrl+alt+s。绝大多数人录制屏幕时,第一个想到的就是电脑自带的录屏功能,比较的方便快捷。这种方法运用起来时非常简单的,只需在键盘上同时按下“ctrl+alt+s”键就...

壁纸下载(壁纸下载安装)

回答如下:要下载电视屏保相册,您需要先找到适用于您的电视的屏保应用程序。这些应用程序可能会根据您的电视品牌和型号而有所不同,您可以在电视的应用商店中搜索或查看电视制造商的网站以获取更多信息。一旦您找到...

木马病毒下载安装(木马病毒下载安装不实名认证)

现在1,你自己机器上下载个杀毒软件,安装之后不要删除安装包2,运行杀毒软件3,插入优盘,杀毒软件会自动扫描优盘发现病毒然后提示你4,选择处理/杀毒/清理这些字样5,把杀毒软件安装包复制到优盘6,右键优...

免费清理软件哪个最好最快(免费好用的清理垃圾软件)
  • 免费清理软件哪个最好最快(免费好用的清理垃圾软件)
  • 免费清理软件哪个最好最快(免费好用的清理垃圾软件)
  • 免费清理软件哪个最好最快(免费好用的清理垃圾软件)
  • 免费清理软件哪个最好最快(免费好用的清理垃圾软件)
手机cdr转jpg最简单的方法(手机cdr转换jpg)

cdr文件怎么转换成jpg,快来看下操作方法吧。方法/步骤1、打开电脑中的cdr软件,点击文件,打开,打开需要转换格式的cdr文件。2、点击菜单栏的文件,导出。3、打开导出对话框选择保存文件路径。4、...

xp永久激活工具(xp永久激活码)

如果你需要重置XP的激活器,你需要先打开“开始”菜单,然后选择“运行”。在运行对话框中,输入“regedit”,然后按回车键。这会打开注册表编辑器。在编辑器中,使用左侧面板来导航到“HKEY_LOCA...

cad2008激活序列号(激活cad的序列号)

1.首先运行“AutoCAD2008安装包”中的“Setup.exe”安装AutoCAD2008,安装过程需要十分钟左右;2.第一次运行AutoCAD2008时,请在注册界面输入序列号666-9...

自己可以重装电脑系统么(可以自己重装系统吗)

电脑自身也可以重装系统。1.电脑是一个可编程的设备,通过特定的步骤和操作,用户可以自行进行系统重装。2.重装系统的过程包括备份重要数据、获取系统安装介质、重新启动电脑进入安装界面、按照指引选择系统...

win11免费下载(win11正式版下载)
  • win11免费下载(win11正式版下载)
  • win11免费下载(win11正式版下载)
  • win11免费下载(win11正式版下载)
  • win11免费下载(win11正式版下载)
qq邮箱在哪里找账号(qq邮箱账号在qq里怎么找)
  • qq邮箱在哪里找账号(qq邮箱账号在qq里怎么找)
  • qq邮箱在哪里找账号(qq邮箱账号在qq里怎么找)
  • qq邮箱在哪里找账号(qq邮箱账号在qq里怎么找)
  • qq邮箱在哪里找账号(qq邮箱账号在qq里怎么找)
苹果处理器性能排行(苹果处理器性能排行榜平板)

1、截止至最新的iPhoneXS上搭载的A12,从iPhone4首次搭载A4处理器开始,目前已经有9代的苹果A系列处理器;2、A4是一颗45nm制程的ARMCortex-A8的单核心处理器,GP...

苹果手机怎么录屏(苹果手机怎么录屏在哪里打开)

iPhone手机的屏幕录制功能需要在设置里面进行添加,添加成功之后,就可以使用录屏功能了。点击控制中心进入iPhone手机的设置,来到设置之后,找到控制中心选项并点击。点击加号添加录屏功能来到控制中心...

电脑怎么打开系统还原(电脑怎么开启系统还原的功能)

右键此电脑,属性,系统保护,配置,勾选启用系统保护,确定,创建,输入还原点描述,点击创建,系统提示已成功创建还原点,点击关闭,当需要还原的时候,点击上面的系统还原,选择需要还原的节点,点击完成,即可开...

ghost系统下载xp(非ghostxp下载)

蒲公英系统网站能下载。下载后缀为gho的xp系统,使用体验非常棒效果非常好。以上信息根据美国华盛顿操作系统邮报最新消息显示。不能装钉钉的。在WindowsXP系统上是不能安装钉钉来上网课的。要使用钉...