mysql數據庫插入數據獲取自增主鍵的三種方式(jdbc PreparedStatement方式、mybatis useGeneratedKeys方式、mybatis selectKey方式)

一般來講對於mysql數據庫插入數據獲取主鍵的方法是採用selectKey的方式,特別是當你持久層使用mybatis框架的時候。java

本文除此以外介紹其它兩種獲取主鍵的方式。mysql

爲了方便描述咱們先建一張mysql數據庫的表:程序員

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

1、 jdbc PreparedStatement方式spring

首先介紹一種jdbc獲取主鍵的方式,其它兩種方式也是對它的封裝的實現,方便咱們使用mybatis框架的時候獲取主鍵值。sql

代碼以下:數據庫

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.ResourceBundle;

public class InformationSchema {
    
    private static Connection con=null;
    private static PreparedStatement ps=null;
    private static ResultSet rs=null;

    static{
        ResourceBundle resourceBundle = ResourceBundle.getBundle("jdbc");
        String driverName = resourceBundle.getString("jdbc.driverClassName");
        String jdbc = resourceBundle.getString("jdbc.url");
        String user = resourceBundle.getString("jdbc.username");
        String password = resourceBundle.getString("jdbc.password");
        try {
            Class.forName(driverName);
            con=DriverManager.getConnection(jdbc, user, password);
        } catch (Exception e) {
            e.printStackTrace();
        }
       
    }
    
    
    public static void insertTable(String sql) {
        try {
            //Statement.RETURN_GENERATED_KEYS,爲必傳參數
            ps = con.prepareStatement(sql,Statement.RETURN_GENERATED_KEYS);
            int count = ps.executeUpdate();
            rs= ps.getGeneratedKeys();
            rs.next();
            System.out.println(rs.getInt(1));
            
        } catch (Exception e) {
            e.printStackTrace();
        }
        
    }
    
    
    public static void main(String[] args) {
        String sql = "INSERT INTO company_01 (`name`) VALUES ('阿里巴巴')";
        insertTable(sql);
    }
    
    
}

以上這種方式,使用了 PreparedStatement 的getGeneratedKeys()方法,在插入的執行以後,獲取主鍵值。apache

二,mybatis useGeneratedKeys方式mybatis

這種方式主要使用了<insert id="insertCompany_01" useGeneratedKeys="true" keyProperty="id"></insert>標籤的這兩個屬性給傳進來的map的key或者對象的id屬性進行賦值(若爲對象,keyProperty的值須跟屬性名進行對應)app

spring和mybatis集成的xml文件框架

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
                    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
                    http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
                    http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">


    <!-- 註冊屬性文件 -->
    <context:property-placeholder location="classpath:jdbc.properties"/>

    <!-- 阿里 druid數據庫鏈接池 -->
    
    
    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
        <!-- 數據庫基本信息配置 -->
        <property name="url" value="${jdbc.url}" />
        <property name="username" value="${jdbc.username}" />
        <property name="password" value="${jdbc.password}" />
        <property name="driverClassName" value="${jdbc.driverClassName}" />

        <!-- 初始化鏈接大小 -->
        <property name="initialSize" value="${jdbc.initialSize}"></property>
        <!-- 鏈接池最大數量 -->
        <property name="maxActive" value="${jdbc.maxActive}"></property>
        <!-- 鏈接池最大空閒 -->
        <property name="maxIdle" value="${jdbc.maxIdle}"></property>
        <!-- 鏈接池最小空閒 -->
        <property name="minIdle" value="${jdbc.minIdle}"></property>
        <!-- 獲取鏈接最大等待時間 -->
        <property name="maxWait" value="${jdbc.maxWait}"></property>
    </bean>

    <!-- 配置mybatis -->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="configLocation" value="classpath:mybatis-config.xml"></property>
        <!-- mapper掃描 -->
        <property name="mapperLocations">
            <array>
                <value>classpath*:mapper/*.xml</value>
            </array>
        </property>
    </bean>

    <!-- 配置映射掃描配置器 -->
    <!-- 能夠幫助咱們掃描dao包下的全部接口生成代理實現類 -->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />
        <property name="basePackage" value="com.opensource.dao" />
    </bean>

</beans>

mybatis的sql配置文件

<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="com.opensource.dao.CompanyDao">

   <insert id="insertCompany_01"  useGeneratedKeys="true" keyProperty="id">
     INSERT INTO `company_01` (`name`) VALUES (#{name})
   </insert>
</mapper>

dao的接口:

import java.io.Serializable;

public interface CompanyDao {
    
    /**
     * 這裏傳參使用Serializable 是爲了同時兼容map和實體類的狀況
     * @param serializable
     * @return
     */
    public int insertCompany_01(Serializable serializable);
    
    
}

實體類:

import java.io.Serializable;

public class Company01 implements Serializable{
    
    private Integer id;
    private String name;
    
    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }

}

測試類:

public static void main(String[] args) {
        
        ApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"spring/spring-mybatis.xml"});
        
        CompanyDao companyDao = context.getBean(CompanyDao.class);
        //聲明這裏要用Hashmap,可序列化的
        HashMap<String,Object> map = new HashMap<String, Object>();
        map.put("name", "阿里巴巴");
        companyDao.insertCompany_01(map);
        System.out.println(map.get("id"));
        
        Company01 c01 = new Company01();
        c01.setName("騰訊");
        companyDao.insertCompany_01(c01);
        System.out.println(c01.getId());
    }

3、mybatis selectKey方式

這種方式你們用的最多,就再也不過多描述了,具體的測試方法同上

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

有必要提出一點的是,order有兩個值,AFTER或BEFORE,獲取自增id時須用AFTER,BEFORE是用來給map的key或者對象的id屬性進行賦值的,用的很少。

最後說一點,咱們做爲程序員,研究問題仍是要仔細深刻一點的。當你對原理了解的有夠透徹,開發起來也就駕輕就熟了,不少開發中的問題和疑惑也就迎刃而解了,並且在面對其餘問題的時候也可作到舉一反三。固然在開發中沒有太多的時間讓你去研究原理,開發中要以實現功能爲前提,可等項目上線的後,你有大把的時間或者空餘的時間,你大可去刨根問底,深刻的去研究一項技術,爲以爲這對一名程序員的成長是很重要的事情。

相關文章
相關標籤/搜索