應一個好友要求寫一個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 + "]";
		}

		
	}

}


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