文章目录
一. Spring的jdbcTemplate(模板)操作
1. spring框架一站式框架
- 针对javaee三层,每一层都有解决技术
- 在dao层,使用 jdbcTemplate
2. Spring对不同的持久化层技术都进行支持(封装)
3. jdbcTemplate是对jdbc进行封装(今天所学)
- JDBCTemplate使用和dbutils使用很相似,都数据库进行crud操作
(1). 增加
1. 导入jdbcTemplate使用的jar包
2. 创建对象,设置数据库信息
3. 创建jdbcTemplate对象,设置数据源
4. 调用jdbcTemplate对象里面的方法实现操作
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对比
2. 查询具体实现:查询返回某一个值
调用查询的方法
- 第一个参数是sql语句
- 第二个参数是返回类型的class
jdbc底层实现代码
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. 查询具体实现:查询返回某个对象
- 第一个参数是sql语句
- 第二个参数是RowMapper,是接口,类似于dbutils里面接口
- 第三个参数是可变参数
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集合
- 第一个参数是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) :添加操作
-
void update(Object entity) :修改操作
-
void delete(Object entity) :删除操作
-
T get(Class entityClass, Serializable id) :根据id查询
-
T load(Class entityClass, Serializable id): 根据id查询
-
List find(String queryString, Object… values) :查询操作的方法
(1)第一个参数是 hql语句 (2)语句参数值
三. spring配置连接池
1. 配置c3p0连接池
(1). 导入c3p0相应的jar包
(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");
把代码的实现在配置文件中进行配置出来
2. dao使用jdbcTemplate操作
(1). 创建service和dao,配置service和dao对象,在service注入dao对象
(2). 创建jdbcTemplate对象,把模板对象注入到dao里面
(3). 在jdbcTemplate对象里面注入dataSource
org.springframework.jdbc.core.JdbcTemplate类里面自带有datasource的set方法
3. 进行测试
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包
(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配置文件
- 基于注解方式