GoMybatis icon indicating copy to clipboard operation
GoMybatis copied to clipboard

请问Mapper支持selectKey标签吗?

Open onlysad opened this issue 5 years ago • 7 comments

<selectKey resultType="int64" order="AFTER">
            SELECT LAST_INSERT_ID() AS id
</selectKey>

请问GoMybatis支持用于数据库Insert时返回当前插入数据的自增主键的selectKey标签吗? 检查dtd文件看到里面是包含该标签的,但是实际使用中返回值永远是1, 传入的User对象里Id的值则始终为0,并没有反向注入。 如果支持的话,请问我是哪里弄错了吗?

我的测试代码如下

<insert id="insert">
        <selectKey resultType="int64" order="AFTER">
            SELECT LAST_INSERT_ID() AS id
        </selectKey>
        INSERT INTO
        sys_user
        <trim prefix="(" suffix=")" suffixOverrides=",">
            <if test="name != nil">name,</if>
            <if test="sex != nil">sex,</if>
        </trim>
        <trim prefix="values (" suffix=")" suffixOverrides=",">
            <if test="name != nil">#{name},</if>
            <if test="sex != nil">#{sex},</if>
        </trim>
    </insert>
import "time"

type User struct {
	Id int64 `json:"id"`
	Name string `json:"name"`
	Sex int `json:"sex"`
	CreateDate time.Time `json:"createTime"`
	UpdateTime time.Time `json:"updateTime"`
}
type UserDao struct {
	Insert func(user User) (int64, error)
	//SelectById func(id int64) (User, error) `mapperParams:"id"`
}

如果不支持的话,请问这个需求有替代的实现方案吗?

onlysad avatar Apr 11 '19 15:04 onlysad

<selectKey resultType="int64" order="AFTER">
            SELECT LAST_INSERT_ID() AS id
</selectKey>

请问GoMybatis支持用于数据库Insert时返回当前插入数据的自增主键的selectKey标签吗? 检查dtd文件看到里面是包含该标签的,但是实际使用中返回值永远是1. 如果支持的话,请问我是哪里弄错了吗?

我的测试代码如下

<insert id="insert">
        <selectKey resultType="int64" order="AFTER">
            SELECT LAST_INSERT_ID() AS id
        </selectKey>
        INSERT INTO
        sys_user
        <trim prefix="(" suffix=")" suffixOverrides=",">
            <if test="name != nil">name,</if>
            <if test="sex != nil">sex,</if>
        </trim>
        <trim prefix="values (" suffix=")" suffixOverrides=",">
            <if test="name != nil">#{name},</if>
            <if test="sex != nil">#{sex},</if>
        </trim>
    </insert>
import "time"

type User struct {
	Id int64 `json:"id"`
	Name string `json:"name"`
	Sex int `json:"sex"`
	CreateDate time.Time `json:"createTime"`
	UpdateTime time.Time `json:"updateTime"`
}
type UserDao struct {
	Insert func(user User) (int64, error)
	//SelectById func(id int64) (User, error) `mapperParams:"id"`
}

如果不支持的话,请问这个需求有替代的实现方案吗?

可以看Session接口的定义,除了查询操作,insert,update,delete操作等都是返回“database/sql“ sql.Result,和go标准库的返回对象其实是一致的,它里面有2个属性

type Result struct {
	LastInsertId int64
	RowsAffected int64
}

看字面意思就是 返回受影响的行,所以你定义一个int64 在更新操作下默认是受影响的行数。

目前框架不会去支持自动递增的id,因为需要兼容类似Tidb等分布式数据库(自增id就没有任何意义而且性能提升不大)不管是 分布式数据库还是 分库分表中间件都不建议id为自增的,为了以后数据库扩展需要。 所以建议id不要用自增,而是给它赋值一个初始值比较好。建议代码里你可以使用uuid,string代替自增主键。

zhuxiujia avatar Apr 11 '19 16:04 zhuxiujia

<selectKey resultType="int64" order="AFTER">
            SELECT LAST_INSERT_ID() AS id
</selectKey>

请问GoMybatis支持用于数据库Insert时返回当前插入数据的自增主键的selectKey标签吗? 检查dtd文件看到里面是包含该标签的,但是实际使用中返回值永远是1. 如果支持的话,请问我是哪里弄错了吗? 我的测试代码如下

<insert id="insert">
        <selectKey resultType="int64" order="AFTER">
            SELECT LAST_INSERT_ID() AS id
        </selectKey>
        INSERT INTO
        sys_user
        <trim prefix="(" suffix=")" suffixOverrides=",">
            <if test="name != nil">name,</if>
            <if test="sex != nil">sex,</if>
        </trim>
        <trim prefix="values (" suffix=")" suffixOverrides=",">
            <if test="name != nil">#{name},</if>
            <if test="sex != nil">#{sex},</if>
        </trim>
    </insert>
import "time"

type User struct {
	Id int64 `json:"id"`
	Name string `json:"name"`
	Sex int `json:"sex"`
	CreateDate time.Time `json:"createTime"`
	UpdateTime time.Time `json:"updateTime"`
}
type UserDao struct {
	Insert func(user User) (int64, error)
	//SelectById func(id int64) (User, error) `mapperParams:"id"`
}

如果不支持的话,请问这个需求有替代的实现方案吗?

可以看Session接口的定义,除了查询操作,insert,update,delete操作等都是返回“database/sql“ sql.Result,和go标准库的返回对象其实是一致的,它里面有2个属性

type Result struct {
	LastInsertId int64
	RowsAffected int64
}

看字面意思就是 返回受影响的行,所以你定义一个int64 在更新操作下默认是受影响的行数。

目前框架不会去支持自动递增的id,因为需要兼容类似Tidb等分布式数据库(自增id就没有任何意义而且性能提升不大)不管是 分布式数据库还是 分库分表中间件都不建议id为自增的,为了以后数据库扩展需要。 所以建议id不要用自增,而是给它赋值一个初始值比较好。建议代码里你可以使用uuid,string代替自增主键。

明白了,我只是想在做一些小东西,不考虑分布式不考虑大数据的情况下,可以偷偷懒。

onlysad avatar Apr 11 '19 16:04 onlysad

另外建议可以把dtd文件里的selectKey删除掉,这样我直接就可以知道不支持了。

onlysad avatar Apr 11 '19 16:04 onlysad

加油,看过xorm,真的完全不敢用,想到一些复杂的SQL用xorm那种类hibernate的方式实现,想想就觉得恐怖。

onlysad avatar Apr 11 '19 16:04 onlysad

加油,看过xorm,真的完全不敢用,想到一些复杂的SQL用xorm那种类hibernate的方式实现,想想就觉得恐怖。

哈哈,老外喜欢写在代码里的orm框架因为方便,做java的都知道hibernate的痛,hibernate后期优化sql很蛋疼。不过我们增加了 乐观锁还有逻辑删除还有模板标签,可以省掉很多重复的crud操作了的。

zhuxiujia avatar Apr 11 '19 16:04 zhuxiujia

我理解selectKey和自增id 没啥关系,我觉得可以支持,selectKey就是在跑sql前或者后 去拿个值 然后塞到结构体里面,只是用selectKey可以完成返回自增id的功能,和数据库是啥没有关系的。java里面mybatis返回自增id的另一种实现方式是useGeneratedKey 这个是和数据库相关的一个操作,不支持也没有关系。

gejun123456 avatar Jun 27 '19 04:06 gejun123456

加油。非常好的orm框架。类hibernate框架会有很多坑,而且学习成本高。 go mod 希望尽快支持。

fabletang avatar Aug 14 '19 02:08 fabletang