insert语句主键自增,sql语句设置主键自增
大家好,今天来为大家分享insert语句主键自增的一些知识点,和sql语句设置主键自增的问题解析,大家要是都明白,那么可以忽略,如果不太清楚的话可以看看本篇文章,相信很大概率可以解决您的问题,接下来我们就一起来看看吧!
mybatis mysql 主键自增加怎么配置
mybatis自增主键配置:
mybatis进行插入操作时,如果表的主键是自增的,针对不同的数据库相应的操作也不同。基本上经常会遇到的就是 Oracle Sequece和 Mysql自增主键。主要说明下在mybatis中对于自增主键的配置。
1、不返回自增主键值:
如果考虑到插入数据的主键不作为其他表插入数据的外键使用,可以考虑这种方式。
Oracle Sequence配置
<sqlid='TABLE_NAME'>TEST_USER</sql>
<sqlid='TABLE_SEQUENCE'>SEQ_TEST_USER_ID.nextval</sql>
<!--注意这里直接调用sequence的nextval函数-->
<insertid="insert"parameterType="User">
insertinto<includerefid="TABLE_NAME"/>(ID,NAME,AGE)
values(<includerefid="TABLE_SEQUENCE"/>,#{name},#{age})
</insert>
当插入语句如上配置时,那么针对如下语句
Useruser=newUser();
user.setName("test");
user.setAge(24);
userMapper.insert(user);
System.out.println(user.id);//user.id为空user.id为空,也就是说如上的配置并不能在完成插入操作后将插入时的主键值存放到保存的对象中。
2、Mysql自增主键配置
由于mysql数据库中,可以设置表的主键为自增,所以对于Mysql数据库在mybatis配置插入语句时,不指定插入ID字段即可。主键的自增交由Mysql来管理。
<sqlid='TABLE_NAME'>TEST_USER</sql>
<!--注意这里的插入SQL中是没有指明ID字段的!-->
<insertid="insert"parameterType="User">
insertinto<includerefid="TABLE_NAME"/>(NAME,AGE)
values(#{name},#{age})
</insert>
同样,针对Mysql如此配置mybaits,插入完成后user.id为空。
插入后获取自增主键值:
上述的情况能满足大部分情况,但有时候我们会遇到类似一对多的那种表结构,在插入多端数据时,需要获取刚刚保存了的一段的主键。那么这个时候,上述的配置就无法满足需要了。为此我们需要使用mybatis提供的<selectKey/>来单独配置针对自增逐渐的处理。
1、Oracle Sequence配置:
<sqlid='TABLE_NAME'>TEST_USER</sql>
<sqlid='TABLE_SEQUENCE'>SEQ_TEST_USER_ID.nextval</sql>
<!--注意这里需要先查询自增主键值-->
<insertid="insert"parameterType="User">
<selectKeykeyProperty="id"resultType="int"order="BEFORE">
select<includerefid="TABLE_SEQUENCE"/>fromdual
</selectKey>
insertinto<includerefid="TABLE_NAME"/>(ID,NAME,AGE)
values(#{id},#{name},#{age})
</insert>
当使用了<selectKey/>后,在实际的插入操作时,mybatis会执行以下两句SQL:
selectSEQ_TEST_USER_ID.nextvalfromdual;//语句1
insertinto(ID,NAME,AGE)values(?,?,?);//语句2在执行插入语句2之前,会先执行语句1以获取当前的ID值,然后mybatis使用反射调用User对象的setId方法,将语句1查询出的值保存在User对象中,然后才执行语句2这样就保证了执行完插入后
Useruser=newUser();
user.setName("test");
user.setAge(24);
userMapper.insert(user);
System.out.println(user.id);//user.id不为空user.id是有值的。
2、Mysql自增主键配置
针对于Mysql这种自己维护主键的数据库,可以直接使用以下配置在插入后获取插入主键,
<sqlid='TABLE_NAME'>TEST_USER</sql>
<insertid="insert"useGeneratedKeys="true"keyProperty="id"parameterType="User">
insertinto<includerefid="TABLE_NAME"/>(NAME,AGE)
values(#{name},#{age})
</insert>当然,由于Mysql的自增主键可以通过SQL语句
selectLAST_INSERT_ID();来获取的。因此针对Mysql,Mybatis也可配置如下:
<sqlid='TABLE_NAME'>TEST_USER</sql>
<!--注意这里需要先查询自增主键值-->
<insertid="insert"parameterType="User">
<selectKeykeyProperty="id"resultType="int"order="BEFORE">
SELECTLAST_INSERT_ID()
</selectKey>
insertinto<includerefid="TABLE_NAME"/>(ID,NAME,AGE)
values(#{id},#{name},#{age})
</insert>只不过该中配置需要额外的一条查询SQL
小结
当数据插入操作不关心插入后数据的主键(唯一标识),那么建议使用不返回自增主键值的方式来配置插入语句,这样可以避免额外的SQL开销.
当执行插入操作后需要立即获取插入的自增主键值,比如一次操作中保存一对多这种关系的数据,那么就要使用插入后获取自增主键值的方式配置.
mybits mysql主键只能是自增的吗
mybatis自增主键配置:
mybatis进行插入操作时,如果表的主键是自增的,针对不同的数据库相应的操作也不同。基本上经常会遇到的就是 Oracle Sequece和 Mysql自增主键。主要说明下在mybatis中对于自增主键的配置。
1、不返回自增主键值:
如果考虑到插入数据的主键不作为其他表插入数据的外键使用,可以考虑这种方式。
Oracle Sequence配置
<sqlid='TABLE_NAME'>TEST_USER</sql>
<sqlid='TABLE_SEQUENCE'>SEQ_TEST_USER_ID.nextval</sql>
<!--注意这里直接调用sequence的nextval函数-->
<insertid="insert"parameterType="User">
insertinto<includerefid="TABLE_NAME"/>(ID,NAME,AGE)
values(<includerefid="TABLE_SEQUENCE"/>,#{name},#{age})
</insert>当插入语句如上配置时,那么针对如下语句
Useruser=newUser();
user.setName("test");
user.setAge(24);
userMapper.insert(user);
System.out.println(user.id);//user.id为空user.id为空,也就是说如上的配置并不能在完成插入操作后将插入时的主键值存放到保存的对象中。
2、Mysql自增主键配置
由于mysql数据库中,可以设置表的主键为自增,所以对于Mysql数据库在mybatis配置插入语句时,不指定插入ID字段即可。主键的自增交由Mysql来管理。
<sqlid='TABLE_NAME'>TEST_USER</sql>
<!--注意这里的插入SQL中是没有指明ID字段的!-->
<insertid="insert"parameterType="User">
insertinto<includerefid="TABLE_NAME"/>(NAME,AGE)
values(#{name},#{age})
</insert>同样,针对Mysql如此配置mybaits,插入完成后user.id为空。
插入后获取自增主键值:
上述的情况能满足大部分情况,但有时候我们会遇到类似一对多的那种表结构,在插入多端数据时,需要获取刚刚保存了的一段的主键。那么这个时候,上述的配置就无法满足需要了。为此我们需要使用mybatis提供的<selectKey/>来单独配置针对自增逐渐的处理。
1、Oracle Sequence配置:
<sqlid='TABLE_NAME'>TEST_USER</sql>
<sqlid='TABLE_SEQUENCE'>SEQ_TEST_USER_ID.nextval</sql>
<!--注意这里需要先查询自增主键值-->
<insertid="insert"parameterType="User">
<selectKeykeyProperty="id"resultType="int"order="BEFORE">
select<includerefid="TABLE_SEQUENCE"/>fromdual
</selectKey>
insertinto<includerefid="TABLE_NAME"/>(ID,NAME,AGE)
values(#{id},#{name},#{age})
</insert>当使用了<selectKey/>后,在实际的插入操作时,mybatis会执行以下两句SQL:
selectSEQ_TEST_USER_ID.nextvalfromdual;//语句1
insertinto(ID,NAME,AGE)values(?,?,?);//语句2在执行插入语句2之前,会先执行语句1以获取当前的ID值,然后mybatis使用反射调用User对象的setId方法,将语句1查询出的值保存在User对象中,然后才执行语句2这样就保证了执行完插入后
Useruser=newUser();
user.setName("test");
user.setAge(24);
userMapper.insert(user);
System.out.println(user.id);//user.id不为空user.id是有值的。
2、Mysql自增主键配置
针对于Mysql这种自己维护主键的数据库,可以直接使用以下配置在插入后获取插入主键,
<sqlid='TABLE_NAME'>TEST_USER</sql>
<insertid="insert"useGeneratedKeys="true"keyProperty="id"parameterType="User">
insertinto<includerefid="TABLE_NAME"/>(NAME,AGE)
values(#{name},#{age})
</insert>当然,由于Mysql的自增主键可以通过SQL语句
selectLAST_INSERT_ID();来获取的。因此针对Mysql,Mybatis也可配置如下:
<sqlid='TABLE_NAME'>TEST_USER</sql>
<!--注意这里需要先查询自增主键值-->
<insertid="insert"parameterType="User">
<selectKeykeyProperty="id"resultType="int"order="BEFORE">
SELECTLAST_INSERT_ID()
</selectKey>
insertinto<includerefid="TABLE_NAME"/>(ID,NAME,AGE)
values(#{id},#{name},#{age})
</insert>只不过该中配置需要额外的一条查询SQL
小结
当数据插入操作不关心插入后数据的主键(唯一标识),那么建议使用不返回自增主键值的方式来配置插入语句,这样可以避免额外的SQL开销.
当执行插入操作后需要立即获取插入的自增主键值,比如一次操作中保存一对多这种关系的数据,那么就要使用插入后获取自增主键值的方式配置.
MySQL为什么主键自增
MySQL之所以要使用自增主键,是因为InnoDB表与它使用时十分方便,效率明显提高。
推荐课程:MySQL教程。
InnoDB引擎表的特点
1、InnoDB引擎表是基于B+树的索引组织表(IOT)
关于B+树
B+树的特点:
所有关键字都出现在叶子结点的链表中(稠密索引),且链表中的关键字恰好是有序的;
不可能在非叶子结点命中;
非叶子结点相当于是叶子结点的索引(稀疏索引),叶子结点相当于是存储(关键字)数据的数据层;
2、如果我们定义了主键(PRIMARY KEY),那么InnoDB会选择主键作为聚集索引、如果没有显式定义主键,则InnoDB会选择第一个不包含有NULL值的唯一索引作为主键索引、如果也没有这样的唯一索引,则InnoDB会选择内置6字节长的ROWID作为隐含的聚集索引(ROWID随着行记录的写入而主键递增,这个ROWID不像ORACLE的ROWID那样可引用,是隐含的)。
3、数据记录本身被存于主索引(一颗B+Tree)的叶子节点上。这就要求同一个叶子节点内(大小为一个内存页或磁盘页)的各条数据记录按主键顺序存放,因此每当有一条新的记录插入时,MySQL会根据其主键将其插入适当的节点和位置,如果页面达到装载因子(InnoDB默认为15/16),则开辟一个新的页(节点)
4、如果表使用自增主键,那么每次插入新的记录,记录就会顺序添加到当前索引节点的后续位置,当一页写满,就会自动开辟一个新的页
5、如果使用非自增主键(如果身份证号或学号等),由于每次插入主键的值近似于随机,因此每次新纪录都要被插到现有索引页得中间某个位置,此时MySQL不得不为了将新记录插到合适位置而移动数据,甚至目标页面可能已经被回写到磁盘上而从缓存中清掉,此时又要从磁盘上读回来,这增加了很多开销,同时频繁的移动、分页操作造成了大量的碎片,得到了不够紧凑的索引结构,后续不得不通过OPTIMIZE TABLE来重建表并优化填充页面。
综上总结,如果InnoDB表的数据写入顺序能和B+树索引的叶子节点顺序一致的话,这时候存取效率是最高的,也就是下面这几种情况的存取效率最高:
使用自增列(INT/BIGINT类型)做主键,这时候写入顺序是自增的,和B+数叶子节点分裂顺序一致;
该表不指定自增列做主键,同时也没有可以被选为主键的唯一索引(上面的条件),这时候InnoDB会选择内置的ROWID作为主键,写入顺序和ROWID增长顺序一致;
除此以外,如果一个InnoDB表又没有显示主键,又有可以被选择为主键的唯一索引,但该唯一索引可能不是递增关系时(例如字符串、UUID、多字段联合唯一索引的情况),该表的存取效率就会比较差。
关于insert语句主键自增,sql语句设置主键自增的介绍到此结束,希望对大家有所帮助。