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 + "]";
}
}
}