GDAO is a comprehensive persistence layer solution. Its primary purpose is to reduce coding effort, enhance productivity, improve performance, support the integration of multiple data sources, facilitate read-write separation, and establish a standard for persistence layer programming. By leveraging GDAO effectively, it's possible to reduce the amount of coding required in the persistence layer by 30%, even up to 50%, while simultaneously establishing a unified programming standard for the persistence layer, reducing errors, and making maintenance and expansion easier. For Go, GDAO serves a similar role as Hibernate + MyBatis do for Java. The GDAO framework combines the abstraction of Hibernate with the flexibility of MyBatis, addressing long-standing pain points in ORM frameworks. For more information about the pain points of Hibernate and MyBatis, refer to the JDAO usage documentation.
GDAO fully implements the core features of MyBatis in Go, achieving the separation of SQL from the application code, and implementing powerful dynamic SQL functionality. It is currently the only ORM in Go that completely separates SQL from the application.
Note: Full table mapping and full SQL mapping can potentially lead to some issues such as over-encapsulation of objects and large numbers of repetitive, similar SQL statements. GDAO uses the abstraction of table mapping combined with the semi-automated management of SQL mapping to solve problems in the persistence layer.
Hibernate, which can lead to over-encapsulation problems.
GDAO supports auto-generating mapping entity classes for tables specifically to handle CRUD operations on single tables. Its underlying dynamic SQL construction effectively addresses the issue of large numbers of similar SQL statements resulting from similar table operation behaviors.MyBatis, allowing SQL to be configured in XML and mapped to Go objects.SqlBuilder for Native SQL Dynamic Construction: GDAO implements dynamic construction of native SQL. For extremely complex SQL, including functions or stored procedures, GDAO supports dynamic construction using SqlBuilder.
It is the procedural implementation of dynamic tags, based on Go programs to construct any form of SQL.go get github.com/donnie4w/gdao
gdao.Init(mysqldb, gdao.MYSQL) // Initialize gdao data source; mysqldb is an sql.DB object, gdao.MYSQL is the database type
// Read
hs := dao.NewHstest()
hs.Where(hs.Id.EQ(10))
h, err := hs.Select(hs.Id, hs.Value, hs.Rowname)
//[DEBUG][SELETE ONE][ select id,value,rowname from hstest where id=?][10]
// Update
hs := dao.NewHstest()
hs.SetRowname("hello10")
hs.Where(hs.Id.EQ(10))
hs.Update()
//[DEBUG][UPDATE][update hstest set rowname=? where id=?][hello10 10]
// Delete
hs := dao.NewHstest()
hs.Where(hs.Id.EQ(10))
hs.Delete()
//[DEBUG][UPDATE][delete from hstest where id=?][10]
// Insert
hs := dao.NewHstest()
hs.SetValue("hello123")
hs.SetLevel(12345)
hs.SetBody([]byte("hello"))
hs.SetRowname("hello1234")
hs.SetUpdatetime(time.Now())
hs.Insert()
//[DEBUG][INSERT][insert into hstest(floa,age,value,level,body,rowname,updatetime )values(?,?,?,?,?)][hello123 12345 hello hello1234 2024-07-17 19:36:44]
// Query, return a single row; gdao is the entry point for native SQL operations
gdao.ExecuteQueryBean("select id,value,rowname from hstest where id=?", 10)
// Insert
gdao.ExecuteUpdate("insert into hstest2(rowname,value) values(?,?)", "helloWorld", "123456789");
// Update
gdao.ExecuteUpdate("update hstest set value=? where id=1", "hello");
// Delete
gdao.ExecuteUpdate("delete from hstest where id = ?", 1);
// Bind Hstest and enable caching; default cache expiration is 300 seconds; gdaoCache is the entry point for cache operations
gdaoCache.BindClass[dao.Hstest]()
mysqldb := getDataSource("mysql.json") // Get slave data source: mysqldb
gdaoSlave.BindClass[dao.Hstest](mysqldb, gdao.MYSQL) // Here the master database is sqlite, the slave database is mysql; Hstest reads from the mysql data source; gdaoSlave is the entry point for read-write splitting operations
<mapper namespace="user">
<select id="selectHstest1" parameterType="int64" resultType="hstest1">
SELECT * FROM hstest1 order by id desc limit #{limit}
</select>
</mapper>
// Read and parse XML configuration
hs1, _ := gdaoMapper.Select[dao.Hstest1]("user.selectHstest1", 1)
fmt.Println(hs1)
<select id="demo1" resultType="Hstest">
SELECT * FROM hstest
<where>
<if test="rowname== 'hello'">
and rowname = #{rowname}
</if>
<if test="id >0">
AND id = #{id}
</if>
</where>
</select>
hs := dao.NewHstest()
hs.SetId(12)
gdaoMapper.SelectBean("dynamic.demo1", hs) //exec mapper id [SELECT * FROM hstest WHERE id = ?]ARGS[12]
func Test_sqlBuilder_if(t *testing.T) {
context := map[string]any{"id": 12}
builder := &SqlBuilder{}
builder.Append("SELECT * FROM hstest where 1=1").
AppendIf("id>0", context, "and id=?", context["id"]) // Dynamic SQL, when id>0, dynamically add and id=?
bean := builder.SelectOne() // Query SQL: SELECT * FROM hstest where 1=1 and id=? [ARGS][12]
logger.Debug(bean)
}