一、Spring的jdbcTemplate操作#

(1)Spring是一站式框架,对于javaee三层,每一层都有解决技术。

  • web层:springMVC
  • service:spring的ioc
  • dao层:spring的jdbcTemplate

(2)Spring使用jdbcTemplate对dao层进行封装,jdbcTemplate使用和dbutils使用很相似,都数据库进行crud操作。

1.jdbcTemplate的crud操作##

1.1导入所需jar包###

IDEA会自动下载所需要的Spring包,但是数据库驱动需要自己导入。

1.2增加###

@Test
public void fun1() { //设置数据库信息
DriverManagerDataSource driverManagerDataSource = new DriverManagerDataSource();
driverManagerDataSource.setDriverClassName("com.mysql.jdbc.Driver");
driverManagerDataSource.setUrl("jdbc:mysql:///test");
driverManagerDataSource.setUsername("root");
driverManagerDataSource.setPassword("123"); //创建jdbcTemplate对象,设置数据源
JdbcTemplate jdbcTemplate = new JdbcTemplate(driverManagerDataSource);
String sql = "insert into stu values(?,?,?)";
Object[] params = {22, "bob", 40};
jdbcTemplate.update(sql, params); }

没有什么需要讲解的,只要创建jdbcTemplate对象,然后调用update方法即可实现。

1.3删除###

/*删除*/
@Test
public void fun2() {
DriverManagerDataSource driverManagerDataSource = new DriverManagerDataSource();
driverManagerDataSource.setDriverClassName("com.mysql.jdbc.Driver");
driverManagerDataSource.setUrl("jdbc:mysql:///test");
driverManagerDataSource.setUsername("root");
driverManagerDataSource.setPassword("123");
JdbcTemplate jdbcTemplate = new JdbcTemplate(driverManagerDataSource);
String sql = "delete from stu where id = ?";
jdbcTemplate.update(sql, 20); }

1.4修改###

/*修改*/
@Test
public void fun3() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUrl("jdbc:mysql:///test");
dataSource.setUsername("root");
dataSource.setPassword("123"); JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
String sql = "update stu set name = ? where id = ?";
jdbcTemplate.update(sql, "lele", 13);
}

1.5查询###

1.5.1查询返回某一值####

/*查询返回值*/
@Test
public void fun5() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUrl("jdbc:mysql:///test");
dataSource.setUsername("root");
dataSource.setPassword("123"); JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
String sql = "select count(*) from stu";
int count = jdbcTemplate.queryForObject(sql, Integer.class);
System.out.println(count);
}

1.5.2查询返回对象####

如果学习了原始的JDBC操作就可知道,使用原始的JDBC进行查询,我们使用preparedStatement进行查询,之后将结果放入resultSet结果集中,最后遍历结果集,最后使用getString()获取结果集中的值。

/*使用JDBC实现查询*/
@Test
public void Jdbc() {
Connection connection = null;
PreparedStatement preparedStatement = null;
ResultSet resultSet = null;
try {
Class.forName("com.mysql.jdbc.Driver");
connection = DriverManager.getConnection("jdbc:mysql:///test", "root", "123");
//String sql = "select * from stu where id = ?";
String sql1 = "select * from stu";
preparedStatement = connection.prepareStatement(sql1);
//preparedStatement.setString(1, "13");
resultSet = preparedStatement.executeQuery();
while (resultSet.next()) {
String id = resultSet.getString("id");
String name = resultSet.getString("name");
String age = resultSet.getString("age");
User user = new User();
user.setId(id);
user.setName(name);
user.setAge(age);
System.out.println(user);
} } catch (SQLException e) {
throw new RuntimeException(e);
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
} finally {
try {
resultSet.close();
preparedStatement.close();
connection.close();
} catch (SQLException e) {
throw new RuntimeException(e);
} }
}

在jdbcTemplate中使用如下方法实现

但是其中要传入一个rowMapper对象,这个参数需要自己写类实现接口,并且自己做数据封装。

class MyRowMapper implements RowMapper<User> {
@Override
public User mapRow(ResultSet resultSet, int i) throws SQLException {
String id = resultSet.getString("id");
String name = resultSet.getString("name");
String age = resultSet.getString("age");
User user = new User();
user.setId(id);
user.setName(name);
user.setAge(age);
return user;
}
}
/*查询某一对象*/
@Test
public void fun6() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUrl("jdbc:mysql:///test");
dataSource.setUsername("root");
dataSource.setPassword("123");
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
String sql = "select * from stu where id = ?";
User user = jdbcTemplate.queryForObject(sql, new MyRowMapper(), 13);
System.out.println(user);
}

1.5.3查询List集合####

查询集合不再使用queryForObject(),而是使用query(),这里也需要传入rowMapper对象。

    JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
String sql = "select * from stu";
List<User> list = jdbcTemplate.query(sql, new MyRowMapper());
System.out.println(list);

二、Spring配置连接池和dao使用jdbcTemplate#

1.Spring配置c3p0连接池##

1.导入c3p0和依赖jar包

2.在配置文件中进行配置

<bean id="datasource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="com.mysql.jdbc.Driver"></property>
<property name="jdbcUrl" value="jdbc:mysql:///test"></property>
<property name="user" value="root"></property>
<property name="password" value="123"></property>
</bean>

2.dao使用jdbcTemplate##

1.创建service和dao,配置service和dao对象,在service注入dao对象

<!--创建service和dao对象-->
<bean id="userDao" class="test.spring.c3p0.UserDao">
<property name="jdbcTemplate" ref="jdbcTemplate"></property>
</bean>
<bean id="userService" class="test.spring.c3p0.UserService">
<!--将dao注入service-->
<property name="userDao" ref="userDao"></property>
</bean>

2.创建jdbcTemplate对象,把模板对象注入到dao里面

spring-config.xml

<!--创建JdbcTemplate对象-->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<!--传入datasource-->
<property name="dataSource" ref="datasource"></property>
</bean>

userDao.java

public class UserDao {
private JdbcTemplate jdbcTemplate; public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
public void add() {
String sql = "insert into stu values(?,?,?)";
Object[] values = {22, "kl", 45};
jdbcTemplate.update(sql , values);
System.out.println("add success...");
}
}

userService.java

    public class UserService {
private UserDao userDao; public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
public void add()
{
System.out.println("userService success..");
userDao.add();
}
}

三、Spring事务管理#

1.spring事务管理两种方式##

第一种 编程式事务管理(不用)

第二种 声明式事务管理

  • 基于xml配置文件实现
  • 基于注解实现

2.搭建转账环境##

1.创建数据库表,添加数据

2.创建service和dao类,完成注入关系

<!--创建OrderService和OrderDao对象-->
<bean id="orderDao" class="test.spring.transaction.anno.OrderDao">
<property name="jdbcTemplate" ref="jdbcTemplate"></property>
</bean>
<bean id="orderService" class="test.spring.transaction.anno.OrderService">
<property name="orderDao" ref="orderDao"></property>
</bean> <!--创建JdbcTemplate对象-->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<!--传入datasource-->
<property name="dataSource" ref="datasource"></property>
</bean>

3.执行转账操作,zhangsan-100,,李四+100.

    public class OrderService {
private OrderDao orderDao; public void setOrderDao(OrderDao orderDao) {
this.orderDao = orderDao;
} public void account() {
orderDao.lessMoney();
orderDao.addMoney();
}
}
public class OrderDao {
private JdbcTemplate jdbcTemplate; public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
} public void lessMoney() {
String sql = "update account set balance=balance-? where name=?";
jdbcTemplate.update(sql, 100, "zhangsan");
} public void addMoney() {
String sql = "update account set balance=balance+? where name=?";
jdbcTemplate.update(sql, 100, "lisi");
}
}

成功运行,并且数据库中也进行了更新。

但是此时,如果程序在运行过程中出现异常,比如我们将在account()中加入如下语句。

public void account() {
orderDao.lessMoney();
int i = 1/0;
orderDao.addMoney();
}

这就会抛出一个非常常见的异常

这时查询数据库,发现zhangsan少了100,但是lisi并没有增加,这100元就这样没了。

所以我们需要在这里引入事务控制。

声明式事务管理(xml配置)##

首先配置事务管理器

<!--配置事务管理器-->
<bean id="transactionManager2" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="datasource"></property>
</bean>

这里使用aop的思想进行事务操作

<!--配置事务增强-->
<tx:advice id="txadvice" transaction-manager="transactionManager">
<!--事务操作-->
<tx:attributes>
<tx:method name="account*" propagation="REQUIRED"/>
</tx:attributes>
</tx:advice>

最后配置切面

<!--配置切面-->
<aop:config>
<!--配置切入点-->
<aop:pointcut id="pointcut2"
expression="execution(* test.spring.transaction.xml.OrderService.account(..))"></aop:pointcut>
<!--配置切面-->
<aop:advisor advice-ref="txadvice" pointcut-ref="pointcut2"></aop:advisor>
</aop:config>

这样再次运行程序,虽然出现异常,但是zhangsan和lisi的余额并没有改变。

声明式事务管理(注解方式)##

使用注解方式进行事务管理,只需要在配置完事务管理器后开启事务注解即可实现,不再通过配置切面完成。

<!--开启事务注解-->
<tx:annotation-driven transaction-manager="transactionManager2"></tx:annotation-driven>

之后,只要在service中声明如下注解即可实现

本节的Demo已上传github,如有需要请下载###

https://github.com/LELE-QAQ/TestSpring_2

Spring基础入门(三)的更多相关文章

  1. Swift语法基础入门三(函数, 闭包)

    Swift语法基础入门三(函数, 闭包) 函数: 函数是用来完成特定任务的独立的代码块.你给一个函数起一个合适的名字,用来标识函数做什么,并且当函数需要执行的时候,这个名字会被用于“调用”函数 格式: ...

  2. C#基础入门 三

    C#基础入门 三 类 类使用class关键字进行声明,前面加一个访问修饰符,public class car{} 访问修饰符:修师傅可以用来修饰类和类成员等,控制它们的可见度 修饰符关键字分别为:pu ...

  3. Spring基础入门

    一.Spring了解 Spring:程序员们的春天 Spring主要技术是IOC.AOP两个大概念 它是轻量级的,每个jar包就1M ~ 3M 左右,所以速度快 面向接口编程:降低了耦合度 面向切面编 ...

  4. Spring基础入门(一)

    一.Spring概念 1.什么是Spring   Spring是一个开源框架,它由Rod Johnson创建.它是为了解决企业应用开发的复杂性而创建的.Spring使用基本的JavaBean来完成以前 ...

  5. Spring基础学习(三)—详解Bean(下)

    一.Bean的生命周期 1.概述      Spring IOC容器可以管理Bean的生命周期,Spring 允许在Bean的生命周期的特定点执行定制的任务.      Spring IOC容器对Be ...

  6. Spring Boot入门(三):使用Scheduled注解实现定时任务

    在程序开发的过程中,经常会使用定时任务来实现一些功能,比如: 系统依赖于外部系统的非核心数据,可以定时同步 系统内部一些非核心数据的统计计算,可以定时计算 系统内部的一些接口,需要间隔几分钟或者几秒执 ...

  7. Spring 基础入门(一)

    本文代码部分来自于<spring in action>,本文讲的是使用!! Spring 是为了解决什么 一个框架的存在是为了解决某个问题的,那么Spring这个框架是为了解决什么问题呢? ...

  8. <Spring Cloud>入门三 Ribbon

    1.Ribbon 客户端软负载均衡组件 1.1配置 搭建了三个消费者供客户端调用: 1.修改yml eureka: client: service-url: defaultZone: http://e ...

  9. Spring boot 入门三:SpringBoot用JdbcTemplates访问Mysql 实现增删改查

    建表脚本 -- create table `account`DROP TABLE `account` IF EXISTSCREATE TABLE `account` ( `id` int(11) NO ...

随机推荐

  1. time模块、datetime模块讲解

    time模块清楚三种格式的时间相互转换 import time# 时间分为三种格式#1.时间戳start= time.time()time.sleep(3)stop= time.time()print ...

  2. GatewayWorker+Laravel demo

    GatewayWorker 结合 Laravel 使用的简单案例,重点是在Laravel中使用GatewayClient发送消息 主要流程:GatewayWorker主要负责推送消息给客户端但不接受客 ...

  3. linux命令规范

    Linux文件后缀: 系统文件:*.conf    *.rpm 系统与脚本:*.c  *.php 存档文件和压缩文件:*.tar   *.gz ……… Linux文件命名规则: 1.大小写敏感 2.除 ...

  4. VS2017 移动开发(Android and IOS) 序

    序 公司原因,要求用C#开发移动端app,老板觉得用现在会的C#做会比较快... 从零开始,折腾一个多星期,重装系统三遍(强迫症),其它各种折腾,终于手机运行上了第一个APP,看看就好... 不得不吐 ...

  5. Farseer.net轻量级ORM开源框架 V1.0 开发目标

    本篇主要给大家说明下在V1.0中,计划开发的任务的状态.按照国际惯例.上大表格 开发计划状态 编号 模块 状态 说明 1  分离Utils.Extend.UI  √  在V0.2版本中,是集成在一个项 ...

  6. 用Python控制摄像头拍照并发邮件

    概述前言 工具 思路 安装及导入包 设置参数 实现拍照 构造邮件内容 发送邮件 判断网络连接 开机自启 后记 o1 前言为什么会有写这个程序的想法呢? 最初的想法是写一个可以用电脑前置摄像头拍照的程序 ...

  7. Jmeter重要组件介绍(一)

    一.常用的取样器 二.常用的逻辑控制器 三.前置处理器 四.后置处理器 五.断言 六.定时器 七.配置元件 八.监听器

  8. viewport 640宽的做法 针对iphone和安卓单独设置

    <!DOCTYPE html> <html lang="ch"> <head> <meta charset="utf-8&quo ...

  9. com口操作excel

    _Application app;       //Excel应用程序接口 Workbooks books;        //工作薄集合 _Workbook book;     //工作薄 Work ...

  10. vue之Render函数

    (1)什么是Render函数 先来看一个场景,在博客网中,一般有一级标题.二级标题.三级标题...,为了方便分享url,它们都做成了锚点,点击后,会将内容加载网址后面,以#分隔. 例如‘特性’是一个& ...