JAVA-Spring 整合 JDBC
一、回顾JDBC 1.java操作关系型数据的API。 导入相关数据库的驱动包后可以通过JDBC提供的接口来操作数据库。 2.实现JDBC的六个步骤 注册数据库驱动 获取数据库连接 获取传输器对象 传输sql执行获取结果集对象 遍历结果集获取信息 关闭资源
1 package cn.tedu.jdbc; 2
3 import java.sql.Connection; 4 import java.sql.DriverManager; 5 import java.sql.PreparedStatement; 6 import java.sql.ResultSet; 7 import java.sql.SQLException; 8
9
10 /**
11 create database springdb; 12 use springdb; 13 create table stu(id int primary key auto_increment,name varchar(255),addr varchar(255)); 14 insert into stu values (null,‘aaa‘,‘bj‘),(null,‘bbb‘,‘sh‘),‘ccc‘,‘gz‘),‘ddd‘,‘eee‘,‘bj‘); 15 */
16 public class Demo01 { 17 public static void main(String[] args){ 18 Connection conn = null; 19 PreparedStatement ps = null; 20 ResultSet rs = null; 21 try { 22 //1.注册数据库驱动
23 Class.forName("com.mysql.jdbc.Driver"); 24 //2.获取数据库连接
25 conn = DriverManager.getConnection("jdbc:mysql:///springdb","root","root"); 26 //3.获取传输器
27 ps = conn.prepareStatement("select * from stu where id < ?"); 28 ps.setInt(1,4); 29 //4.执行sql获取结果集
30 rs = ps.executeQuery(); 31 //5.遍历结果集获取结果
32 while(rs.next()){ 33 String name = rs.getString("name"); 34 System.out.println(name); 35 } 36 } catch (Exception e) { 37 e.printStackTrace(); 38 } finally { 39 //6.关闭资源
40 if(rs!=null){ 41 try { 42 rs.close(); 43 } catch (SQLException e) { 44 e.printStackTrace(); 45 } finally{ 46 rs = null; 47 } 48 } 49 if(ps!=null){ 50 try { 51 ps.close(); 52 } catch (SQLException e) { 53 e.printStackTrace(); 54 } finally{ 55 ps = null; 56 } 57 } 58 if(conn!=null){ 59 try { 60 conn.close(); 61 } catch (SQLException e) { 62 e.printStackTrace(); 63 } finally{ 64 conn = null; 65 } 66 } 67 } 68
69 } 70 }
3.数据库连接池(数据源) C3P0连接池
1 package cn.tedu.jdbc; 2
3 import java.beans.PropertyVetoException; 4 import java.sql.Connection; 5 import java.sql.PreparedStatement; 6 import java.sql.ResultSet; 7 import java.sql.SQLException; 8
9 import com.mchange.v2.c3p0.ComboPooledDataSource; 10
11
12 /**
13 create database springdb; 14 use springdb; 15 create table stu(id int primary key auto_increment,addr varchar(255)); 16 insert into stu values (null,‘bj‘); 17 */
18 public class Demo02 { 19 private static ComboPooledDataSource dataSource = new ComboPooledDataSource(); 20 static{ 21 try { 22 dataSource.setDriverClass("com.mysql.jdbc.Driver"); 23 dataSource.setJdbcUrl("jdbc:mysql:///springdb"); 24 dataSource.setUser("root"); 25 dataSource.setPassword("root"); 26 } catch (PropertyVetoException e) { 27 e.printStackTrace(); 28 throw new RuntimeException(e); 29 } 30 } 31
32 public static void main(String[] args){ 33 Connection conn = null; 34 PreparedStatement ps = null; 35 ResultSet rs = null; 36 try { 37 //1.2.从数据源中获取连接
38 conn = dataSource.getConnection(); 39 //3.获取传输器
40 ps = conn.prepareStatement("select * from stu where id < ?"); 41 ps.setInt(1,4); 42 //4.执行sql获取结果集
43 rs = ps.executeQuery(); 44 //5.遍历结果集获取结果
45 while(rs.next()){ 46 String name = rs.getString("name"); 47 System.out.println(name); 48 } 49 } catch (Exception e) { 50 e.printStackTrace(); 51 } finally { 52 //6.关闭资源
53 if(rs!=null){ 54 try { 55 rs.close(); 56 } catch (SQLException e) { 57 e.printStackTrace(); 58 } finally{ 59 rs = null; 60 } 61 } 62 if(ps!=null){ 63 try { 64 ps.close(); 65 } catch (SQLException e) { 66 e.printStackTrace(); 67 } finally{ 68 ps = null; 69 } 70 } 71 if(conn!=null){ 72 try { 73 conn.close(); 74 } catch (SQLException e) { 75 e.printStackTrace(); 76 } finally{ 77 conn = null; 78 } 79 } 80 } 81
82 } 83 }
? 二、整合JDBC - 管理数据源 1.导入相关开发包 ? ? 2.将数据源交于Spring管理 ? ? 3.通过Spring获取数据源,获取连接,操作数据库 ? 三、Spring整合JDBC - JDBC 模板类 使用模板类能够极大的简化原有JDBC的编程过程。 a.在Spring中配置JDBC模板类 b.使用JDBC模板类实现增删改查 1 /**
2 * 使用jdbc模板类 实现 delete 3 */
4 @Test 5 public void test06(){ 6 JdbcTemplate jdbcTemplate = (JdbcTemplate) context.getBean("jdbcTemplate"); 7 int count = jdbcTemplate.update("delete from stu where id = ?",4); 8 System.out.println("执行成功,影响到的行数为"+count); 9 } 10
11 /**
12 * 使用jdbc模板类 实现 insert 13 */
14 @Test 15 public void test05(){ 16 JdbcTemplate jdbcTemplate = (JdbcTemplate) context.getBean("jdbcTemplate"); 17 int count = jdbcTemplate.update("insert into stu values (null,?,?)","fff","gz"); 18 System.out.println("执行成功,影响到的行数为"+count); 19 } 20
21
22 /**
23 * 使用jdbc模板类 实现 update 24 */
25 @Test 26 public void test04(){ 27 JdbcTemplate jdbcTemplate = (JdbcTemplate) context.getBean("jdbcTemplate"); 28 int count = jdbcTemplate.update("update stu set addr = ? where id = ?","sz",3); 29 System.out.println("执行成功,影响到的行数为"+count); 30 } 31
32 /**
33 * 使用jdbc模板类 实现 query 34 */
35 @Test 36 public void test03(){ 37 JdbcTemplate jdbcTemplate = (JdbcTemplate) context.getBean("jdbcTemplate"); 38 SqlRowSet rs = jdbcTemplate.queryForRowSet("select * from stu where id < ?",4); 39 while(rs.next()){ 40 String name = rs.getString("name"); 41 System.out.println(name); 42 } 43 } 44
45 /**
46 * 使用jdbc模板类 实现 query 47 */
48 @Test 49 public void test02(){ 50 JdbcTemplate jdbcTemplate = (JdbcTemplate) context.getBean("jdbcTemplate"); 51 List<Map<String,Object>> list = jdbcTemplate.queryForList("select * from stu where id < ?",4); 52 System.out.println(list); 53 }
? 3.使用RowMapper封装bean RowMapper接口定义了对象到列的映射关系,可以帮助我们在查询时自动封装bean。 1 package cn.tedu.spring.domain; 2
3 import java.sql.ResultSet; 4 import java.sql.SQLException; 5
6 import org.springframework.jdbc.core.RowMapper; 7
8 public class UserRowMapper implements RowMapper<User> { 9
10 @Override 11 public User mapRow(ResultSet rs,int rowNum) throws SQLException { 12 User user = new User(); 13 user.setId(rs.getInt(1)); 14 user.setName(rs.getString(2)); 15 user.setAddr(rs.getString(3)); 16 return user; 17 } 18
19 }
1 /** 2 * 使用jdbc模板类 使用RowMapper 3 */ 4 @Test 5 public void test08(){ 6 JdbcTemplate jdbcTemplate = (JdbcTemplate) context.getBean("jdbcTemplate"); 7 User user = jdbcTemplate.queryForObject("select * from stu where id = ?",new UserRowMapper(),2); 8 System.out.println(user); 9 } 10 /** 11 * 使用jdbc模板类 实现单条query 12 */ 13 @Test 14 public void test09(){ 15 JdbcTemplate jdbcTemplate = (JdbcTemplate) context.getBean("jdbcTemplate"); 16 List<User> list = jdbcTemplate.query("select * from stu",new UserRowMapper()); 17 System.out.println(list); 18 } 4.使用BeanPropertyRowMapper自动进行映射 BeanPropertyRowMapper内部可以指定类进行反射(内省)来获知类内部的属性信息,自动映射到表的列。使用它一定要注意,类的属性名要和对应表的列名必须对应的上,否则属性无法自动映射。BeanPropertyRowMapper底层通过反射(内省)来实现,相对于之前自己写的RowwMapper效率比较低。
1 /**
2 * 使用jdbc模板类 实现单条query 3 */
4 @Test 5 public void test10(){ 6 JdbcTemplate jdbcTemplate = (JdbcTemplate) context.getBean("jdbcTemplate"); 7 List<User> list = jdbcTemplate.query( 8 "select * from stu", 9 new BeanPropertyRowMapper(User.class)); 10 System.out.println(list); 11 }
? 四、Spring整合JDBC - 声明式事务处理 Spring中提供了内置的事务处理机制,称之为声明式事务处理。 1.创建项目,模拟MVC三层架构 2.在配置文件中导入相关约束 3.配置事务管理器 4.配置事务切面 ? ? 5.配置事务通知 ? ? 6.配置关系图 ? ??7.事务管理策略 异常的种类: java.lang.Throwable |-Exception |-RuntimeException |-其他Exception |-Error spring内置的事务策略,只在底层抛出的异常是运行时异常时,才会回滚,其他异常不回滚,留给用户手动处理。 也可以在配置中指定在原有规则的基础上,哪些异常额外回滚或不回滚: 配置成如下形式,可以实现任意异常都自动回滚: ? 8.注意:如果在一个业务逻辑中,需要有多步不同表的操作,此时应该在service层完成对不同表的操作,一次保证多步操作处于同一个事务中,切勿将业务代码在web层中调用Service来实现,虽然正常情况下也可以完成功能,但一旦出问题,很可能只有部分操作回滚,数据出现问题。 出现这种问题,不是事务管理机制的问题,而是开发者将业务逻辑错误的在web层中进行了实现,所以切记,web层只负责和用户交互和业务逻辑的调用,不进行任何业务逻辑的处理,任何业务逻辑都在service层中进行。 ? 五、声明式事务处理 - 注解方式 1.开启事务注解配置 2.在方法上通过注解开启事务 即可以标注在接口上,也可以标注在实现类上,理论上应该表在接口上,实现面向接口编程,但实际开发中为了方便也有人写在实现类上。 也可以在类上使用此接口,此时类中所有方法都会有事务 当在类上开启了事务后,可以此类的方法中使用如下方法,控制某个方法没有事务 通过注解控制事务时,和配置文件方式控制事务相同的是,默认只有运行时异常才会回滚,非运行时异常不回滚,此时可以通过如下注解选项额外配置 ,哪些异常需要回滚,哪些不需要。 ? 六、扩展案例 **扩展案例:缓存的使用 - 通过AOP实现为查询操作增加缓存机制
1 @Component 2 @Aspect 3 public class CatchAspect { 4 /** 5 * 使用Map实现的缓存 6 * 只会增加不会减少 7 * 没有超时时间,不管过了多久都使用历史缓存 8 * 没有存储优化 9 */ 10 private Map<Integer,User> map = new HashMap<Integer,User>(); 11 12 @Around("execution(* cn.tedu.spring.service.*.queryUser(..))") 13 public User around(ProceedingJoinPoint jp) throws Throwable{ 14 int i = (Integer) jp.getArgs()[0]; 15 if(map.containsKey(i)){ 16 System.out.println("使用缓存查询。。。"); 17 //有缓存 18 return map.get(i); 19 }else{ 20 System.out.println("使用数据库查询。。。"); 21 //没缓存 22 User user = (User) jp.proceed(); 23 map.put(user.getId(),user); 24 return user; 25 } 26 } 27 } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |