zoukankan      html  css  js  c++  java
  • mysql数据库插入数据获取自增主键的三种方式(jdbc PreparedStatement方式、mybatis useGeneratedKeys方式、mybatis selectKey方式)

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

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

    为了方便描述我们先建一张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';

    一、 jdbc PreparedStatement方式

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

    代码如下:

    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()方法,在插入的执行之后,获取主键值。

    二,mybatis useGeneratedKeys方式

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

    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());
        }

    三、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属性进行赋值的,用的不多。

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

  • 相关阅读:
    HttpInvoker GET/POST方式
    maven命令
    java内存简单描述
    零零碎碎之SPU与SKU
    ZooKeeper的ACL权限
    ZooKeeper常用命令行操作
    Zookeeper基本数据模型
    ZooKeeper的安装及部署
    ZooKeeper原理及介绍
    Shell脚本编程(一)
  • 原文地址:https://www.cnblogs.com/cdf-opensource-007/p/8068575.html
Copyright © 2011-2022 走看看