java spring jdbc_JAVA-Spring 整合 JDBC

一、回顾JDBC

1.java操作关系型数据的API。

导入相关数据库的驱动包后可以通过JDBC提供的接口来操作数据库。

2.实现JDBC的六个步骤

注册数据库驱动

获取数据库连接

获取传输器对象

传输sql执行获取结果集对象

遍历结果集获取信息

关闭资源

1 packagecn.tedu.jdbc;2

3 importjava.sql.Connection;4 importjava.sql.DriverManager;5 importjava.sql.PreparedStatement;6 importjava.sql.ResultSet;7 importjava.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'),(null,'ccc','gz'),(null,'ddd','sh'),(null,'eee','bj');15 */

16 public classDemo01 {17 public static voidmain(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 packagecn.tedu.jdbc;2

3 importjava.beans.PropertyVetoException;4 importjava.sql.Connection;5 importjava.sql.PreparedStatement;6 importjava.sql.ResultSet;7 importjava.sql.SQLException;8

9 importcom.mchange.v2.c3p0.ComboPooledDataSource;10

11

12 /**

13 create database springdb;14 use springdb;15 create table stu(id int primary key auto_increment,name varchar(255),addr varchar(255));16 insert into stu values (null,'aaa','bj'),(null,'bbb','sh'),(null,'ccc','gz'),(null,'ddd','sh'),(null,'eee','bj');17 */

18 public classDemo02 {19 private static ComboPooledDataSource dataSource = newComboPooledDataSource();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 newRuntimeException(e);29 }30 }31

32 public static voidmain(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.导入相关开发包

ccd13a4e633d8009c1bfb9e5d6ca5a2c.png

2.将数据源交于Spring管理

4f2973a1dc2bacf61acf056b0315d4a7.png

3.通过Spring获取数据源,获取连接,操作数据库

ab787b9051abeacd33af44656ff0c09e.png

三、Spring整合JDBC - JDBC 模板类

使用模板类能够极大的简化原有JDBC的编程过程。

a.在Spring中配置JDBC模板类

fd162c65cf2526783e776aab020a5e42.png

b.使用JDBC模板类实现增删改查

1 /**

2 * 使用jdbc模板类 实现 delete3 */

4 @Test5 public voidtest06(){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模板类 实现 insert13 */

14 @Test15 public voidtest05(){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模板类 实现 update24 */

25 @Test26 public voidtest04(){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模板类 实现 query34 */

35 @Test36 public voidtest03(){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模板类 实现 query47 */

48 @Test49 public voidtest02(){50 JdbcTemplate jdbcTemplate = (JdbcTemplate) context.getBean("jdbcTemplate");51 List> list = jdbcTemplate.queryForList("select * from stu where id < ?",4);52 System.out.println(list);53 }

3.使用RowMapper封装bean

RowMapper接口定义了对象到列的映射关系,可以帮助我们在查询时自动封装bean。

1 packagecn.tedu.spring.domain;2

3 importjava.sql.ResultSet;4 importjava.sql.SQLException;5

6 importorg.springframework.jdbc.core.RowMapper;7

8 public class UserRowMapper implements RowMapper{9

10 @Override11 public User mapRow(ResultSet rs, int rowNum) throwsSQLException {12 User user = newUser();13 user.setId(rs.getInt(1));14 user.setName(rs.getString(2));15 user.setAddr(rs.getString(3));16 returnuser;17 }18

19 }

1 /** 2 * 使用jdbc模板类 使用RowMapper3 */ 4 @Test5 public voidtest08(){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模板类 实现单条query12 */ 13 @Test14 public voidtest09(){15 JdbcTemplate jdbcTemplate = (JdbcTemplate) context.getBean("jdbcTemplate");16 List list = jdbcTemplate.query("select * from stu", newUserRowMapper());17 System.out.println(list);18 }

4.使用BeanPropertyRowMapper自动进行映射

BeanPropertyRowMapper内部可以指定类进行反射(内省)来获知类内部的属性信息,自动映射到表的列。使用它一定要注意,类的属性名要和对应表的列名必须对应的上,否则属性无法自动映射。BeanPropertyRowMapper底层通过反射(内省)来实现,相对于之前自己写的RowwMapper效率比较低。

1 /**

2 * 使用jdbc模板类 实现单条query3 */

4 @Test5 public voidtest10(){6 JdbcTemplate jdbcTemplate = (JdbcTemplate) context.getBean("jdbcTemplate");7 List list =jdbcTemplate.query(8 "select * from stu",9 new BeanPropertyRowMapper(User.class));10 System.out.println(list);11 }

四、Spring整合JDBC - 声明式事务处理

Spring中提供了内置的事务处理机制,称之为声明式事务处理。

1.创建项目,模拟MVC三层架构

2.在配置文件中导入相关约束

aa2cce5b75fa794fbe7e5082263b9367.png

3.配置事务管理器

3b36033714f2923653cdb7c952f380b1.png

4.配置事务切面

ed4b2ce24b0d6e1b142f9a985e693dd5.png

5.配置事务通知

b5ace5fdebf914db20fcef8d718712af.png

6.配置关系图

47bf3342a5ccf890e21efd4ec5776b68.png

7.事务管理策略

异常的种类:

java.lang.Throwable

|-Exception

|-RuntimeException

|-其他Exception

|-Error

spring内置的事务策略,只在底层抛出的异常是运行时异常时,才会回滚,其他异常不回滚,留给用户手动处理。

也可以在配置中指定在原有规则的基础上,哪些异常额外回滚或不回滚:

741c8bbbbd5606fda06b1f3bfb151f77.png

配置成如下形式,可以实现任意异常都自动回滚:

f51f4f94c18a220f8fdf3edf8b18f832.png

8.注意:如果在一个业务逻辑中,需要有多步不同表的操作,此时应该在service层完成对不同表的操作,一次保证多步操作处于同一个事务中,切勿将业务代码在web层中调用Service来实现,虽然正常情况下也可以完成功能,但一旦出问题,很可能只有部分操作回滚,数据出现问题。

出现这种问题,不是事务管理机制的问题,而是开发者将业务逻辑错误的在web层中进行了实现,所以切记,web层只负责和用户交互和业务逻辑的调用,不进行任何业务逻辑的处理,任何业务逻辑都在service层中进行。

五、声明式事务处理 - 注解方式

1.开启事务注解配置

c8f37b06a3533d8f2111531485892798.png

2.在方法上通过注解开启事务

即可以标注在接口上,也可以标注在实现类上,理论上应该表在接口上,实现面向接口编程,但实际开发中为了方便也有人写在实现类上。

7b677f404a03931065365ee72661b7ee.png

也可以在类上使用此接口,此时类中所有方法都会有事务

50b46ea8ca2023cb51833b53d928957f.png

当在类上开启了事务后,可以此类的方法中使用如下方法,控制某个方法没有事务

7c8d117199307b37b06d2bd49a6e5eff.png

通过注解控制事务时,和配置文件方式控制事务相同的是,默认只有运行时异常才会回滚,非运行时异常不回滚,此时可以通过如下注解选项额外配置 ,哪些异常需要回滚,哪些不需要。

a0eeeed766b678aaa4c9c6adcd511644.png

六、扩展案例

**扩展案例:缓存的使用 - 通过AOP实现为查询操作增加缓存机制

1 @Component2 @Aspect3 public classCatchAspect {4 /**

5 * 使用Map实现的缓存6 * 只会增加不会减少7 * 没有超时时间,不管过了多久都使用历史缓存8 * 没有存储优化9 */

10 private Map map = new HashMap();11

12 @Around("execution(* cn.tedu.spring.service.*.queryUser(..))")13 public User around(ProceedingJoinPoint jp) throwsThrowable{14 int i = (Integer) jp.getArgs()[0];15 if(map.containsKey(i)){16 System.out.println("使用缓存查询。。。");17 //有缓存

18 returnmap.get(i);19 }else{20 System.out.println("使用数据库查询。。。");21 //没缓存

22 User user =(User) jp.proceed();23 map.put(user.getId(), user);24 returnuser;25 }26 }27 }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值