通常来说对于mysql数据库插入数据获取主键的方法是采用selectKey的方式,特别是当你持久层使用mybatis框架的时候。

本文除此之外介绍其它两种获取主键的方式。

为了方便描述我们先建一张mysql数据库的表:

  1. CREATE TABLE `company_01` (
  2. `id` int(11) NOT NULL AUTO_INCREMENT,
  3. `name` varchar(50) NOT NULL,
  4. PRIMARY KEY (`id`)
  5. ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='company_01';

一、 jdbc PreparedStatement方式

首先介绍一种jdbc获取主键的方式,其它两种方式也是对它的封装的实现,方便我们使用mybatis框架的时候获取主键值。

代码如下:

  1. import java.sql.Connection;
  2. import java.sql.DriverManager;
  3. import java.sql.PreparedStatement;
  4. import java.sql.ResultSet;
  5. import java.sql.SQLException;
  6. import java.sql.Statement;
  7. import java.util.ArrayList;
  8. import java.util.HashMap;
  9. import java.util.List;
  10. import java.util.Map;
  11. import java.util.ResourceBundle;
  12.  
  13. public class InformationSchema {
  14.  
  15. private static Connection con=null;
  16. private static PreparedStatement ps=null;
  17. private static ResultSet rs=null;
  18.  
  19. static{
  20. ResourceBundle resourceBundle = ResourceBundle.getBundle("jdbc");
  21. String driverName = resourceBundle.getString("jdbc.driverClassName");
  22. String jdbc = resourceBundle.getString("jdbc.url");
  23. String user = resourceBundle.getString("jdbc.username");
  24. String password = resourceBundle.getString("jdbc.password");
  25. try {
  26. Class.forName(driverName);
  27. con=DriverManager.getConnection(jdbc, user, password);
  28. } catch (Exception e) {
  29. e.printStackTrace();
  30. }
  31.  
  32. }
  33.  
  34. public static void insertTable(String sql) {
  35. try {
  36. //Statement.RETURN_GENERATED_KEYS,为必传参数
  37. ps = con.prepareStatement(sql,Statement.RETURN_GENERATED_KEYS);
  38. int count = ps.executeUpdate();
  39. rs= ps.getGeneratedKeys();
  40. rs.next();
  41. System.out.println(rs.getInt(1));
  42.  
  43. } catch (Exception e) {
  44. e.printStackTrace();
  45. }
  46.  
  47. }
  48.  
  49. public static void main(String[] args) {
  50. String sql = "INSERT INTO company_01 (`name`) VALUES ('阿里巴巴')";
  51. insertTable(sql);
  52. }
  53.  
  54. }

以上这种方式,使用了 PreparedStatement 的getGeneratedKeys()方法,在插入的执行之后,获取主键值。

二,mybatis useGeneratedKeys方式

这种方式主要使用了<insert id="insertCompany_01" useGeneratedKeys="true" keyProperty="id"></insert>标签的这两个属性给传进来的map的key或者对象的id属性进行赋值(若为对象,keyProperty的值须跟属性名进行对应)

spring和mybatis集成的xml文件

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xmlns:p="http://www.springframework.org/schema/p"
  5. xmlns:context="http://www.springframework.org/schema/context"
  6. xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
  7. xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
  8. http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
  9. http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
  10. http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
  11.  
  12. <!-- 注册属性文件 -->
  13. <context:property-placeholder location="classpath:jdbc.properties"/>
  14.  
  15. <!-- 阿里 druid数据库连接池 -->
  16.  
  17. <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
  18. <!-- 数据库基本信息配置 -->
  19. <property name="url" value="${jdbc.url}" />
  20. <property name="username" value="${jdbc.username}" />
  21. <property name="password" value="${jdbc.password}" />
  22. <property name="driverClassName" value="${jdbc.driverClassName}" />
  23.  
  24. <!-- 初始化连接大小 -->
  25. <property name="initialSize" value="${jdbc.initialSize}"></property>
  26. <!-- 连接池最大数量 -->
  27. <property name="maxActive" value="${jdbc.maxActive}"></property>
  28. <!-- 连接池最大空闲 -->
  29. <property name="maxIdle" value="${jdbc.maxIdle}"></property>
  30. <!-- 连接池最小空闲 -->
  31. <property name="minIdle" value="${jdbc.minIdle}"></property>
  32. <!-- 获取连接最大等待时间 -->
  33. <property name="maxWait" value="${jdbc.maxWait}"></property>
  34. </bean>
  35.  
  36. <!-- 配置mybatis -->
  37. <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
  38. <property name="dataSource" ref="dataSource" />
  39. <property name="configLocation" value="classpath:mybatis-config.xml"></property>
  40. <!-- mapper扫描 -->
  41. <property name="mapperLocations">
  42. <array>
  43. <value>classpath*:mapper/*.xml</value>
  44. </array>
  45. </property>
  46. </bean>
  47.  
  48. <!-- 配置映射扫描配置器 -->
  49. <!-- 可以帮助我们扫描dao包下的所有接口生成代理实现类 -->
  50. <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
  51. <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />
  52. <property name="basePackage" value="com.opensource.dao" />
  53. </bean>
  54.  
  55. </beans>

mybatis的sql配置文件

  1. <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  2.  
  3. <mapper namespace="com.opensource.dao.CompanyDao">
  4.  
  5. <insert id="insertCompany_01" useGeneratedKeys="true" keyProperty="id">
  6.   INSERT INTO `company_01` (`name`) VALUES (#{name})
  7. </insert>
  8. </mapper>

dao的接口:

  1. import java.io.Serializable;
  2.  
  3. public interface CompanyDao {
  4.  
  5. /**
  6. * 这里传参使用Serializable 是为了同时兼容map和实体类的情况
  7. * @param serializable
  8. * @return
  9. */
  10. public int insertCompany_01(Serializable serializable);
  11.  
  12. }

实体类:

  1. import java.io.Serializable;
  2.  
  3. public class Company01 implements Serializable{
  4.  
  5. private Integer id;
  6. private String name;
  7.  
  8. public Integer getId() {
  9. return id;
  10. }
  11. public void setId(Integer id) {
  12. this.id = id;
  13. }
  14. public String getName() {
  15. return name;
  16. }
  17. public void setName(String name) {
  18. this.name = name;
  19. }
  20.  
  21. }

测试类:

  1. public static void main(String[] args) {
  2.  
  3. ApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"spring/spring-mybatis.xml"});
  4.  
  5. CompanyDao companyDao = context.getBean(CompanyDao.class);
  6. //声明这里要用Hashmap,可序列化的
  7. HashMap<String,Object> map = new HashMap<String, Object>();
  8. map.put("name", "阿里巴巴");
  9. companyDao.insertCompany_01(map);
  10. System.out.println(map.get("id"));
  11.  
  12. Company01 c01 = new Company01();
  13. c01.setName("腾讯");
  14. companyDao.insertCompany_01(c01);
  15. System.out.println(c01.getId());
  16. }

三、mybatis selectKey方式

这种方式大家用的最多,就不再过多描述了,具体的测试方法同上

  1. <insert id="insertCompany_01">
  2. INSERT INTO `company_01` (`name`) VALUES (#{name})
  3. <selectKey resultType="java.lang.Integer" order="AFTER" keyProperty="id">
  4. SELECT LAST_INSERT_ID();
  5. </selectKey>
  6. </insert>

有必要提出一点的是,order有两个值,AFTER或BEFORE,获取自增id时须用AFTER,BEFORE是用来给map的key或者对象的id属性进行赋值的,用的不多。

最后说一点,我们作为程序员,研究问题还是要仔细深入一点的。当你对原理了解的有够透彻,开发起来也就得心应手了,很多开发中的问题和疑惑也就迎刃而解了,而且在面对其他问题的时候也可做到触类旁通。当然在开发中没有太多的时间让你去研究原理,开发中要以实现功能为前提,可等项目上线的后,你有大把的时间或者空余的时间,你大可去刨根问底,深入的去研究一项技术,为觉得这对一名程序员的成长是很重要的事情。

mysql数据库插入数据获取自增主键的三种方式(jdbc PreparedStatement方式、mybatis useGeneratedKeys方式、mybatis selectKey方式)的更多相关文章

  1. mysql数据库表的自增主键号不规律,重新排列

    mysql数据库表的自增主键ID乱了,需要重新排序. 原理:删除原有的自增ID,重新建立新的自增ID. 1.删除原有主键: ALTER TABLE `table_name` DROP `id`; 2. ...

  2. Mysql数据库表的自增主键ID号乱了,需要重新排列。

    Mysql数据库表的自增主键ID号乱了,需要重新排列. 原理:删除原有的自增ID,重新建立新的自增ID. 1,删除原有主键:ALTER TABLE `table_name` DROP `id`; 2, ...

  3. 关于mybatis用mysql时,插入返回自增主键的问题

    公司决定新项目用mybatis,虽然这个以前学过但是一直没用过都忘得差不多了,而且项目比较紧,也没时间去系统点的学一学,只好很粗略的百度达到能用的程度就行了. 其中涉及到插入实体要求返回主键id的问题 ...

  4. mysql数据库单表只有一个主键自增id字段,ibatis实现id自增

    mysql数据库单表只有一个主键自增id字段,ibatis实现id自增 <insert id="autoid">        insert into user_id ...

  5. MySQL 插入与自增主键值相等的字段 与 高并发下保证数据准确的实验

    场景描述: 表t2 中 有 自增主键 id  和 字段v  当插入记录的时候 要求 v与id 的值相等(按理来说这样的字段是需要拆表的,但是业务场景是 只有某些行相等 ) 在网上搜的一种办法是 先获取 ...

  6. MYSQL获取自增主键【4种方法】

    通常我们在应用中对mysql执行了insert操作后,需要获取插入记录的自增主键.本文将介绍java环境下的4种方法获取insert后的记录主键auto_increment的值: 通过JDBC2.0提 ...

  7. Mybatis批量插入返回自增主键(转)

    我们都知道Mybatis在插入单条数据的时候有两种方式返回自增主键: 1.对于支持生成自增主键的数据库:useGenerateKeys和keyProperty. 2.不支持生成自增主键的数据库:< ...

  8. MYSQL获取自增主键【4种方法】(转)

    转自:http://blog.csdn.net/ultrani/article/details/9351573 作者已经写的非常好了,我不废话了,直接转载收藏: 通常我们在应用中对mysql执行了in ...

  9. mysql数据库表操作-表的主键索引和普通索引

    数据库索引就象书的目录一样,如果在字段上建立了索引,那么以索引列为查询条件时可以加快查询数据的速度.查询数据库,按主键查询是最快的,每个表只能有一个主键列,但是可以有多个普通索引列,主键列要求列的所有 ...

随机推荐

  1. poj 3321Apple Tree

    Apple Tree Time Limit:2000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u Submit S ...

  2. PHP基础入门(二)【PHP函数基础】

    PHP基础入门(二)--函数基础 了解 PHP基础入门详解(一) 后,给大家分享一下PHP的函数基础. 这部分主要讲的就是: 函数的声明与使用.PHP中变量的作用域.静态变量.函数的参数传递.变量函数 ...

  3. keepalived中的脑裂

    在高可用(HA)系统中,当联系2个节点的“心跳线”断开时,本来为一整体.动作协调的HA系统,就分裂成为2个独立的个体.由于相互失去了联系,都以为是对方出了故障.两个节点上的HA软件像“裂脑人”一样,争 ...

  4. 注销/etc/passwd带来的系统登陆不上

    今天在修改虚拟机密码上的时候,将/etc/passwd中root所在的哪行注销掉了,想象是注销了,root登陆时应该不要输入密码,结果是系统进度条走到最后的时候 进入不了系统了. 结果去普及了下/et ...

  5. 使用weinre远程调试

    1.调试环境: 1)使用nodejs搭建调试服务器: 先安装node,然后使用npm安装weinre,在node.js安装目录输入以下命令 npm install weinre 2)需要wifi环境和 ...

  6. MQTT——订阅报文

    我们已经把相关的连接报文搞定了.笔者想来想去还是决定先讲解一下订阅报文(SUBSCRIBE ).如果传统的通信方式是客户端和服务端之间一般就直接传输信息.但是MQTT的通信方式是通过发布/订阅的方式进 ...

  7. 分享如何将git项目导入GitHub(附创建分支)

    前言:我们应该很多都会有自己的私有项目,大多情况都是存放在自己的硬盘中,今天我分享一下怎么讲自己的私有项目更新到GitHub上,这样再也不用担心项目丢失了. 一:下载git 下载链接git链接,根据自 ...

  8. sql 1.1 1.1.1 1.10.1 排序

    解决思路:计算每位的权重,得到序号完整的权重值,使用权重值进行排序! 创建sql 函数如下: ALTER FUNCTION [dbo].[SequenceToOrderNum] ( @Sequence ...

  9. CentOS6.8系统下,ecipse下进行编辑操作,意外退出

    错误情况:centos下打开eclipse软件,点击*.java或者*.pom软件卡死,命令行终端报错误信息,稍后eclipse自动退出. 错误信息: Java: cairo-misc.c:380: ...

  10. CSS3属性——“box-flex”

    CSS3的新增属性有很多,其中有一个比较神奇的,通常称为盒子模型布局,不需要把div浮动,也能合理分配.看如下例子: HTML: <div id="box"> < ...