文章目录

  • ​​一. Spring的jdbcTemplate(模板)操作​​
  • ​​1. spring框架一站式框架​​
  • ​​2. Spring对不同的持久化层技术都进行支持(封装)​​
  • ​​3. jdbcTemplate是对jdbc进行封装(今天所学)​​
  • ​​(1). 增加​​
  • ​​1. 导入jdbcTemplate使用的jar包​​
  • ​​2. 创建对象,设置数据库信息​​
  • ​​3. 创建jdbcTemplate对象,设置数据源​​
  • ​​4. 调用jdbcTemplate对象里面的方法实现操作​​
  • ​​(2). 修改​​
  • ​​(3). 删除​​
  • ​​(4). 查询​​
  • ​​1. 使用jdbcTemplate实现查询操作和dbutil对比​​
  • ​​2. 查询具体实现:查询返回某一个值​​
  • ​​3. 查询具体实现:查询返回某个对象​​
  • ​​4. 查询具体实现:查询返回list集合​​
  • ​​二. spring的HibernateTemplate模板​​
  • ​​1. HibernateTemplate对hibernate框架进行封装​​
  • ​​2. HibernateTemplate常用的方法​​
  • ​​三. spring配置连接池​​
  • ​​1. 配置c3p0连接池​​
  • ​​(1). 导入c3p0相应的jar包​​
  • ​​(2). 创建spring配置文件,配置连接池​​
  • ​​2. dao使用jdbcTemplate操作​​
  • ​​(1). 创建service和dao,配置service和dao对象,在service注入dao对象​​
  • ​​(2). 创建jdbcTemplate对象,把模板对象注入到dao里面​​
  • ​​(3). 在jdbcTemplate对象里面注入dataSource​​
  • ​​3. 进行测试​​
  • ​​4. 详细的spring配置代码​​
  • ​​5. 注意事项​​
  • ​​(1). spring最详细的约束​​
  • ​​(2). spring c3p0 mysql_在Spring中使用c3p0连接MySql8.0+数据库的配置信息​​
  • ​​6. Spring 中配置 DBCP 连接池​​
  • ​​(1). 引入 dbcp 连接池的 jar包​​
  • ​​(2). 配置连接池​​
  • ​​四. spring事务管理​​
  • ​​1. 事务概念​​
  • ​​(1). 什么是事务​​
  • ​​(2). 事务特性​​
  • ​​(3). 如果不考虑隔离性引发安全性问题​​
  • ​​(4). 如果不考虑隔离性引发安全性问题​​
  • ​​2. Spring 进行事务管理一组 API​​
  • ​​(1). PlatformTransactionManager:平台事务管理器​​
  • ​​(2). TransactionDefinition:事务定义信息​​
  • ​​(3). TransactionStatus:事务的状态​​
  • ​​(4). Spring 的这组接口是如何进行事务管理:​​
  • ​​(5). PROPAGION_XXX :事务的传播行为​​
  • ​​3. spring进行事务配置(声明式)​​

一. Spring的jdbcTemplate(模板)操作

1. spring框架一站式框架

  • 针对javaee三层,每一层都有解决技术
  • 在dao层,使用 jdbcTemplate

2. Spring对不同的持久化层技术都进行支持(封装)

Spring_Day03_spring

3. jdbcTemplate是对jdbc进行封装(今天所学)

  • JDBCTemplate使用和dbutils使用很相似,都数据库进行crud操作

(1). 增加

1. 导入jdbcTemplate使用的jar包

Spring_Day03_Source_02


Spring_Day03_spring_03

2. 创建对象,设置数据库信息
3. 创建jdbcTemplate对象,设置数据源
4. 调用jdbcTemplate对象里面的方法实现操作

Spring_Day03_Source_04

package com.pudding.jdbc;

import org.junit.Test;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DriverManagerDataSource;

public class JdbcTemplateDemo1 {

//1. 添加操作
@Test
public void add() {
//创建对象,设置数据库信息
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
dataSource.setUrl("jdbc:mysql://localhost:3306/hibernate?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=UTC&rewriteBatchedStatements=true");
dataSource.setUsername("root");
dataSource.setPassword("root");


//创建jdbcTemplate对象,设置数据源
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);

//调用jdbcTemplate对象里面的方法实现操作
//创建sql语句
String sql = "insert into user values(?,?)";
int rows = jdbcTemplate.update(sql, "张三","123");
System.out.println(rows);
}

}

(2). 修改

同增加

package com.pudding.jdbc;

import org.junit.Test;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DriverManagerDataSource;

public class JdbcTemplateDemo1 {

//2. 修改操作
@Test
public void update() {
//创建对象,设置数据库信息
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
dataSource.setUrl("jdbc:mysql://localhost:3306/hibernate?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=UTC&rewriteBatchedStatements=true");
dataSource.setUsername("root");
dataSource.setPassword("root");

//创建jdbcTemplate对象,设置数据源
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);

//调用jdbcTemplate对象里面的方法实现操作
String sql = "update user set password=? where username=?";
int rows = jdbcTemplate.update(sql, "1314","张三");
System.out.println(rows);

}
}

(3). 删除

同增加

package com.pudding.jdbc;

import org.junit.Test;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DriverManagerDataSource;

public class JdbcTemplateDemo1 {

//3. 删除操作
@Test
public void delete() {
//创建对象,设置数据库信息
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
dataSource.setUrl("jdbc:mysql://localhost:3306/hibernate?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=UTC&rewriteBatchedStatements=true");
dataSource.setUsername("root");
dataSource.setPassword("root");

//创建jdbcTemplate对象,设置数据源
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);

//调用jdbcTemplate对象里面的方法实现操作
String sql = "delete from user where username=?";
int rows = jdbcTemplate.update(sql, "张三");
System.out.println(rows);

}

}

(4). 查询

同增加

1. 使用jdbcTemplate实现查询操作和dbutil对比

Spring_Day03_bc_05

2. 查询具体实现:查询返回某一个值

调用查询的方法

Spring_Day03_spring_06

  • 第一个参数是sql语句
  • 第二个参数是返回类型的class

Spring_Day03_spring_07

jdbc底层实现代码

Spring_Day03_sql_08

package com.pudding.jdbc;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import org.junit.Test;

public class JdbcTemplateDemo2 {

//2 jdbc底层实现代码
@Test
public void testJDBC() {
Connection conn = null;
PreparedStatement psmt = null;
ResultSet rs = null;
//加载驱动
try {
Class.forName("com.mysql.cj.jdbc.Driver");
//创建连接
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/hibernate?serverTimezone=GMT%2B8", "root", "root");
//编写sql语句
String sql = "select * from user where username=?";
//预编译sql
psmt = conn.prepareStatement(sql);
//设置参数值
psmt.setString(1, "张三");
//执行sql
rs = psmt.executeQuery();
//遍历结果集
while(rs.next()) {
//得到的返回结果值
String username = rs.getString("username");
String password = rs.getString("password");
//放到user对象里面去
User user = new User();
user.setUsername(username);
user.setPassword(password);

System.out.println(user);
}

} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
try {
rs.close();
psmt.close();
conn.close();

} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
}
package com.pudding.jdbc;

public class User {
private String username;
private String password;

public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public String toString() {
return "User [username=" + username + ", password=" + password + "]";
}
}
3. 查询具体实现:查询返回某个对象

Spring_Day03_bc_09

  • 第一个参数是sql语句
  • 第二个参数是RowMapper,是接口,类似于dbutils里面接口
  • 第三个参数是可变参数

Spring_Day03_sql_10

package com.pudding.jdbc;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import org.junit.Test;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.datasource.DriverManagerDataSource;

public class JdbcTemplateDemo2 {

//3. 查询返回某个对象
@Test
public void testObject() {
//创建对象,设置数据库信息
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
dataSource.setUrl("jdbc:mysql://localhost:3306/hibernate?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=UTC&rewriteBatchedStatements=true");
dataSource.setUsername("root");
dataSource.setPassword("root");

//创建jdbcTemplate对象,设置数据源
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);

//写sql语句,根据username查询
String sql = "select * from user where username=?";
//调用jdbcTemlate的方法实现
//第二个参数是接口RowMapper,需要自己写类实现接口,自己做数据库封装
User user = jdbcTemplate.queryForObject(sql, new MyRowMapper(), "Tom");
System.out.println(user);
}

class MyRowMapper implements RowMapper<User>{

@Override
public User mapRow(ResultSet rs, int num) throws SQLException {
//1. 从结果集把数据得到
String username = rs.getString("username");
String password = rs.getString("password");

//2.把得到数据封装到对象里面
User user = new User();
user.setUsername(username);
user.setPassword(password);

return user;
}

}
4. 查询具体实现:查询返回list集合

Spring_Day03_Source_11

  • 第一个参数是sql语句
  • 第二个参数是RowMapper接口,自己写类实现数据封装
  • 第三个参数是可变参数
package com.pudding.jdbc;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;

import org.junit.Test;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.datasource.DriverManagerDataSource;

public class JdbcTemplateDemo2 {

//4. 查询返回list集合
@Test
public void testList() {
//创建对象,设置数据库信息
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
dataSource.setUrl("jdbc:mysql://localhost:3306/hibernate?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=UTC&rewriteBatchedStatements=true");
dataSource.setUsername("root");
dataSource.setPassword("root");

//创建jdbcTemplate对象,设置数据源
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);

//写sql语句
String sql = "select * from user";
//调用jdbcTemplate的方法实现
List<User> list = jdbcTemplate.query(sql, new MyRowMapper());
System.out.println(list);
}

class MyRowMapper implements RowMapper<User>{

@Override
public User mapRow(ResultSet rs, int num) throws SQLException {
//1. 从结果集把数据得到
String username = rs.getString("username");
String password = rs.getString("password");

//2.把得到数据封装到对象里面
User user = new User();
user.setUsername(username);
user.setPassword(password);

return user;
}

}

二. spring的HibernateTemplate模板

1. HibernateTemplate对hibernate框架进行封装

  • 直接调用HibernateTemplate里面的方法实现功能

2. HibernateTemplate常用的方法

  • Serializable save(Object entity) :添加操作
  • Spring_Day03_Source_12

  • void update(Object entity) :修改操作
  • void delete(Object entity) :删除操作
  • T get(Class entityClass, Serializable id) :根据id查询
  • Spring_Day03_bc_13

  • T load(Class entityClass, Serializable id): 根据id查询
  • List find(String queryString, Object… values) :查询操作的方法
(1)第一个参数是 hql语句
(2)语句参数值

Spring_Day03_sql_14


Spring_Day03_sql_15


Spring_Day03_sql_16

三. spring配置连接池

1. 配置c3p0连接池

(1). 导入c3p0相应的jar包

Spring_Day03_Source_17

(2). 创建spring配置文件,配置连接池

最原始的c3p0连接池

ComboPooledDataSource dataSouse = new ComboPooledDataSource();
dataSouse.setDriverClass("com.mysql.cj.jdbc.Driver");
dataSouse.setJdbcUrl("jdbc:mysql://localhost:3306/hibernate?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=UTC&rewriteBatchedStatements=true");
dataSouse.setUser("root");
dataSouse.setPassword("root");

把代码的实现在配置文件中进行配置出来

Spring_Day03_sql_18

2. dao使用jdbcTemplate操作

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

Spring_Day03_spring_19


Spring_Day03_Source_20

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

Spring_Day03_Source_21


Spring_Day03_Source_22

(3). 在jdbcTemplate对象里面注入dataSource

Spring_Day03_Source_23


org.springframework.jdbc.core.JdbcTemplate类里面自带有datasource的set方法

Spring_Day03_Source_24

3. 进行测试

Spring_Day03_sql_25

4. 详细的spring配置代码

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">

<!-- 创建service和dao对象,在service注入dao对象 -->
<bean id="userService" class="com.pudding.c3p0.UserService">
<!-- 注入dao对象 -->
<property name="userDao" ref="userDao"></property>
</bean>

<bean id="userDao" class="com.pudding.c3p0.UserDao">
<property name="jdbcTemplate" ref="jdbcTemplate"></property>
</bean>

<!-- 创建jdbcTemplate对象 -->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<!-- 把dataSourse传递到模板对象里面 -->
<property name="dataSource" ref="dataSource"></property>
</bean>

<!-- 配置c3p0连接池 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<!-- 注入里面的属性值 -->
<property name="driverClass" value="com.mysql.cj.jdbc.Driver"></property>
<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/hibernate?useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true"></property>
<property name="user" value="root"></property>
<property name="password" value="root"></property>
</bean>
</beans>

5. 注意事项

(1). spring最详细的约束

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
</beans>

(2). spring c3p0 mysql_在Spring中使用c3p0连接MySql8.0+数据库的配置信息

需要注意的是url的值在8.0以上必须有useSSL、serverTimezone、allowPublicKeyRetrieval三个属性的设置,否则在某时刻必会出错。

<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="com.mysql.cj.jdbc.Driver"></property>
<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/数据库名?useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true"></property>
<property name="user" value="root"></property>
<property name="password" value="root"></property>
</bean>

6. Spring 中配置 DBCP 连接池

(1). 引入 dbcp 连接池的 jar包

Spring_Day03_bc_26

(2). 配置连接池

<!-- 配置 DBCP 连接池 -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql:///spring_day02"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</bean>

四. spring事务管理

1. 事务概念

(1). 什么是事务

  • 事务逻辑上的一组操作,组成这组操作的各个逻辑单元,要么一起成功,要么一起失败

(2). 事务特性

  • 原子性 :强调事务的不可分割.
  • 一致性 :事务的执行的前后数据的完整性保持一致.
  • 隔离性 :一个事务执行的过程中,不应该受到其他事务的干扰
  • 持久性 :事务一旦结束,数据就持久到数据库

(3). 如果不考虑隔离性引发安全性问题

  • 脏读 :一个事务读到了另一个事务的未提交的数据
  • 不可重复读 :一个事务读到了另一个事务已经提交的 update 的数据导致多次查询结果不一致.
  • 虚读 :一个事务读到了另一个事务已经提交的 insert 的数据导致多次查询结果

(4). 如果不考虑隔离性引发安全性问题

  • 未提交读 :脏读,不可重复读,虚读都有可能发生
  • 已提交读 :避免脏读。但是不可重复读和虚读有可能发生
  • 可重复读 :避免脏读和不可重复读.但是虚读有可能发生.
  • 串行化的 :避免以上所有读问题.

2. Spring 进行事务管理一组 API

  • spring针对不同的dao层框架提供不同的实现类

(1). PlatformTransactionManager:平台事务管理器

***** 真正管理事务的对象
org.springframework.jdbc.datasource.DataSourceTransactionManager 使用 SpringJDBC 或 iBatis 进行持久化数据时使用

org.springframework.orm.hibernate3.HibernateTransactionManager 使用Hibernate 版本进行持久化数据时使用

(2). TransactionDefinition:事务定义信息

  • 隔离级别
  • 传播行为
  • 超时信息
  • 是否只读

(3). TransactionStatus:事务的状态

  • 记录事务的状态

(4). Spring 的这组接口是如何进行事务管理:

  • 平台事务管理根据事务定义的信息进行事务的管理,事务管理的过程中产生一些状态,将这些状态记录到 TransactionStatus 里

(5). PROPAGION_XXX :事务的传播行为

  • 保证同一个事务中
PROPAGATION_REQUIRED 支持当前事务,如果不存在 就新建一个(默认)
PROPAGATION_SUPPORTS 支持当前事务,如果不存在,就不使用事务
PROPAGATION_MANDATORY 支持当前事务,如果不存在,抛出异常
  • 保证没有在同一个事务中
PROPAGATION_REQUIRES_NEW 如果有事务存在,挂起当前事务,创建一个新的事务
PROPAGATION_NOT_SUPPORTED 以非事务方式运行,如果有事务存在,挂起当前事务
PROPAGATION_NEVER 以非事务方式运行,如果有事务存在,抛出异常
PROPAGATION_NESTED 如果当前事务存在,则嵌套事务执行

3. spring进行事务配置(声明式)

  • 基于xml配置文件
  • 基于注解方式