`
zhangzuanqian
  • 浏览: 268795 次
  • 来自: ...
社区版块
存档分类
最新评论

spring jdbc 获取主键值 mysql

 
阅读更多
最近在做J-Hi融合SpringJDBC时遇到一个棘手的问题,那就是在insert一条记录时如何取回记录主键值的?问题主要让我纠结在对跨数据库SpringJDBC的处理上,大家都知道象SQLServer或MyServer主键的值是以自增的方式,而象Oracle主建的值通过序列生成并通过insert将值直接插入到表中的。为此SpringJDBC提供了两种机制,
    1、主键自增的解决方案
        KeyHolder keyHolder = new GeneratedKeyHolder(); 
        
this.getJdbcTemplate().update(new PreparedStatementCreator(){

            
public PreparedStatement createPreparedStatement(Connection con)
                    
throws SQLException {
   
PreparedStatement ps
=con.prepareStatement(sql,Statement.RETURN_GENERATED_KEYS);
 
                
return ps;
            }
            
        }, keyHolder);
        
    
return keyHolder.getKey().intValue();
keyHolder 数据库自增主键值的持有者,它监听PreparedStatement的返回的值Statement.RETURN_GENERATED_KEYS获取主键值,并存放在自己的池中(实际上是一个list)一般来说,一个keyHolder实例只绑定一个PreparedStatement的执行,当然最好也只是插入一条数据库记录,这样才能保证池中只有一个主键值。
当keyHolder获得主键值后,您可以在任何时候通过访问keyHolder对象得到这个主键值,也就是说只要它的生命期存在,这个主键的值就一直不会丢失。
总结:1)、在执行
PreparedStatement之前创建自增主键的持有者对象keyHolder
      2)、在创建
PreparedStatement对象时一定要声明返回主键值,列如con.prepareStatement(sql,Statement.RETURN_GENERATED_KEYS)
      3)、只要keyHolder的生命期存在,那么主键的值在任何时候与位置你都可以取得到

    2、检索数据库序列生成的主键的解决方案
        OracleSequenceMaxValueIncrementer incr = new OracleSequenceMaxValueIncrementer(dataSource, "SIMPLE_SEQUENCE");
        
return incr.nextIntValue();
象Oracle这样的数据库SpringJDBC的解决方案一目了解,通过给定数据源dataSource与序列名"SIMPLE_SEQUENCE"就可以这个序列的最大值。当然还可以通过这个类设计缓冲区大小通过setCacheSize方法,该方法可以一次性取出多个值以减少与数据库的访问次数(数据库的交互是很耗时与耗费资源的)

J-Hi的问题与解决方法
    因为J-Hi要实现跨数据库跨多个ORM框架因此对于SpringJDBC这两种方案必须要融合到一起,并且在总体设计上还要与其它的ORM框架(目前J-Hi已融合的ORM框架有hibernate、ibatis2、ibatis3)的接口声明相兼容,因此在对SpringJDBC集成的总体设计上我借鉴了hibernate的方言思想,通过方言将SpringJDBC两种方案融合在J-Hi之中以实现对不同类型数据库主键管理的差异性。
        KeyHolder keyHolder = new GeneratedKeyHolder(); 
        
this.getJdbcTemplate().update(new PreparedStatementCreator(){

            
public PreparedStatement createPreparedStatement(Connection con)
                    
throws SQLException {
  
ISpringJDBCHiDialect dialect 
= sessionFactory.getDialect();   
PreparedStatement ps
=con.prepareStatement(sql,Statement.RETURN_GENERATED_KEYS);
 
                    
if(stepFlage == primaryKeyIndex && valueClass.getPropertyName().equals(primaryKeyName)){
                        Number _id 
= dialect.getSelectKey(entity.getEntityName(), getJdbcTemplate().getDataSource());
                
return ps;
            }
            
        }, keyHolder);
        
        
if(obj.getPrimarykey() == null)
            BeanUtil.setPropertyValue(obj, 
"id", keyHolder.getKey().intValue());

从原生的SQL语句上讲Oracle在insert时要插入主键值,而SQLServer恰好相反必须不能插入主键的值,我在设计上就是抓住这一特性,再结合方言,实现了跨数据库的SpringJDBC, dialect.getSelectKey()方法,对应不同的数据库方言,如果是oracle就会生成主键的值,而如果是SQLServer这个方法不会返回任何值,代码如下
Oracle的方言方法:
    public Number getSelectKey(String entityName, DataSource dataSource) {
        OracleSequenceMaxValueIncrementer incr 
= new OracleSequenceMaxValueIncrementer(dataSource, "HIBERNATE_SEQUENCE");
        
return incr.nextIntValue();
    }
SQLServer的方言方法:
    public Number getSelectKey(String entityName, DataSource dataSource) {
//        自增主键不用实现该方法
        return null;
    }
通过返回主键值是否为null,还判断在拼写sql时是否插入主键字段的值
最后通过
        if(obj.getPrimarykey() == null)
            BeanUtil.setPropertyValue(obj, 
"id", keyHolder.getKey().intValue());
Pojo对象是否主键值(如果没有就说明是自增型的如SQLServer,如果有就说明是序列生成的如Oracle),来将其赋值到POJO的属性中.
 
转自:http://www.blogjava.net/hao-zhang-hi/archive/2011/04/21/348599.html
分享到:
评论

相关推荐

    Spring Jdbc的jar包

    在事务和JDBC操作的配合下,Spring JDBC支持多种数据库供应商,如MySQL、Oracle、PostgreSQL等,这得益于其良好的数据库供应商无关性。通过`DataSource`的配置,开发者可以轻松切换不同的数据库,而无需修改大部分...

    SpringMVC+JDBC+Redis+Mysql+EasyUI simba精简版本

    Spring Data Redis库提供了对Redis的集成,包括操作键值、哈希、集合、有序集合等功能,并支持事务、发布/订阅模式等高级特性。通过配置RedisTemplate或StringRedisTemplate,可以轻松地在SpringMVC应用中使用Redis...

    Redis+mysql整合spring的Demo

    5. **Spring JDBC**: Spring JDBC模块提供了对JDBC的封装,简化了数据库操作。在整合MySQL时,我们可以通过配置DataSource和JdbcTemplate来执行SQL语句。 6. **整合过程**: - 首先,需要在项目中添加Redis和MySQL...

    spring+springMVC+Mybatis+MYSQL+Redis+Maven项目整合源码.zip

    Mybatis避免了几乎所有的JDBC代码和手动设置参数以及获取结果集。在本项目中,Mybatis与MySQL数据库配合,用于数据的增删改查操作,通过XML或注解的方式定义SQL语句。 4. **MySQL**:MySQL是一种关系型数据库管理...

    maven 创建 spring + springmvc + mybatis + redis + mysql 学生查询例子

    在本项目中,Maven的pom.xml文件定义了所有依赖项,包括Spring、SpringMVC、MyBatis、Redis和MySQL的JDBC驱动,以及所需的其他库。 Spring框架是Java企业级应用的核心组件,提供IoC(Inversion of Control)和AOP...

    源码:【Spring+MyBatis+MySQL实战入门】一、MyBatis操作入门

    - 插入(Insert):使用`<insert>`标签定义插入操作,返回主键值。 - 查询(Select):使用`<select>`标签定义查询操作,可选结果映射。 - 更新(Update):使用`<update>`标签定义更新操作。 - 删除(Delete)...

    Spring Cloud 开源系统SpringBoot、MyBatis、Redis、 MySql、 ….zip

    在Spring Boot应用中,我们可以使用JDBC或者JPA(比如Hibernate)来与MySQL进行交互,实现数据的增删改查。 在实际的毕业设计过程中,你可能需要完成以下步骤: 1. **环境搭建**:安装并配置Java环境,下载并设置...

    springBoot+mysql+redis基础项目

    Spring Boot通过JDBC或MyBatis等数据访问技术与MySQL进行交互,实现对数据库的查询和操作。 【Redis】则是一个高性能的键值存储系统,常被用作缓存服务。它以内存中的数据结构存储数据,读写速度快,特别适合频繁...

    springboot+mybatis+druid+mysql DEMO

    Mybatis避免了几乎所有的JDBC代码和手动设置参数以及获取结果集。Mybatis可以使用简单的XML或注解进行配置和原始映射,将接口和Java的POJOs(Plain Old Java Objects,普通的Java对象)映射成数据库中的记录。在本DEMO...

    springboot整合mybatis和mysql

    - **JDBC驱动**:确保项目中包含MySQL的JDBC驱动依赖,如`mysql-connector-java`。 - **数据源配置**:在Spring Boot的配置文件中指定MySQL的连接信息,包括数据库名称、用户名、密码、端口等。 - **自动配置**:...

    spring-boot-redis.zip

    在Spring Boot中集成MySQL,我们可以使用JDBC或Spring Data JPA来处理数据操作。MyBatis则作为一个优秀的持久层框架,它允许开发者将SQL语句直接写在XML映射文件或注解中,实现了SQL与Java代码的解耦,提高了开发...

    spring mvc 配置多数据源

    jdbc-mysql.url=jdbc:mysql://localhost:3306/test jdbc-mysql.username=root jdbc-mysql.password=229 ``` 这里需要注意,每个数据源的配置都应当独立且完整,包括连接字符串、用户名、密码等必要信息。 #### 3. ...

    java中将数据库中数据赋值给Map对象源代码

    Spring框架提供了强大的数据访问抽象,包括Spring JDBC模块,使得与数据库交互变得更加简单。本文将深入探讨如何在Java中利用Spring JDBC将数据库查询结果转换为Map对象。 首先,确保已经引入了Spring JDBC的相关...

    Springboot+maven+idea+mysql实战之获取数据库信息显示在前端

    在本教程中,我们将探讨如何使用Spring Boot、Maven、IntelliJ IDEA和MySQL数据库创建一个实战项目,目的是从数据库获取信息并在前端展示。首先,我们需要确保我们的开发环境已准备就绪,包括安装IntelliJ IDEA作为...

    springboot整合mongodb+redis+mybatis+mysql

    SpringBoot 整合 MySQL 通常使用 `spring-boot-starter-jdbc` 或 `spring-boot-starter-data-jpa` 依赖,其中 JPA(Java Persistence API)是 Java 提供的 ORM(对象关系映射)标准,可以方便地进行对象与数据库表...

    springboot-mybatis-mysql-redis demo

    MyBatis避免了几乎所有的JDBC代码和手动设置参数以及获取结果集。MyBatis可以使用简单的XML或注解进行配置和原始映射,将接口和Java的POJOs(Plain Old Java Objects,普通的Java对象)映射成数据库中的记录。 ...

    shiro-freemarker-springBoot- redis-mysql

    Spring Boot通过JDBC或MyBatis等库与MySQL交互,进行数据的CRUD操作。 综上所述,"shiro-freemarker-springBoot-redis-mysql"项目是一个利用JavaWeb技术栈构建的全功能Web应用。它利用Shiro进行安全控制,...

    spring-jpa(hibernate实现)环境搭建

    例如,我们可以使用`@Entity`注解来标记一个Java类为数据库实体,`@Table`来指定对应的数据库表,`@Id`来定义主键,以及`@GeneratedValue`来自动生成主键值。 接下来,我们需要配置Spring的ApplicationContext,...

    springboot-shiros-mybatis-redis+mysql(前后分离)

    MyBatis避免了几乎所有的JDBC代码和手动设置参数以及获取结果集。MyBatis可以使用简单的XML或注解进行配置和原始映射,将接口和Java的POJOs(Plain Old Java Objects,普通的Java对象)映射成数据库中的记录。 ...

    java贷款项目spring+springMVC+mybatis+redis+mysql

    该贷款项目是一个基于Java技术栈的全面解决方案,利用Spring、SpringMVC、Mybatis和Redis等主流框架构建,配合MySQL数据库,旨在实现高效且可扩展的信贷服务。下面将详细介绍这些关键技术及其在项目中的作用。 1. *...

Global site tag (gtag.js) - Google Analytics