Spring学习笔记④
Spring使用注解方式进行AOP
方式:在XML文件里面进行配置,不需要指定切入点和切面,只需要开启AspectJ自动代理,使用注解将自动为我们指定切入点和切面
<!-- 第二步 开启AOP操作 / AspectJ自动代理 --> <aop:aspectj-autoproxy></aop:aspectj-autoproxy> <!-- 第一步 配置增强类和被增强类的对象 --> <bean id="book" class="tech.youngs.aop.Book"></bean> <bean id="myBook" class="tech.youngs.aop.MyBook"></bean>
在增强类的类名前使用@Aspect注解
在增强(方法)前根据是前置增强还是环绕增强使用不同的注解:以前置增强为例:
使用@before(value = "execution(* tech.youngs.aop.Book.*(..))")即可
Spring jdbcTemplate使用
步骤
① 导入jar包 spring-jdbc和spring-tx
②创建对象,设置数据库信息
③创建jdbcTemplate对象 设置数据源
④使用jdbcTemplate对象进行CURD操作
//1.设置数据库信息 DriverManagerDataSource dataSource = new DriverManagerDataSource(); dataSource.setDriverClassName("com.mysql.jdbc.Driver"); dataSource.setUrl("jdbc:mysql:///spring_demo"); dataSource.setUsername("root"); dataSource.setPassword("996225"); //2.创建jdbcTemplate对象 JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource); //3.调用jdbcTemplate对象方法进行操作 String sql = "INSERT INTO user VALUES(?,?)"; int row = jdbcTemplate.update(sql, "zhangsan","12345"); System.out.println("成功添加"+row+"条记录");
增加、删除、修改都是用jdbcTemplate.update(String sql, args);方法
@param sql 和PreparedStatement的sql语句写法一样 参数用?来写
@param args 是可变参数 按照问号的顺序来填充问号的内容
查询操作
① 返回一个值
② 返回一个实体对象
③ 返回一个list
//3.调用jdbcTemplate对象方法进行操作 String sql = "select * from user"; /* * @param sql sql语句 * @param rowMapper * */ List<User> user = jdbcTemplate.query(sql, new UserDao()); /* * @param sql sql语句 * @param RowMapper rowMapper 是一个接口,需要自己写一个类实现这个接口 * 有两种写法:① 使用匿名内部类 * ② 内部类 ③ 新建一个外部类 * @param args 可变参数 SQL语句传值 * */ User user = jdbcTemplate.queryForObject(sql, new UserDao(), "zhangsan"); user.toString(); /* * queryForObject * @param sql 查询语句 * @param class 返回对象的class * */ String count = jdbcTemplate.queryForObject(sql, String.class); System.out.println(count); int row = jdbcTemplate.update(sql, "zhangsan","12345"); System.out.println("成功添加"+row+"条记录");
下面是RowMapping的实现类
class UserDao implements RowMapper<User> { @Override public User mapRow(ResultSet rs, int num) throws SQLException { // 1 拿到rs String username = rs.getString("username"); String password = rs.getString("password"); // 2 将rs封装到对象里 User user = new User(); user.setUsername(username); user.setPassword(password); return user; } }
Spring使用c3p0数据库连接池
原始的数据库连接池设置方式:
//设置c3p0连接池 ComboPooledDataSource dataSource = new ComboPooledDataSource(); dataSource.setDriverClass("com.mysql.jdbc.Driver"); dataSource.setJdbcUrl("jdbc:mysql:///spring_demo"); dataSource.setUser("root"); dataSource.setPassword("996225");
Spring配置c3p0数据库连接池只需要在xml文件中对ComboPoolDataSource对象进行管理,并注入相关属性:
<!-- 配置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_demo"></property> <property name="user" value="root"></property> <property name="password" value="996225"></property> </bean>
然后新建两个类 Dao和Service,Dao直接对数据库操作,所以向这个类注入jdbcTemplate对象,所以定义属性,并生成setter方法,并在配置文件中配置注入。
由于jdbcTemplate需要DataSource才能实例化,所以还需要向jdbcTemplate注入Datasource属性。
<!-- 配置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_demo"></property> <property name="user" value="root"></property> <property name="password" value="996225"></property> </bean> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> <!-- 把数据库连接池注入到jdbcTemplate的属性里面 jdbcTemplate得到DataSource才可以实例化 --> <property name="dataSource" ref="dataSource"></property> </bean> <bean id="userdao" class="tech.youngs.c3p0.UserDao"> <property name="jdbcTemplate" ref="jdbcTemplate"></property> </bean> <bean id="userservice" class="tech.youngs.c3p0.UserService"> <property name="userdao" ref="userdao"></property> </bean>
UserDao中的代码:
String sql = "insert into user values(?,?)"; int row = jdbcTemplate.update(sql,"小明","789456"); System.out.println("成功添加了"+row+"条数据");
Spring事务管理
Spring提供了两种事务管理的方式:声明式事务管理【常用】和编程式事务管理【不常用】
声明式事务管理:基于xml配置文件实现,基于注解的实现
Spring为不同的框架提供了不同的事务管理接口:
DataSourceTransactionManager --- jdbcTemplate、iBitis、MyBatis
HibernateTransactionManager --- Hibernate
要想使用Spring对事务进行管理,要先对事务管理器进行配置。
e.g.通过转账的例子演示Spring事务管理
Service层 业务逻辑层 所有的业务逻辑代码在这里面写
Dao层 数据持久层 只放对数据库操作
转账过程中可能会出现这样的问题:
当减少的操作指令发出后系统出现了异常,导致无法继续执行操作则会造成应该增加的一方并未增加该有的钱数。例如:
public void transfer() { //小王少钱 accountDao.minus(); //出异常 int i = 10/0; //小马多钱 accountDao.add(); }
正常的数据库总数应该是相同的,但是现在的数据库情况是:
这时候就需要事务的管理了,hibernate中在出现异常时可以进行事务回滚,Spring也提供了类似的机制
Spring的事务管理器的配置类似于切面:
配置文件方法:
<!-- 第一步 配置事务管理器 --> <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <!-- 注入DataSource --> <property name="dataSource" ref="dataSource"></property> </bean> <!-- 第二步 配置事务管理增强 --> <!-- tranaction-manager 的值要和配置的事务管理器的id值 --> <tx:advice id="txadvice" transaction-manager="txManager"> <!-- 设置进行事务操作的规则 只有满足规则的条件才执行事务操作 --> <tx:attributes> <!-- method 配置执行事务操作的方法 --> <tx:method name="transfer"/> </tx:attributes> </tx:advice> <!-- 第三步 配置切面 --> <aop:config> <aop:pointcut expression="execution(* tech.youngs.account.AccountService.*(..))" id="pointcut"/> <aop:advisor advice-ref="txadvice" pointcut-ref="pointcut"/> </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的注解
package tech.youngs.account; import org.springframework.transaction.annotation.Transactional; @Transactional public class AccountService { private AccountDao accountDao; public void setAccountDao(AccountDao accountDao) { this.accountDao = accountDao; } public void transfer() { //小王少钱 accountDao.minus(); //出异常 int i = 10/0; //小马多钱 accountDao.add(); } }