(完整的代码在文章附带文件中 , 文章里的代码仅作展示 , 可能有部分不完善
代码地址 :下载:https://javazhang.lanzn.com/i5oLI1vyiile 密码:1234
)
任务目标
具体实现方法和心得
步骤1. 导入依赖项
Spring依赖 , aop依赖,德鲁伊依赖,mybatis依赖 ,
mysql驱动 , mybatis-spring 依赖
注意点 mybatis-spring 和 mybatis 的依赖版本有
关联关系 , 需要注意
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>spring-Demo1</artifactId>
<packaging>war</packaging>
<version>1.0-SNAPSHOT</version>
<name>spring-Demo1 Maven Webapp</name>
<url>http://maven.apache.org</url>
<dependencies>
<!-- Spring依赖 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.10.RELEASE</version>
</dependency>
<!-- aop依赖 -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.4</version>
</dependency>
<!-- 德鲁伊依赖 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.16</version>
</dependency>
<!--mybatis依赖 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.6</version>
</dependency>
<!--mysql驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
<!-- mybatis整合spring 和mybais是关联的 属于mybatis的pro -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.3.0</version>
</dependency>
<!-- 测试框架依赖 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.2.10.RELEASE</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.2.10.RELEASE</version>
</dependency>
</dependencies>
<build>
<finalName>spring-Demo1</finalName>
</build>
</project>
步骤2.
编辑Spring配置类 , Jdbc配置类 , Mybatis配置类
package com.zhang.config;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Controller;
@Configuration
@ComponentScan("com.zhang")
@PropertySource("classpath:jdbc.properties")
@Import({MyBatisConfig.class , JdbcConfig.class})
@EnableTransactionManagement
public class SpringConfig {
}
package com.zhang.config;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.mapper.MapperScannerConfigurer;
import org.springframework.context.annotation.Bean;
import javax.sql.DataSource;
public class MyBatisConfig {
@Bean
public SqlSessionFactoryBean sqlSessionFactoryBean(DataSource dataSource) {
SqlSessionFactoryBean ssfb = new SqlSessionFactoryBean();
ssfb.setTypeAliasesPackage("com.zhang.domain");
ssfb.setDataSource(dataSource);
return ssfb;
}
@Bean
public MapperScannerConfigurer mapperScannerConfigurer() {
MapperScannerConfigurer msc = new MapperScannerConfigurer();
msc.setBasePackage("com.zhang.dao");
return msc;
}
}
心得Mybatis的两个关联路径操作 如果路径错误 ,会导致后面Service无法自动装配
package com.zhang.config;
import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.sql.DataSource;
public class JdbcConfig {
@Value("${jdbc.driver}")
private String driver;
@Value("${jdbc.url}")
private String url;
@Value("${jdbc.username}")
private String username;
@Value("${jdbc.password}")
private String password;
@Bean
public DataSource dataSource() {
DruidDataSource ds = new DruidDataSource();
ds.setDriverClassName(driver);
ds.setUrl(url);
ds.setUsername(username);
ds.setPassword(password);
return ds;
}
@Bean
public PlatformTransactionManager transactionManager(DataSource dataSource){
DataSourceTransactionManager ptm = new DataSourceTransactionManager();
ptm.setDataSource(dataSource);
return ptm;
}
}
}
心得
MybatisConfig的 MapperScannerConfigurer 方法
是对数据举行处理代码的绑定
SqlSessionFactoryBean 方法是对 数据库中的数据部分
代码进行绑定
步骤三:编写数据操作AccountDao 和 日志操作 LogDao
package com.zhang.dao;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Update;
public interface AccountDao {
@Update("update tbl_account set money = money + #{money} where name = #{name}")
void inMoney(@Param("name") String name ,@Param("money") Double money);
@Update("update tbl_account set money = money - #{money} where name = #{name}")
void outMoney(@Param("name") String name , @Param("money") Double money);
}
package com.zhang.dao;
import org.apache.ibatis.annotations.Insert;
public interface LogDao {
@Insert("insert into tbl_log (info, createDate) values(#{info},now())")
void log(@Param("info")String info);
}
心得 : 在LogDao中 Insert 语句用到了一个now() 方法用于在数据库中添加当前时间
步骤四:编写domain包账户方法
package com.itheima.domain;
import java.io.Serializable;
public class Account implements Serializable {
private Integer id;
private String name;
private Double money;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Double getMoney() {
return money;
}
public void setMoney(Double money) {
this.money = money;
}
@Override
public String toString() {
return "Account{" +
"id=" + id +
", name='" + name + '\'' +
", money=" + money +
'}';
}
}
步骤五 编写服务层Service , logService 和AccountService
这里用到事务的知识点 , 事务为了保证在程序出现错误时,回滚操作,防止出现更大错误 , 而数据库日志需要在数据库操作有错误时也要执行,不需要回滚 ,所以他的事务要和数据库操作的事务分开 , 分为两个事务
package com.zhang.service;
import org.apache.ibatis.annotations.Update;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
public interface LogService {
@Transactional(propagation = Propagation.REQUIRES_NEW)
void log(String out , String in ,Double money);
}
package com.zhang.service;
import org.springframework.transaction.annotation.Transactional;
public interface AccountService {
@Transactional
void transfer(String out , String in ,Double money);
}
package com.zhang.service.imp;
import com.zhang.dao.AccountDao;
import com.zhang.service.AccountService;
import com.zhang.service.LogService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class AccountServiceImp implements AccountService {
@Autowired
private AccountDao accountDao;
@Autowired
private LogService logService;
public void transfer(String out, String in, Double money) {
try {
accountDao.outMoney(out, money);
accountDao.inMoney(in, money);
} finally {
logService.log(out, in, money);
}
}
}
package com.zhang.service.imp;
import com.zhang.dao.LogDao;
import com.zhang.service.LogService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class LogServiceImp implements LogService {
@Autowired
private LogDao logDao;
public void log(String out, String in, Double money) {
logDao.log("转账操作由" + out +"到" + in + ",金额" + money);
}
}
测试用例
package com.zhang.service;
import com.zhang.config.SpringConfig;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = SpringConfig.class)
public class AccountServiceTest {
@Autowired
private AccountService accountService;
@Test
public void testTransfer() {
accountService.transfer("Tom" , "Jerry" , 50D);
}
}