基于aspectj的注解aop
- 使用注解方式实现aop操作
第一步 创建对象
<!-- 创建对象 -->
<bean id="book" class="cn.itcast.aop.Book"></bean>
<bean id="myBook" class="cn.itcast.aop.MyBook"></bean>
第二步 在spring核心配置文件中,开启aop操作
<!-- 开启aop操作 -->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
第三步 在增强类上面使用注解完成aop操作
@Aspect
public class MyBook {
//在方法上面使用注解完成增强配置
@Before("execution(* cn.itcast.aop.Book.*(..))")
public void before() {
System.out.println("before......");
}
}
Spring的jdbcTemplate操作
- spring框架一站式框架
(1)针对javaee三层,每一层都有解决技术
(2)在dao层,使用 jdbcTemplate - spring对不同的持久化层技术都进行封装
(1)jdbcTemplate对jdbc进行封装 - jdbcTemplate使用和dbutils使用很相似,都数据库进行crud操作
-
增加
- 1 导入jdbcTemplate使用的jar包
不能忘记数据库驱动(导入数据库驱动jar包) - 2 创建对象,设置数据库信息
- 3 创建jdbcTemplate对象,设置数据源
- 4 调用jdbcTemplate对象里面的方法实现操作
- 1 导入jdbcTemplate使用的jar包
-
修改
-
删除
-
查询
- 使用jdbcTemplate实现查询操作
- 查询具体实现
第一个 查询返回某一个值
queryForObject(String sql, Class requiredType):T-Jdbc
(1)第一个参数是sql语句
(2)第二个参数 返回类型的class
Jdbc实现
- 使用jdbcTemplate实现查询操作
//2 jdbc实现代码
@Test
public void testJDBC() {
Connection conn= null;
PreparedStatement psmt = null;
ResultSet rs = null;
//加载驱动
try{
Class.forName("com.mysql.jdbc.Driver");
//创建连接
conn = (Connection) DriverManager.getConnection("jdbc:mysql:///spring_day03", "root", "123456");
//编写SQL语句
String sql = "select * from user where username=?";
//预编译sql
psmt = (PreparedStatement) conn.prepareStatement(sql);
//设置参数的值
psmt.setString(1, "lucy");
//执行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 (Exception e) {
// TODO: handle exception
e.printStackTrace();
}finally {
try {
rs.close();
psmt.close();
conn.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
第二个 查询返回对象
- queryForObject(String sql, RowMapper rowMaper,Object… args):T-Jdbc
- 第一个参数是sql语句
- 第二个参数是 RowMapper,是接口,类似于dbutils里面接口
- 第三个参数是 可变参数
// 3 查询返回对象
@Test
public void testObject() {
// 创建对象,设置数据库信息
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUrl("jdbc:mysql:///spring_day03");
dataSource.setUsername("root");
dataSource.setPassword("123456");
// 创建jdbcTemplate对象,设置数据源
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
// 写sql语句,根据username查询
String sql = "select * from user where username=?";
//调用jdbctemplate的方法实现
//第二个参数是接口 RowMapper,需要自己写类实现接口,自己做数据封装。
User user = jdbcTemplate.queryForObject(sql, new MyRowMapper(), "Brown");
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;
}
}
第三个 查询返回list集合
queryForObject(String sql, RowMapper rowMaper,Object… args):List-Jdbc
(1)sql语句
(2)RowMapper接口,自己写类实现数据封装
(3)可变参数
// 4 查询返回对象集合
@Test
public void testList() {
// 创建对象,设置数据库信息
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUrl("jdbc:mysql:///spring_day03");
dataSource.setUsername("root");
dataSource.setPassword("123456");
// 创建jdbcTemplate对象,设置数据源
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
// 写sql语句
String sql = "select * from user";
//调用jdbctemplate的方法实现
//第二个参数是接口 RowMapper,需要自己写类实现接口,自己做数据封装。
List<User> list = jdbcTemplate.query(sql, new MyRowMapper());
System.out.println(list);
}
}
Spring配置连接池和dao使用jdbcTemplate
- spring配置c3p0连接池
第一步 导入jar包
第二步 创建spring配置文件,配置连接池
ComboPooledDataSource dataSource = new ComboPooledDataSource();
dataSource.setDriverClass("com.mysql.jdbc.Driver");
dataSource.setJdbcUrl("jdbc:mysql:///spring_day03");
dataSource.setUser("root");
dataSource.setPassword("123456");
(1) 把代码在配置文件中进行配置
<!-- 配置c3p0连接池 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<!-- 注入属性值 -->
<property name="driverClass" value="com.mysql.jdbc.Driver"></property>
<property name="jdbcUrl" value="jdbc:mysql:///spring_day03"></property>
<property name="user" value="root"></property>
<property name="password" value="123456"></property>
</bean>
- dao使用jdbcTemplate
(1)创建service和dao,配置service和dao对象,在service注入dao对象
<!-- 创建service和dao对象,在service注入dao对象 -->
<bean id="userService" class="cn.itcast.c3p0.UserService">
<!-- 注入dao对象 -->
<property name="userDao" ref="userDao"></property>
</bean>
<bean id="userDao" class="cn.itcast.c3p0.UserDao">
(2)创建jdbcTemplate对象,把模板对象注入到dao里面
//得到jdbcTemplate对象
private JdbcTemplate jdbcTemplate;
public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
(3)在jdbcTemplate对象里面注入dataSource
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<!-- 把dataSource传递到模板对象里面 -->
<property name="dataSource" ref="dataSource"></property>
</bean>
Spring的事务管理
事务概念
- 什么事务
一组操作,要么都成功,有一个失败都失败。 - 事务特性
原子性、一致性、隔离性、持久性 - 不考虑隔离性产生读问题
脏独、不可重复读、虚读、幻读 - 解决读问题
(1)设置隔离级别
Spring事务管理api
- spring事务管理两种方式
第一种 编程式事务管理(不用)
第二种 声明式事务管理
(1)基于xml配置文件实现
(2)基于注解实现 - spring事务管理的api介绍
(1)spring针对不同的dao层框架,提供接口不同的实现类
(2)首先 配置事务管理器
搭建转账环境
- 创建数据库表,添加数据
- 创建service和dao类,完成注入关系
<bean id="ordersService" class="cn.itcast.service.OrdersService">
<property name="ordersDao" ref="ordersDao"></property>
</bean>
<bean id="ordersDao" class="cn.itcast.dao.OrdersDao">
<property name="jdbcTemplate" ref="jdbcTemplate"></property>
</bean>
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"></property>
</bean>
(1)service层又叫业务逻辑层
(2)dao层,单纯对数据库操作层,在dao层不添加业务
(3)需求:小王 转账 1000 给 小马
- 小王少1000
- 小马多1000
/*
* 做对数据库操作的方法,不写业务操作
*/
//小王少钱的方法
public void lessMone() {
String sql = "update account set salary=salary-? where username=?";
jdbcTemplate.update(sql, 1000,"小王");
}
//小马多钱的方法
public void moreMoney() {
String sql = "update account set salary=salary+? where username=?";
jdbcTemplate.update(sql, 1000,"小马");
}
//调用dao方法
//业务逻辑层,写转账业务
public void accountMOney() {
//小王少1000
ordersDao.lessMone();
//小马多1000
ordersDao.moreMoney();
}
- 产生问题:
(1)如果小王少了1000之后,出现异常,小马不会多1000,钱丢失了 - 解决:
(1)添加事务解决,出现异常进行回滚操作
声明式事务管理(xml配置)
- 配置文件方式使用aop思想配置
- 第一步 配置事务管理器
<!-- 第一步 配置事务管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!-- 注入dataSource -->
<property name="dataSource" ref="dataSource"></property>
</bean>
- 第二步 配置事务增强
<!-- 第二步配置上事务增强 -->
<tx:advice id="txadvice" transaction-manager="transactionManager">
<!-- 做事务操作 -->
<tx:attributes>
<!-- 设置进行事务操作的方法匹配规则 -->
<tx:method name="account*" />
</tx:attributes>
</tx:advice>
- 第三步 配置切面
<!-- 第三步 配置切面 -->
<aop:config>
<!-- 切入点 -->
<aop:pointcut expression="execution(* cn.itcast.service.OrdersService.*(..))" id="pointcut1"/>
<!-- 切面 -->
<aop:advisor advice-ref="txadvice" pointcut-ref="pointcut1"/>
</aop:config>
声明式事务管理(注解)
- 第一步 配置事务管理器
<!-- 第一步 配置事务管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!-- 注入dataSource -->
<property name="dataSource" ref="dataSource"></property>
</bean>
- 第二步 配置事务注解
<!-- 第二步开启事务注解 -->
<tx:annotation-driven transaction-manager="transactionManager"/>
- 第三步 在要使用事务的方法所在类上面添加注解
@Transactional
public class OrdersService {