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