Mybatis与Spring整合(纯注解)
java1.5版本之后开始支持注解,spring*2开始提供注解配置方式,到spring**4后spring推荐使用注解配置
IOC注解(主要作用就是在spring容器中声明一个Bean,同xml中的Bean节点作用相同,用在类上):
@Repository(标识DAO层)
@Service(标识Service层)
@Conmpent(用在其他组件上)
隐式注入:
@Autowired:根据类型注入
@Qualifier:更具名字注入,但是需要和Autowired连用
@Resource:jdk提供,默认根据名字注入,如果没找到名字则根据类型注入
Aop注解()
@Aspect(作用在类上,标识这是一个切面)
@Before(作用在方法上,前置增强)
@AfterReturing(作用在方法上,后置增强)
@AfterThrowing(作用在方法上,异常抛出增强)
@After(作用在方法上,最终增强)
其他注解
@Configuration:标识作用,表示这个类是一个核心配置类
@MapperScan:扫描Mapper接口,为dao层生成动态代理
@ComponentScan:扫描有注解的类所在的包
@EnableTransactionManagement:开启事务的注解
@EnableAspectJAutoProxy:开启aop的注解
@Transactional表示开启事务,作用在类上为该类所有方法都开启一个事务,也可以作用在方法上,表示当前方法开启一个事务
1.导入依赖
pom节点砸死上一章spring+mybatis整合(xml)配置中有,这里就不重复了。
2.准备数据库
3.业务代码
dao层代码
1 public interface AccountDao { 2 List<Account>getAll();//查询数据库中所有信息 3 @Update("update account set accountmonkey=accountmonkey+1000 where accountid=1") 4 int addMonkey();//给id为1的用户加1000块钱 5 @Update("update account set accountmonkey=accountmonkey-1000 where accountid=2") 6 int subMonkey();//给id为2的用户减1000块钱 7 }
service层接口
1 public interface AccountService { 2 List<Account> getAll();//查询所有 3 int changemonkey();//模拟转账 4 }
service层实现类
1 @Service 2 public class AccountServiceImpl implements AccountService { 3 //注入dao接口实例 4 @Autowired 5 private AccountDao dao; 6 @Override 7 public List<Account> getAll() { 8 return dao.getAll(); 9 } 10 11 @Transactional(propagation = Propagation.REQUIRED,isolation = Isolation.READ_COMMITTED) 12 @Override 13 public int changemonkey() { 14 dao.subMonkey();//id为2的先转出1000 15 //int reuslt=5/0;//模拟一个异常,中断交易 16 dao.addMonkey();//id为1的收到1000 17 return 0; 18 } 19 20 }
实体类(建完表一定要先写实体类)
public class Account { private int accountid; private String accountname; private Double accountmonkey; //省略setter,getter }
4.核心配置类
1 package com.cn.config; 2 3 import com.cn.advisor.AccountAdvisor; 4 import org.apache.commons.dbcp2.BasicDataSource; 5 import org.mybatis.spring.SqlSessionFactoryBean; 6 import org.mybatis.spring.annotation.MapperScan; 7 import org.springframework.context.annotation.Bean; 8 import org.springframework.context.annotation.ComponentScan; 9 import org.springframework.context.annotation.Configuration; 10 import org.springframework.context.annotation.EnableAspectJAutoProxy; 11 import org.springframework.core.io.support.PathMatchingResourcePatternResolver; 12 import org.springframework.jdbc.datasource.DataSourceTransactionManager; 13 import org.springframework.transaction.annotation.EnableTransactionManagement; 14 15 import javax.sql.DataSource; 16 import java.beans.PropertyVetoException; 17 import java.io.IOException; 18 import java.net.MalformedURLException; 19 20 @Configuration//指定这是一个核心配置类 21 @MapperScan("com.cn.dao")//扫描dao层,生成动态代理 22 @ComponentScan("com.cn")//扫描该路径下所有类上的注解 23 @EnableTransactionManagement//开启事务 24 @EnableAspectJAutoProxy 25 public class ApplicationConfig { 26 //配置数据源 27 @Bean//等同于xml中的<bean>节点 28 public DataSource dataSource(JdbcConfig dbcp) throws PropertyVetoException { 29 //其中JdbcConfig是自定义的配置类,读取properties文件的类 30 BasicDataSource cd = new BasicDataSource(); 31 cd.setDriverClassName(dbcp.getDriver()); 32 cd.setUrl(dbcp.getUrl()); 33 cd.setUsername(dbcp.getName()); 34 cd.setPassword(dbcp.getPassword()); 35 return cd; 36 } 37 //配置核心Mybatis核心工厂 38 @Bean 39 public SqlSessionFactoryBean sqlSessionFactoryBean(DataSource ds) throws IOException { 40 SqlSessionFactoryBean bean = new SqlSessionFactoryBean(); 41 bean.setDataSource(ds);//配置数据源 42 bean.setTypeAliasesPackage("com.cn.entity");//设置实体类别名 43 PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(); 44 bean.setMapperLocations(resolver.getResources("classpath:/mapper/*.xml"));//配置Mapper映射文件的路径 45 return bean; 46 } 47 //配置事务管理器 48 @Bean 49 public DataSourceTransactionManager dataSourceTransactionManager(DataSource ds){ 50 DataSourceTransactionManager dm = new DataSourceTransactionManager(); 51 dm.setDataSource(ds); 52 return dm; 53 } 54 }
读取连接参数的配置类
package com.cn.config; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.PropertySource; import org.springframework.stereotype.Component; import org.springframework.stereotype.Repository; @Repository//这里就是向证明一下IOC的几个声明bean的注解是可以混用的 @PropertySource("classpath:/database.properties") public class JdbcConfig { @Value("${jdbc.username}") private String name; @Value("${jdbc.password}") private String password; @Value("${jdbc.driver}") private String driver; @Value("${jdbc.url}") private String url; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String getDriver() { return driver; } public void setDriver(String driver) { this.driver = driver; } public String getUrl() { return url; } public void setUrl(String url) { this.url = url; } }
切面
@Aspect//标志这是一个切面 @Component//和@Service作用一样,都是在spring容器中声明一个Bean public class AccountAdvisor { @Pointcut("execution(* com.cn.service.*.*(..))") public void pointcut(){} @Before("pointcut()") public void before(JoinPoint jp){ System.out.println("我是前置增强!!!"); } }
编写测试类
public class App { public static void main( String[] args ) { ApplicationContext context = new AnnotationConfigApplicationContext(ApplicationConfig.class); AccountService bean = context.getBean(AccountService.class); System.out.println(bean.getAll());//获取所有用户 bean.changemonkey();//模拟转账 } }
将service层的算术异常的注释解开,模拟一个异常,可以验证事务是否能用!