应一个好友要求写一个SpringJDBC 的文章 , 介绍返回操作数据库最新id写法

Spring Jdbc 解决了繁琐的statement 创建 连接的打开 关闭 异常的处理

spring给我们提供了jdbc的统一封装,和其它的orm不同,它是对jdbc api的封装,相当于我们自己写的java bean,而没有对对象模型进行封装(比如将po封装为pojo)。它保持了jdbc数据对象的原始性,具有极大程度的灵活性,其性能也极高。


下面所有代码都已经亲测


import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Map;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.springframework.jdbc.core.BatchPreparedStatementSetter;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.PreparedStatementCreator;
import org.springframework.jdbc.core.PreparedStatementSetter;
import org.springframework.jdbc.core.RowCallbackHandler;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.jdbc.support.GeneratedKeyHolder;
import org.springframework.jdbc.support.KeyHolder;

public class SJTest {

	JdbcTemplate jdbcTemplate = new JdbcTemplate();

	@Before
	public void init() {
		DriverManagerDataSource ds = new DriverManagerDataSource();
		ds.setDriverClassName("com.mysql.jdbc.Driver");
		ds.setUrl("jdbc:mysql://127.0.0.1:3306/test");
		ds.setUsername("root");
		ds.setPassword(""); // 我的数据库没有密码

		jdbcTemplate.setDataSource(ds);
	}
	

	/**
	 * 添加
	 */
	@Test
	public void add() {
		String sql = "insert into student(sid,name) values(?,?)";
		jdbcTemplate.update(sql, new Object[] { 3, "321" });
	}

	/**
	 * 修改
	 */
	@Test
	public void update() {
		String sql = "update student set name=? where sid=?";
		jdbcTemplate.update(sql, new Object[] { "432", 3 });
	}

	/**
	 * 删除
	 */
	@Test
	public void delete() {
		String sql = "delete from student where sid = ?";
		jdbcTemplate.update(sql, new Object[] { 3 });
	}

	/**
	 * 查询在程序设计当中占用的比重较重, 所以我出多种写法 来进行表现
	 * 在spring 中拥有较多查询方法
	 */
	
	
	// ----------------------------------首先介绍 query 开头方法
	
	/**
	 * 在下面的两个方法中 第一个不会产生非常多的系统开销,第二个非常浪费系统性能 不推荐使用 会产生 内存溢出
	 * 产生的原因主要在 用法上 第一种 processRow() 方法里面在内部实现中逐行获取 user 数据
	 * 					  第二种  mapRow() 返回一个集合通过遍历来达成目的
	 * 如果你无法理解 可以在网上查下 RowCallbackHandler 和 RowMapper 的比较
	 */
	
	@Test
	public void select() {
		// org.springframework.jdbc.core.RowCallbackHandler  是一个回调接口
		String sql = "select * from student where sid=?";
		
		final Student student = new Student();
		
		jdbcTemplate.query(sql, new Object[]{8} , new RowCallbackHandler() {
			
			@Override
			public void processRow(ResultSet rs) throws SQLException {
				// TODO Auto-generated method stub
				student.setAge(rs.getString("age"));
				student.setId(rs.getLong("sid"));
			}
		});
		
		System.out.println(student.toString());
	}
	
	@Test
	public void query() {
		String sql = "select * from student";
		
		List<List<Student>> student2 = jdbcTemplate.query(sql, new RowMapper<List<Student>>(){
			
			final List<Student >  student = new ArrayList<Student> ();
			
			@Override
			public List<Student> mapRow(ResultSet rs, int rowNum) throws SQLException {
				final Student stu = new Student();
				stu.setAge(rs.getString("age"));
				stu.setId(rs.getLong("sid"));
				student.add(stu);
				return student;
			}
		});
		System.out.println(Arrays.toString(student2.toArray()));
	}
	
	
	
	/**
	 * 在有些时候我们执行完操作需要返回数据库表的最新id spring 已经帮助我们做好了 不需要再编写sql 语句查询了
	 * 我扩展下 其实spring 也是在jdbc 基础上封装的 很多刚学习的认为spring 怎么怎么样
	 * 在jdbc 中 也有相应地方法我给大家演示下两种 Statement 和 PreparedStatement
	 */
	
	/**
	 * 使用jdbc Statement 返回里面的id 
	 * @throws SQLException 
	 */
	@Test
	public void jdbcNativeID () throws SQLException {
		 String sql = "insert into student(sid,name) values(7,'457')";
		 Connection conn = jdbcTemplate.getDataSource().getConnection();
		 Statement stmt = conn.createStatement();
		 
		 // Statement.RETURN_GENERATED_KEYS 可以绑定数据库产生的id
		 // Statement.NO_GENERATED_KEYS 不产生id 默认可能。
		 stmt.executeUpdate(sql,Statement.RETURN_GENERATED_KEYS);
		 
		 ResultSet rs = stmt.getGeneratedKeys();
		 
		 if(rs.next())
		 System.out.println("这是一个返回 数据库id 的打印 " + rs.getInt(1));
	}
	
	/**
	 * 使用jdbc PreparedStatement 返回里面的id 
	 * @throws SQLException
	 */
	@Test
	public void jdbcNativeId() throws SQLException {
		 String sql = "insert into student(sid,name) values(8,'457')";
		 Connection conn = jdbcTemplate.getDataSource().getConnection();
		 PreparedStatement ps = conn.prepareStatement(sql,PreparedStatement.RETURN_GENERATED_KEYS);
		 ps.executeUpdate();
		 ResultSet rs  = ps.getGeneratedKeys();
		 
		 if(rs.next())
	     System.out.println("这是一个返回 数据库id 的打印 " + rs.getInt(1));
	}
	
	/**
	 * 这是在spring 中返回最新id 的处理方式
	 */
	@Test
	public void resultID() {
		
		KeyHolder keyHolder = new GeneratedKeyHolder();

		final String sql = "insert into student(sid,name) values(?,?)";
		
		jdbcTemplate.update(new PreparedStatementCreator() {

			@Override
			public PreparedStatement createPreparedStatement(Connection con)
					throws SQLException {
				// TODO Auto-generated method stub
				
				PreparedStatement ps = con.prepareStatement(sql);
				ps.setString(1, "4");
				ps.setString(2, "457");
				return ps;
			}
		}, keyHolder);
		
		/**
		 * 可以调用 keyHolder.getKeyList(); 返回 List<Map<String, Object>> 或者
		 * keyHolder.getKeys(); 返回 Map<String, Object>
		 */	
		System.out.println(keyHolder.getKey().intValue());
	}

	
	
	/**
	 * 这是一种spring 批处理方式
	 */
	@Test
	public void batchUpdate() {
		String sql = "insert into student(sid,age) values(?,?)";
		
		final List<Student>  list = new ArrayList<Student>();
		
		for(int i =  1 ;  i< 10; i ++) {
			Student student = new Student();
			student.setAge(i + "1");
			student.setId(9 + i);
			list.add(student);
		}
		
		jdbcTemplate.batchUpdate(sql, new BatchPreparedStatementSetter() {
			
			@Override
			public void setValues(PreparedStatement ps, int i) throws SQLException {
				// TODO Auto-generated method stub
				Student  obj = list.get(i);
				ps.setLong(1, obj.getId());
				ps.setString(2, obj.getAge());
			}
			
			@Override
			public int getBatchSize() {
				// TODO Auto-generated method stub
				return list.size();
			}
		});
	}
	
	class Student {
		private long id;
		private String age;

		public String getAge() {
			return age;
		}

		public void setAge(String age) {
			this.age = age;
		}

		public long getId() {
			return id;
		}

		public void setId(long id) {
			this.id = id;
		}

		@Override
		public String toString() {
			return "Student [id=" + id + ", age=" + age + "]";
		}

		
	}

}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章