【如果你要使用的是spring6,那么还需要配置一个spring里程碑版本的仓库】
<repository>
<id>repository.spring.milestone</id>
<name>Spring Milestone Repository</name>
<url>https://repo.spring.io/milestone</url>
</repository>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>6.0.0-M2</version>
</dependency>
【获取spring容器当中的bean对象】
这个是获取spring容器对象,ClassPathXmlApplicationContext专门从类路径下加载文件
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");
获取spring文件当中配置的bean对象
applicationContext.getBean("这里写xml文件bean当中的id属性值");
【技巧】
* 1.获取的bean是Object类型的,我们不使用强转直接转化为原本的类型
Vip vipBean = applicationContext.getBean("vipBean", Vip.class);
这样使用getbean方法直接获取的对象是它原本的类的类型
【日志文件log4j2的使用】
第一步::首先加入依赖
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.19.0</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j2-impl</artifactId>
<version>2.19.0</version>
</dependency>
第二步::再类的根路径下(resource)文件当中创建log4j2.xml文件,文件名必须是log4j2.xml不能更改
【Bean注入】
spring6-dependency-injection
【set注入】
第一步:在我们需要创建接口对象的类当中创建这个对象的set方法,一般直接使用set加对象属性名
第二步:在我们的spring.xml文件当中编写 <!--set注入-->
<bean id="userDaoBean" class="com.xsh.spring6.dao.UserDao"/>
<bean id="userServiceBean" class="com.xsh.spring6.service.UserService">(这里的id就是去掉set然后首字母该小写)
<property name="userDao" ref="userDaoBean"></property>
</bean>
【构造注入】
第一步:在我们需要创建接口对象的类当中创建这个对象的构造方法
第二步: <bean id="userDaoBean" class="com.xsh.spring6.dao.UserDao"/>
<bean id="vipDaoBean" class="com.xsh.spring6.dao.VipDao"/>
<bean id="customerServiceBean" class="com.xsh.spring6.service.CustomerService">
<constructor-arg index="0" ref="userDaoBean"/>
<constructor-arg index="1" ref="vipDaoBean"/>(这里的index是我们构造方法当中需要传入值的序号)
(也可以把index改为使用name,name就是构造方法当中传入值的属性名)
</bean>
【set注入专题】 不给属性注入,属性的默认值就是null
*1.简单类型注入
一个user类,类当中有username,password,age三个属性
<bean id="userBean" class="com.xsh.spring6.bean.User">
<property name="username" value="zhangsan"/>
<property name="password" value="123456"/>
<property name="age" value="21"/>(简单类型可以直接使用value进行赋值)
</bean>
*2.注入数组类型
<bean id="daYeBean" class="com.xsh.spring6.bean.DaYe">
<property name="aiHaos">
<array>
<value>抽烟</value>
<value>喝酒</value>
<value>烫头</value>(如果是复杂类型的话
要使用<ref bean="这里写复杂类型的bean的id"/>)
</array>
</property>
</bean>
*3.map集合注入 set-di.xml
<bean id="personBean" class="com.xsh.spring6.bean.Person">
<property name="phone">
<map key-type="java.lang.String" value-type="java.lang.String">
<entry key="zhangsan" value="123456"/>
<entry key="lisi" value="1234567"/>
(如果不是简单类型 使用 key-ref="" value-ref="")
</map>
</property>
</bean>
*4.特殊符号的注入
第一种:使用实体符号 比如 < - < 这个是小于号和它的尸体符号
第二种:使用 <![CDATA[]]>这个符号里面的不会被xml文件解析,只会被认为是普通字符串
*5.p命名空间注入 简化set方法注入
第一步 在spring.xml文件当中加入 xmlns:p="http://www.springframework.org/schema/p"
第二步 <bean id="pDogBean" class="com.xsh.spring6.bean.PDog" p:name="zhangsan" p:age="21" p:brith-ref="brithBean">
<property name="pass" value="2 < 3"/> <!--测试特殊符号注入-->
</bean>
<bean id="brithBean" class="java.util.Date"/>
*6.c命名空间注入 简化构造方法注入 spring-c.xml
第一步:在spring.xml文件当中加入 xmlns:c="http://www.springframework.org/schema/c"
第二步: <bean id="cDogBean" class="com.xsh.spring6.bean.CDog" c:_0="zhangsan" c:_1="21">
<constructor-arg name="sex" value="男"></constructor-arg>(这里可以直接写在前面的bean当中)
</bean>
*7.配置复用 spring-util.xml
第一步:在配置文件当中加入
xmlns:util="http://www.springframework.org/schema/util
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">
第二步: <util:properties id="prop">
<prop key="driver">com.mysql.cj.jdbc.Driver</prop>
<prop key="url">jdbc:mysql://localhost:3306/spring6</prop>
<prop key="user">root</prop>
<prop key="password">123456</prop>
</util:properties>
*8.自动装配 自动装配是建立在set方法之上的
根据名字自动装配(autowire="byName") spring-autowire.xml
<bean id="order" class="com.xsh.spring6.bean.Order"></bean>
<bean id="orderServiceBean" class="com.xsh.spring6.service.OrderService" autowire="byName"></bean>
<!--这里加上autowire="byName"就是根据名字自动装配
如果使用自动装配的话,拿我们的索要创建的接口对象bean
的id不能随便写,只能是set方法当中去掉set,首字母改小写,差不多就是属性名字-->
【xml引入外部文件】 spring6-dependency-injection 》》 spring-properties.xml
第一步:在配置文件当中加入
xmlns:context="http://www.springframework.org/schema/context"
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
第二步: <!--引入外部文件-->
<context:property-placeholder location="jdbc.properties"/>
<bean id="myDataSourceBean" class="com.xsh.spring6.jdbc.MyDataSource">
<property name="driver" value="${driverClass}"/>
<property name="url" value="${url}"/>
<property name="password" value="${password}"/>
<property name="user" value="${user}"/>
</bean>
【bean的作用域】 spring6-004-scope
单例与多例:: bean默认情况下是单例的,在spring上下文初始化的时候实例化对象,而不是在getBean的时候实例化
多例模式: 将scope设置成 prototype 多例模式上下文时候并不会初始化这些bean,在调用getBean的时候初始化
<bean id="stringBean" class="com.xsh.spring.bean.StringBean" scope="prototype"></bean>
其实scope有4个值:prototype,singleton,request,session
【自定义一个scope】 一般是为了创建线程获取与主线程不是同一个的对象
第一步:在spring.xml文件将scope注册到spring容器当中
使用方式就是entry标签当中的key
<bean class="org.springframework.beans.factory.config.CustomScopeConfigurer">
<property name="scopes">
<map>
<entry key="threadScope">
<bean class="org.springframework.context.support.SimpleThreadScope"/>
</entry>
</map>
</property>
</bean>
<bean id="sBean" class="com.xsh.spring.bean.StringBean" scope="threadScope"></bean>
主线程调用之后,我们还可以创建一个线程再次调用,另一个线程拿到的和主线程的不是同一个对象
//使用另一个线程获取对象
new Thread(new Runnable() {
@Override
public void run() {
StringBean sb3 =applicationContext.getBean("sBean", StringBean.class);
System.out.println(sb3);
}
}).start();
【工厂】 spring6-simple-factory
简单工厂模式:: com.xsh.simple.factory.pojo
工厂方法模式:: com.xsh.spring.factory.method
【Bean实例化的四种方式】 spring6-005-instantiation
(这里需要注意的是简单工厂当中的是静态方法,而方法模式当中的不是静态get方法,
所以方法模式需要创建对象调用get,而简单工厂不需要使用对象调用,直接类调用
FactoryBean需要实现,这个方法其实就是第三种方式的简化版本)
<!--bean实例化的第一种方式,构造方法实例-->
<bean id="userBean" class="com.xsh.spring6.bean.User"></bean>
<!--bean实例化第二种方式,通过简单工厂实例化对象,需要告诉spring框架调用那个类的那个方法获取bean-->
<!--factory-method属性指定的就是工厂类房中的静态方法,也就是告诉spring框架那个类可以获取bean-->
<bean id="starBean" class="com.xsh.spring6.bean.StarFactory" factory-method="get"/>
<!--spring提供的实例化方式,第三种,通过工厂方法模式,通过factory-bean属性 + factory-method属性共同完成-->
<!--告诉spring调用那个对象的那个方法来获取Bean-->
<bean id="gunFactory" class="com.xsh.spring6.bean.GunFactory"/>
<!--factory-bean告诉spring调用那个类,factory-method告诉spring调用那个方法-->
<bean factory-bean="gunFactory" factory-method="get"/>
<!--spring提供的实例化方式第四种,通过factoryBean来实现
由于你编写的类实现了factoryBean,所以不需要指定factory-bean和factory-method这两个属性,factoryBean会自动帮你实现-->
<!--通过FactoryBean这个Bean,主要是对普通Bean进行加工处理-->
<bean id="person" class="com.xsh.spring6.bean.PersonFactory"/>
【FactoryBean实战之注入Date【
spring6-005-instantiation 》》》 DateSpring.xml
<!--工厂Bean,返回普通Bean:Date--> DateFactory这个类实现了FactoryBean
<bean id="dateBean" class="com.xsh.spring6.pojo.DateFactory">
<property name="strDate" value="2001-11-28"></property>
</bean>(这里是将字符串传入工厂里,转化成Date)
<!--将我们的Date赋值给Student的Date属性-->
<bean id="student" class="com.xsh.spring6.pojo.Student">
<property name="date" ref="dateBean"/>
</bean>
【Bean的生命周期】 spring6-006-bean-lifecycle
生命周期之五步
其中init和destroy这两个方法自己写了,需要到Bean容器当中进行配置
/*
* Bean生命周期
* 第一步:实例化Bean(调用无参数构造方法)
* 第二步:给bean属性赋值(调用set方法)
* 第三步:初始化Bean(会调用init方法,这个方法需要我们自己配置)
* 第四步:使用Bean
* 第五步:销毁Bean(会调用Bean的destroy方法,这个方法也需要我们自己配置)
* */
生命周期之七步:;
七步的话就是多了一个Bean后处理器
【配置Bean后处理器】
写一个类去实现BeanPostProcessor这个类,重写其中的两个方法
围绕init方法前后执行
/*
* Bean生命周期
* 第一步:实例化Bean(调用无参数构造方法)
* 第二步:给bean属性赋值(调用set方法)
* 第三步:执行Bean后处理器before方法
* 第四步:初始化Bean(会调用init方法,这个方法需要我们自己配置)
* 第五步 执行Bean后处理器的after方法
* 第六步:使用Bean
* 第七步:销毁Bean(会调用Bean的destroy方法,这个方法也需要我们自己配置)
* */
【将自己new出来的对象纳入spring容器当中去管理】 spring6-006-bean-lifecycle 》》 bean
DefaultListableBeanFactory dlbf = new DefaultListableBeanFactory();
dlbf.registerSingleton("stuBean",stu);
Object stuBean = dlbf.getBean("stuBean");
循环依赖: 循环依赖只有在两个Bean都是scope="prototype"的时候,才会出现异常,
循环依赖一般是使用 scope="singleton"和构造注入一起实现
【反射机制的调用】 spring6-revlew-reflect
四要素:调用那个对象的那个方法,传入什么参数,返回什么值;
//获取类
Class<?> clazz = Class.forName("com.xsh.spring.reflect.SomeService");
//获取方法 首先是方法名字,再是方法的传入参数的类型
Method doSome = clazz.getDeclaredMethod("doSome", String.class, int.class);
//创建对象
Object obj = clazz.newInstance();
//执行方法
Object zhangsan = doSome.invoke(obj, "zhangsan", 20);//这里传入的参数,对象,传入的参数
------------------------------------------------------------
【spring注解式开发】
注解开发扫描原理: spring6-review-annotation
(自定义注解配置,解析注解,获取注解当中的值)
spring6-007-ioc-annotation
【声明Bean的注解】
@Component
@Controller
@Service
@Repository (这四个是同一个意思,只是为了增强可读性,分别使用再不同的业务层)
注解的使用:: 第一步:添加aop依赖,就是spring的依赖
第二步:再配置文件当中添加context(引入外部文件)命名空间
第三步:在配置文件当中指定扫描的包
<!--给spring框架指定要扫描那些包-->
组件扫描:: <context:component-scan base-package="这里写的需要扫描包的地址"/>
如果让单个声明Bean生效那么在context当中配置
【负责注入的注解:】
*1.@Value注解:
直接使用@Value,可以用在属性上,并且使用Value注解的话,可以不提供set属性赋值,
一般是简单类型,还可以用在set方法和构造方法上
*2.@Autowired:@Qualifier 一般是非简单类型
Autowired如果单个使用的话,是根据类型自动装配,如果想根据名字自动装配的话,需要连同@Qualifier一起使用
例子:: @Autowired
@Qualifier("orderDaoImplMysql")
private OrderDao orderDao;
(直接在属性上使用,Qualifier指定你所要创建的对象,因为impl下面有多个类,根据类型指定会报错)
*3.@Resource ::默认根据名字装配,byName,没有指定name时,使用属性名作为name,
通过name找不到的话自动启动类型自动装配
第一步: 使用这个的话需要引入依赖
<dependency>
<groupId>jakarta.annotation</groupId>
<artifactId>jakarta.annotation-api</artifactId>
<version>2.1.1</version>
</dependency>
第二步:然后可以直接作用在属性上或者set方法上,但是不能作用在构造方法上
@Resource(name = "personDaoMysql") 这里的name属性是我们配置的Bean的id
使用类代替注解配置xml文件,(Bean容器)
创建一个类加上:@Configuration(这个必须)
@ComponentScan({"cn.xsh.spring.dao","cn.xsh.spring.service"})(包扫描配置)
然后获取容器对象也不是ClassPathXmlApplicationContext
而是:AnnotationConfigApplicationContext,传的是我们的类对象
【jdbcTemplate】 spring-008-jdbc
使用第一步::在配置文件当中配置:
<!--配置jdbcTemplate-->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="myds"/>(这里配置的是我们的数据源))
</bean>
第二步就是获取对象:调用对象的方法,记住,在jdbctemplate当中insert,delete,update都是调用update方法
查询语句的话调用 .queryForObject方法
queryForObject(sql, new BeanPropertyRowMapper<>(User.class), 2);1.sql语句,返回值的类型,这里我们是创建的user对象,2是像sql语句当中的 ?传值
批量添加,修改,删除的话使用:.batchUpdate(sql,list)
查询多个.queryForList
jdbc回调函数其中也有例子
【使用德鲁伊连接池 DruidDataSource】
第一步:导入依赖 <dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.2.18</version>
</dependency>
第二步:在xml文件当中配置Bean
----------------------------------------------------------
【GOF代理模式机制】
【 静态代理】 就是简单工厂生产类似 static-proxy
【jdk 动态代理机制】:程序运行阶段,在内存当中动态生成代理类 dynamic-proxy-jdk
//获取目标对象
OrderService target = new OrderServiceImpl();
//创建代理对象
/*这里需要传入三个参数
newProxyInstance:翻译为新代理对象
1.ClassLoader loader 类加载器
类加载器,这个是在内存当中生成的字节码也是class文件,要执行也得先加载到内存当中,加载类就需要类加载器,所以需要指定类加载器
并且jdk要求,目标类的类加载器和代理类的类加载器要一致
2.Class<?>[] interfaces 实现的接口
代理类和目标类实现同一个接口
在内存当中生成代理类的时候,这个代理类是你需要告诉他实现那些接口
3.InvocationHandler h
调用处理器 ,这里一般是你具体需要加强什么代码,所以我们可以创建一个类来继承InvocationHandler类
从而实现加强代码,第三个传入的参数也就是那个类的对象
* */
OrderService orderService = (OrderService)Proxy.newProxyInstance(target.getClass().getClassLoader(),
target.getClass().getInterfaces(),
new TimerInvocationHandler(target));
//代理对象调用方法
orderService.generate();
/**其中继承InvocationHandler接口实现invoke方法
/*invoke当中有三个参数
第一个参数,Object proxy 代理对象的引用,这里引用较少
第二个参数:Method method 调用的那个方法
第三个参数 Object[] args 方法传入的值
* */
//调用目标对象上的目标方法,四要素,那个方法,那个对象,传入的参数,返回值
Object retValue = method.invoke(target, args);
*/
【CGLIB动态代理】
//创建字节码增强器
Enhancer enhancer = new Enhancer();
//告诉CGLIB父类是谁
enhancer.setSuperckass(“这里写父类”)
//设置回调(等同于jdk动态代理调用处理器,InvocationHandler
只是在CGLIB当中是MethodInterceptor )
enhancer.setCallBack(new "这里写继承了MethodInterceptor接口的类")
//然后就可以调用了
Object o = enhancer.create();
【面向切面编程】
1.* 切面编程七大术语:
连接点(joinpoint)描述的位置
切点(pointcut) 本质上就是方法(真正织入切面的那个方法叫做切点)
通知(Advice) 通知又叫做增强代码,就是具体增强的那个代码
切面:切点 + 通知
切面一般需要使用@Aspect注解进行标记
*1.前置通知@Before 目标方法执行之前的通知
*2.后置通知 @AfterReturning 目标方法执行之后的通知
*3.环绕通知 @Around 目标方法之前添加通知,同时目标方法之后添加通知 (范围是最大的)
*4.异常通知 @AfterThrowing 发生异常之后执行的通知
*5.最终通知 @After 放在finally语句块当中的通知
2.* 切点表达式
execution([访问控制权限修饰符] 返回值类型 [全限定类名] 方法名(形式参数列表) [异常])
[]这个里面代表可选
【*.spring aop基于注解式准备工作】 spring-009-aspectj-aop-anno 详解看
1.依赖文件
比之前的多一个aspects依赖 <dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>6.0.0-M2</version>
</dependency>
2.引入命名空间: context 和 aop 两个命名空间
context是组件扫描
aop是开启自动管理
<!--组件扫描-->
<context:component-scan base-package="com.xsh.spring.service"/>
<!--开启自动aspectj自动代理-->
<!--spring容器在扫描类的时候,查看该类上是否有@Aspect注解,如果有,就给它生成自动代理-->
<!-- expose-proxy="true"表示使用CGLIB自动代理
expose-proxy="false" 表示接口使用JDk动态代理,反之则使用CGLIB代理
-->
<aop:aspectj-autoproxy expose-proxy="true"/>
3.目标类
就是service类的构建 要声明Bean
4.切面类
切面类需要使用@Aspect注解进行标记
然后再切面类当中进行通知的编写
@Order 这个是切面执行顺序的,数字越小,优先级越高
5.如果使用全注解开发的话
新建一个类,代替spring.xml文件
添加下面的注解
@Configuration
@ComponentScan({"com.xsh.spring.service"}) 组件扫描--
@EnableAspectJAutoProxy(proxyTargetClass = true) 启用aspectj的自动代理机制
*.基于xml文件 spring6-010-aspectj-aop-xml 不使用注解,使用xml文件进行配置
还是一样要引入context和aop命名空间
<!--纳入spring ioc管理-->
目标类 <bean id="userService" class="com.xsh.spring6.service.UserService"/>
切面类 <bean id="timerAspect" class="com.xsh.spring6.service.TimerAspect"/>
<!--aop的配置-->
<aop:config>
<!--切点表达式-->
<aop:pointcut id="myPointcut" expression="execution(* com.xsh.spring6.service..*(..))"/>
<!--切面=通知+切点-->
<aop:aspect ref="timerAspect">
<aop:around method="aroundAdvice" pointcut-ref="myPointcut"/>
</aop:aspect>
</aop:config>
【开启事务】 spring6-011-tx-bank
1.添加依赖 jdbc,spring-context,数据库依赖,德鲁伊连接池,@Resource,junit依赖
2.配置文件当中: 添加context,tx命名空间
<!--配置组件扫描-->
<context:component-scan base-package="com.xsh.spring6.bank"/>
<!--配置数据源-->
<bean id="mydateSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/mvc"/>
<property name="username" value="root"/>
<property name="password" value="Xx20011128"/>
</bean>
<!--配置jdbcTemplate-->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="mydateSource"/>
</bean>
<!--配置事务管理器-->
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="mydateSource"/>
</bean>
<!--开启事务注解驱动器,开启事务注解,告诉spring,采用注解的方式去控制事务-->
<tx:annotation-driven transaction-manager="txManager"/>
3.那里需要使用事务管理,直接加上注解 @Transactional
*.Transactional 一共有7中传播行为 传播行为看里面的保存数据的方法
·REQUIRED:支持当前事务,如果没有就新建一个 (默认)
·SUPPORTS:支持当前事务,如果当前没有事务,就以非事务的方式执行
·MANDATORY:必须运行再一个事务中,如果当前没有事务正在发生,将抛出一个异常
·Requires_NEW:开启一个新的事务,如果之前存在事务,则将之前的事务挂起
·NOT_SUPPORTED:以非事务的的方式运行,如果存在事务,就将事务挂起
·NEVER:以非事务方式运行,如果有事务存在,抛出异常
·NETED:如果当前正有一个事务正在进行当中,则再该事务当中在嵌套一个事务,如果没有事务,则像REQUIRED一样,创建一个事务
*.使用例子: @Transactional(propagation = Propagation.REQUIRED)
4.dao层操作直接使用德鲁伊连接池
5.使用全注解去配置spring.xml文件 看这个类Spring6Config
测试方法看 NoXmlTest
【spring整合mybatis】
1.pojo类
package com.xsh.bank.pojo;
public class Account {
private int id;
private String actno;
private Double balance;
public Account(int id, String actno, Double balance) {
this.id = id;
this.actno = actno;
this.balance = balance;
}
public Account() {
}
@Override
public String toString() {
return "Account{" +
"id=" + id +
", actno='" + actno + '\'' +
", balance=" + balance +
'}';
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getActno() {
return actno;
}
public void setActno(String actno) {
this.actno = actno;
}
public Double getBalance() {
return balance;
}
public void setBalance(Double balance) {
this.balance = balance;
}
}
2.mapper接口
package com.xsh.bank.mapper;
import com.xsh.bank.pojo.Account;
import org.springframework.context.annotation.Configuration;
import java.util.List;
@Configuration("accountMapper")
public interface AccountMapper {//该接口不需要写实现类,通过mybatis代理机制生成实现类
//这里就是dao,只需要编写crud方法即可
int insert(Account account);
int deleteByActno(String actno);
int update(Account account);
Account selectByActno(String actno);
List<Account> selectAll();
}
3.业务层service
接口
package com.xsh.bank.service;
import com.xsh.bank.pojo.Account;
import java.util.List;
public interface AccountService {//Service接口
/**
* 开户
* */
int save(Account account);
/**
* 销毁户
* */
int deleteByAccount(String actno);
/**
* 修改账户
* */
int modify(Account account);
/**
* 查询账户
* */
Account getByActno(String actno);
/**
* 查询所有账户
* */
List<Account> getAll();
/**
* 转账业务
* */
void transfer(String fromactno,String toactno,Double money);
}
实现类
package com.xsh.bank.service.impl;
import com.xsh.bank.mapper.AccountMapper;
import com.xsh.bank.pojo.Account;
import com.xsh.bank.service.AccountService;
import jakarta.annotation.Resource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.sql.SQLOutput;
import java.util.List;
@Transactional
@Service("accountService")
public class AccountServiceImpl implements AccountService {
@Autowired
private AccountMapper accountMapper;
@Override
public int save(Account account) {
int count = accountMapper.insert(account);
return count;
}
@Override
public int deleteByAccount(String actno) {
int count = accountMapper.deleteByActno(actno);
return count;
}
@Override
public int modify(Account account) {
int count = accountMapper.update(account);
return count;
}
@Override
public Account getByActno(String actno) {
Account account = accountMapper.selectByActno(actno);
return account;
}
@Override
public List<Account> getAll() {
List<Account> accounts = accountMapper.selectAll();
return accounts;
}
/**
* 转账业务
* */
@Override
public void transfer(String fromactno, String toactno, Double money) {
Account account1 = accountMapper.selectByActno(fromactno);
if(account1.getBalance()<money){
throw new RuntimeException("余额不足");
}
Account account2 = accountMapper.selectByActno(toactno);
account1.setBalance(account1.getBalance()-money);
account2.setBalance(account2.getBalance()+money);
int count = accountMapper.update(account1);
count += accountMapper.update(account2);
if(count == 2){
System.out.println("转账成功");
}else{
throw new RuntimeException("转账失败");
}
}
}
4.在resources下配置mapper配置,记住,文件所放的位置要和前面配置的Mapper接口的位置一致
在其中写数据库的操作,dao层
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.xsh.bank.mapper.AccountMapper">
<insert id="insert">
insert into t_act values(#{id},#{actno},#{balance});
</insert>
<delete id="deleteByActno">
delete from t_act where actno = #{actno}
</delete>
<update id="update">
update t_act set balance = #{balance} where actno = #{actno};
</update>
<select id="selectByActno" resultType="Account">
SELECT id, actno, balance from t_act where actno = #{actno}
</select>
<select id="selectAll" resultType="Account">
SELECT id, actno, balance from t_act
</select>
</mapper>
5.外部文件类,数据流 jdbc.properties
jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mvc
jdbc.username=root
jdbc.password=Xx20011128
6.mybatis核心文件的配置(mybatis-config.xml)
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!--斑海猪我们打印mybatis日志信息,sql语句-->
<settings>
<setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>
</configuration>
7.spring.xml文件的配置
<?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: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/tx http://www.springframework.org/schema/tx/spring-tx.xsd">
<!--上面引入了context,tx的命名空间-->
<!--组件扫描-->
<context:component-scan base-package="com.xsh.bank"/>
<!--引入外部的属性配置文件-->
<context:property-placeholder location="jdbc.properties"/>
<!--数据源-->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
<!--配置SqlSessionFactoryBean-->
<bean class="org.mybatis.spring.SqlSessionFactoryBean">
<!--注入数据源-->
<property name="dataSource" ref="dataSource"/>
<!--注入mybatis核心配置文件路径-->
<property name="configLocation" value="mybatis-config.xml"/>
<!--指定别名包-->
<property name="typeAliasesPackage" value="com.xsh.bank.pojo"/>
</bean>
<!--Mapper扫描配置器-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.xsh.bank.mapper"/>
</bean>
<!--配置事务管理器 注入数据源-->
<bean id="txMapper" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<!--启用事务注解-->
<tx:annotation-driven transaction-manager="txMapper"/>
</beans>