spring jdbctemple 获得自动生成的主键ID

58 篇文章 0 订阅
2 篇文章 0 订阅
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.Map;

import javax.sql.DataSource;

import org.apache.commons.dbcp.BasicDataSource;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.PreparedStatementCreator;
import org.springframework.jdbc.support.GeneratedKeyHolder;
import org.springframework.jdbc.support.KeyHolder;

public class TestRetrieveAutoGeneratedKeys {

	private static final String DRIVER_CLASSNAME = "oracle.jdbc.driver.OracleDriver";
	private static final String IP = "192.168.123.72";
	private static final int PORT = 1521;
	private static final String SID = "wmdw";
	private static final String USERNAME = "dss";
	private static final String PASSWORD = "dss";
	private static final String INSERT_SQL = "insert into testid(id,name) values(test_SEQ.Nextval,?)";

	/**
	 * <pre>
	 * @param args
	 * </pre>
	 */
	public static void main(String[] args) {
		int count = 10000;
		TestRetrieveAutoGeneratedKeys test = new TestRetrieveAutoGeneratedKeys();
		DataSource dataSource = createOracleDataSource(IP, PORT, SID, USERNAME,
				PASSWORD);
		JdbcTemplate jdbcTemplate = createJdbcTemplate(dataSource);
		for (int i = 0; i < count; i++) {
			Map<String, Object> map = test.getPKs(jdbcTemplate);
			System.out.println("id:"
					+ Integer.valueOf(map.get("id").toString()).intValue());

		}
	}

	/**
	 * <pre>
	 * 得到数据库自动生成的PK的id
	 * 这里使用 oracle 数据库做的例子,其他的数据库同样适用,例如:MySQL,MS SQLServer
	 * DB: Oracle database
	 * -- Create table
	 * create table testid(
	 *        id number(11),
	 *        name  varchar2(100),
	 *        primary key(id)
	 * )
	 * 
	 * -- Create sequence 
	 * create sequence test_SEQ
	 * minvalue 1
	 * maxvalue 9999999999999999999999999999
	 * start with 1
	 * increment by 1
	 * nocache;
	 *  @return
	 * </pre>
	 */
	private Map<String, Object> getPKs(JdbcTemplate jdbcTemplate) {

		KeyHolder keyHolder = createKeyHolder();
		jdbcTemplate.update(new PreparedStatementCreator() {
			public PreparedStatement createPreparedStatement(
					Connection connection) throws SQLException {
				PreparedStatement ps = connection.prepareStatement(INSERT_SQL,
						new int[] { 1 });
				ps.setString(1, "name-1");
				return ps;
			}
		}, keyHolder);
		return keyHolder.getKeys();
	}

	private static DataSource createOracleDataSource(String ip, int port,
			String sid, String username, String password) {
		String url = "jdbc:oracle:thin:@" + ip + ":" + port + ":" + sid;
		BasicDataSource dataSource = createBasicDataSource();
		dataSource.setDriverClassName(DRIVER_CLASSNAME);
		dataSource.setUrl(url);
		dataSource.setUsername(username);
		dataSource.setPassword(password);
		return dataSource;
	}

	private static BasicDataSource createBasicDataSource() {
		return new BasicDataSource();
	}

	private static KeyHolder createKeyHolder() {
		return new GeneratedKeyHolder();
	}

	private static JdbcTemplate createJdbcTemplate(DataSource dataSource) {
		return new JdbcTemplate(dataSource);
	}

}

  另外可以参考一下org.springframework.jdbc.core.simple.AbstractJdbcInsert.java的源代码,看见spring是如何写的。

部分内容如下:

	/**
	 * Method to execute the insert generating any number of keys
	 */
	private KeyHolder executeInsertAndReturnKeyHolderInternal(final List<Object> values) {
		if (logger.isDebugEnabled()) {
			logger.debug("The following parameters are used for call " + getInsertString() + " with: " + values);
		}
		final KeyHolder keyHolder = new GeneratedKeyHolder();
		if (this.tableMetaDataContext.isGetGeneratedKeysSupported()) {
			getJdbcTemplate().update(
					new PreparedStatementCreator() {
						@Override
						public PreparedStatement createPreparedStatement(Connection con) throws SQLException {
							PreparedStatement ps = prepareStatementForGeneratedKeys(con);
							setParameterValues(ps, values, getInsertTypes());
							return ps;
						}
					},
					keyHolder);
		}
		else {
			if (!this.tableMetaDataContext.isGetGeneratedKeysSimulated()) {
				throw new InvalidDataAccessResourceUsageException(
						"The getGeneratedKeys feature is not supported by this database");
			}
			if (getGeneratedKeyNames().length < 1) {
				throw new InvalidDataAccessApiUsageException("Generated Key Name(s) not specified. " +
						"Using the generated keys features requires specifying the name(s) of the generated column(s)");
			}
			if (getGeneratedKeyNames().length > 1) {
				throw new InvalidDataAccessApiUsageException(
						"Current database only supports retrieving the key for a single column. There are " +
						getGeneratedKeyNames().length  + " columns specified: " + Arrays.asList(getGeneratedKeyNames()));
			}
			// This is a hack to be able to get the generated key from a database that doesn't support
			// get generated keys feature. HSQL is one, PostgreSQL is another. Postgres uses a RETURNING
			// clause while HSQL uses a second query that has to be executed with the same connection.
			final String keyQuery = this.tableMetaDataContext.getSimulationQueryForGetGeneratedKey(
					this.tableMetaDataContext.getTableName(), getGeneratedKeyNames()[0]);
			Assert.notNull(keyQuery, "Query for simulating get generated keys can't be null");
			if (keyQuery.toUpperCase().startsWith("RETURNING")) {
				Long key = getJdbcTemplate().queryForObject(getInsertString() + " " + keyQuery,
						values.toArray(new Object[values.size()]), Long.class);
				Map<String, Object> keys = new HashMap<String, Object>(1);
				keys.put(getGeneratedKeyNames()[0], key);
				keyHolder.getKeyList().add(keys);
			}
			else {
				getJdbcTemplate().execute(new ConnectionCallback<Object>() {
					@Override
					public Object doInConnection(Connection con) throws SQLException, DataAccessException {
						// Do the insert
						PreparedStatement ps = null;
						try {
							ps = con.prepareStatement(getInsertString());
							setParameterValues(ps, values, getInsertTypes());
							ps.executeUpdate();
						}
						finally {
							JdbcUtils.closeStatement(ps);
						}
						//Get the key
						Statement keyStmt = null;
						ResultSet rs = null;
						Map<String, Object> keys = new HashMap<String, Object>(1);
						try {
							keyStmt = con.createStatement();
							rs = keyStmt.executeQuery(keyQuery);
							if (rs.next()) {
								long key = rs.getLong(1);
								keys.put(getGeneratedKeyNames()[0], key);
								keyHolder.getKeyList().add(keys);
							}
						}
						finally {
							JdbcUtils.closeResultSet(rs);
							JdbcUtils.closeStatement(keyStmt);
						}
						return null;
					}
				});
			}
			return keyHolder;
		}
		return keyHolder;
	}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
您好!要使用 JdbcTemplate 操作 Blob 类型,可以按照以下步骤进行操作: 1. 首先,创建一个 `DataSource` 对象,用于连接到数据库。可以使用 Spring 的 `DriverManagerDataSource` 或者其他适合您的数据源实现。 2. 然后,创建一个 `JdbcTemplate` 对象,将数据源作为参数传入构造函数。 ```java JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource); ``` 3. 接下来,可以使用 `jdbcTemplate` 对象执行 SQL 查询和更新操作。对于 Blob 类型的操作,可以使用 `jdbcTemplate` 的 `execute` 方法,并传入一个 `PreparedStatementCallback` 对象。 ```java jdbcTemplate.execute("INSERT INTO your_table (blob_column) VALUES (?)", new PreparedStatementCallback<Object>() { @Override public Object doInPreparedStatement(PreparedStatement ps) throws SQLException, DataAccessException { // 将 Blob 数据设置到 PreparedStatement 中 Blob blob = createBlobFromData(); // 创建 Blob 对象,可以根据需要自己实现 ps.setBlob(1, blob); ps.executeUpdate(); return null; } }); ``` 在上面的示例中,我们通过 `setBlob` 方法将 Blob 数据设置到 PreparedStatement 中,并执行更新操作。 4. 当需要从数据库中获取 Blob 类型的数据时,可以使用 `jdbcTemplate` 的 `query` 方法,并传入一个 `RowMapper` 对象。 ```java byte[] blobData = jdbcTemplate.query("SELECT blob_column FROM your_table WHERE id = ?", new Object[]{id}, new ResultSetExtractor<byte[]>() { @Override public byte[] extractData(ResultSet rs) throws SQLException, DataAccessException { if (rs.next()) { Blob blob = rs.getBlob("blob_column"); if (blob != null) { return blob.getBytes(1, (int) blob.length()); } } return null; } }); ``` 在上面的示例中,我们通过 `getBlob` 方法获取 Blob 数据,并使用 `getBytes` 方法将其转换为字节数组。 这样,您就可以使用 JdbcTemplate 操作 Blob 类型的数据了。请注意,上述示例中的表名、列名和参数均需要根据您的实际情况进行修改。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值