Spring
1.Spring框架
1.spring优点
(1)轻量
- Spring框架使用的jar都比较小,一般在1M以下或者几百kb。Spring核心功能的所需的jar总共在3M左右。
- Spring框架运行占用的资源少,运行效率高。不依赖其他jar
(2)针对接口编程,解耦合
- Spring 提供了loc控制反转,由容器管理对象,对象的依赖关系。原来在程序代码中的对象创建方式,现在由容器完成。对象之间的依赖解耦合。
(3)AOP编程的支持
- 通过Spring提供的AOP功能,方便进行面向切面的编程,许多不容易用传统OOP实现的功能可以通过AOP轻松应付
- 在Spring 中,开发人员可以从繁杂的事务管理代码中解脱出来,通过声明式方式灵活地进行事务的管理,提高开发效率和质量。
(4)方便集成各种优秀框架
- spring不排斥各种优秀的开源框架,相反 Spring可以降低各种框架的使用难度,Spring提供了对各种优秀框架(如Struts,Hibernate、MyBatis)等的直接支持。简化框架的使用。Spring像插线板一样,其他框架是插头,可以容易的组合到一起。需要使用哪个框架,就把这个插头放入插线板。不需要可以轻易的移除。
2.IOC理论推导
- UserDao接口
- UserDaoImpl实现类
- UserService业务接口
- UserServiceImpl业务实现类
3.Spring快速入门
-
Spring的开发步骤导入坐标
<dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.3.16</version> </dependency> </dependencies> -
创建Bean 接口和实体类
public interface UserDao { void save(); }import com.kaiyu.dao.UserDao; public class UserDaoImpl implements UserDao { @Override public void save() { System.out.println("save running........"); } } -
创建applicationContext.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" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="userDao" class="com.kaiyu.dao.impl.UserDaoImpl"></bean> </beans> -
创建ApplicationContext对象getBean
public static void main(String[] args) { ClassPathXmlApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml"); UserDao userDao = (UserDao) app.getBean("userDao"); userDao.save(); }
4.Spring配置文件
4.1别名
-
添加了别名也可以使用别名使用
-
ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml"); Student student = (Student) app.getBean("st"); student.show();
<alias name="student" alias="st"></alias>
4.2 Bean标签基本配置
- 用于配置对象交由Spring来创建。
默认情况下它调用的是类中的无参构造函数,如果没有无参构造函数则不能创建成功。 - 基本属性:
- id: Bean实例在Spring容器中的唯一标识
- class: Bean的全限定名称
- name :别名 而且name可以取多个别名
4.3 Bean标签范围配置
scope:指对象的作用范围,取值如下:
| 取值范围 | 说明 |
|---|---|
| singleton | 默认值,单例的 |
| prototype | 多例的 |
| request | WEB 项目中,Spring创建一个Bean的对象,将对象存入到request域中 |
| session | WEB项目中,Spring创建一个 Bean的对象,将对象存入到session域中 |
| global session |
- 当scope的取值为singleton时
- Bean的实例化个数:1个
- Bean的实例化时机:当Spring核心文件被加载时,实例化配置的Bean实例
- Bean的生命周期:
- 对象创建:当应用加载,创建容器时,对象就被创建了
- 对象运行:只要容器在,对象一直活着
- 对象销毁:当应用卸载,销毁容器时,对象就被销毁了
- 当scope的取值为prototype时
- Bean的实例化个数:多个
- Bean的实例化时机:当调用getBean(方法时实例化Bean
- 对象创建:当使用对象时,创建新的对象实例
- 对象运行:只要对象在使用中,就一直活着
- 对象销毁:当对象长时间不用时,被Java的垃圾回收器回收了
4.4、improt
这个import,一般用于团队开发,它可以将多个配置文件,导入合并为一个
4.5 Bean生命周期配置
- init-method:指定类中的初始化方法名称
- destroy-method:指定类中销毁方法名称
4.6 Bean的依赖注入概念
依赖注入(DependencyInjection):它是Spring框架核心IOC的具体实现。
在编写程序时,通过控制反转,把对象的创建交给了Spring,但是代码中不可能出现没有依赖的情况。IOC解耦只是降低他们的依赖关系,但不会消除。例如:业务层仍会调用持久层的方法。
那这种业务层和持久层的依赖关系,在使用Spring之后,就让Spring来维护了。简单的说,就是坐等框架把持久层对象传入业务层,而不用我们自己去获取
3.依赖注入
3.1Set方式注入【重点】
-
·依赖注入:Set注入!
。依赖: bean对象的创建依赖于容器!I
。注入: bean对象中的所有属性,由容器来注入!-
复杂对象
-
private String address; @Override public String toString() { return "Address{" + "address='" + address + '\'' + '}'; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; }
-
-
-
配置注入
-
<bean id="address" class="com.kaiyu.pojo.Address"> <property name="address" value="长沙"></property> </bean> <bean id="student" class="com.kaiyu.pojo.Student"> <!--普通注入--> <property name="name" value="张三"></property> <!--ref注入--> <property name="address" ref="address" ></property> <!--数组注入--> <property name="books"> <array> <value>三国演义</value> <value>红楼梦</value> <value>水浒传</value> <value>西游记</value> </array> </property> <!--list注入--> <property name="hobbys"> <list> <value>听歌</value> <value>跳舞</value> <value>学习</value> </list> </property> <!-- map注入--> <property name="card"> <map> <entry key="省份证" value="1564564654654"></entry> <entry key="银行卡" value="797879798"></entry> </map> </property> <!--set注入--> <property name="games"> <set> <value>LOL</value> <value>CF</value> <value>CDF</value> </set> </property> <property name="info"> <props> <prop key="学号">2020</prop> <prop key="性别">男</prop> <prop key="姓名">姚开钰</prop> </props> </property> </bean>
-
-
真实测试对象
-
ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml"); Student student = (Student) app.getBean("student"); System.out.println(student.getName()); System.out.println(student.toString());
-
3.2 p标签和c标签
-
p标签和c标签不能直接使用 需要导入xml约束
xmlns:p="http://www.springframework.org/schema/p" xmlns:c="http://www.springframework.org/schema/c"
package com.pojo;
public class User {
private String name;
private int age;
public User() {
}
public User(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
<?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:p="http://www.springframework.org/schema/p"
xmlns:c="http://www.springframework.org/schema/c"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd">
<!--p命名空间注入/set注入-->
<bean id="use" class="com.pojo.User" p:name="丽梅" p:age="10">
</bean>
<!--c命名空间/构造器-->
<bean id="use2" class="com.pojo.User" c:name="开钰" c:age="19"></bean>
</beans>
4.Bean的自动装配
4.1autowire
1.byName自动装配
-
byName:会自动在容器上下文中查找,和自己对象set方法后面的值对应 beanid
-
<bean id="people" class="com.kaiyu.pojo.People" autowire="byName"> <property name="name" value="开钰"></property> </bean>
-
2.byType自动装配
-
byType:会自动在容器上下文中查找,和自己属性类型后面的值对应 bean
-
<bean id="people" class="com.kaiyu.pojo.People" autowire="byType"> <property name="name" value="开钰"></property> </bean>
-
3.小结
- byName的时候,需保证所有bean的id唯一,并且这个bean需要和自动注入的属性的set方法的值一致
- byType的时候,需保证所有bean的class唯一,并且这个bean需要和自动注入的属性的类型一致
4.2使用注解实现自动装配
1.使用须知
1.1导入约束 :context约束
1.2配置注解的支持 context:annotation-config/
<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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd">
<context:annotation-config/>
</beans>
2.@Autowired
-
@Autowire
-
在属性上个使用,也可以在set上使用
我们可以不用编写set方法了前提是这个自动装配的属性在啊IOC(Spring)容器中存在,切符合名字byname!
-
@Autowired
private Cat cat;
@Autowired
private Dog dog;
private String name;
public Cat getCat() {
return cat;
}
public Dog getDog() {
return dog;
}
public String getName() {
return name;
}
3.@Data
- 自动生成get set方法
4.@NoArgsConstructor
- 生成无参构造
5.@AllArgsConstructor
- 生成有参构造
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Phone {
private String name;
private double money;
}
public void phone(){
ApplicationContext app = new ClassPathXmlApplicationContext("phone.xml");
Phone phone = app.getBean("phone", Phone.class);
Phone xm = new Phone("小米", 222);
System.out.println(xm);
}
5.读取配置文件
5.1.读取properties文件
我们可以让Spring读取properties文件中的key/value,然后使用其中的值。
①设置读取properties
在Spring配置文什中加入如下标签:指定要读取的文件的路径。
<!--读取properties配置文件-->
<context:property-placeholder location="classpath:jdbc.properties"></context:property-placeholder>
其中的classpath表示类加载路径下。
我们也会用到如下写法: classpath:.properties其中的表示文件名任意。注意: context命名空间的引入是否正确
②使用配置文件中的值
在我们需要使用的时候可以使用${key)来表示具体的值。注意要再value属性中使用才可以。例如:
<bean id="datasource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="${jdbc.Driver}"></property>
<property name="url" value="${jdbc.url}"></property>
<property name="username" value="${jdbc.username}"></property>
<property name="password" value="${jdbc.password}"></property>
</bean>
6.Spring注解开发
6.1Spring原始注解
Spring原始注解主要是替代
| 注解 | 说明 |
|---|---|
| @Component | 使用在类上用于实例化Bean |
| @Controller | 使用在web层类上用于实例化Bean |
| @Service | 使用在service层类上用于实例化Bean |
| @Repository | 使用在dao层类上用于实例化Bean |
| @Autowired | 使用在字段上用于根据类型依赖注入 |
| @Qualifier | 结合@Autowired一起使用用于根据名称进行依赖注入 |
| @Resource | 相当于@Autowired+@Qualifier,按照名称进行注入 |
| @Value | 注入普通属性 |
| @Scope | 标注Bean的作用范围 |
| @PostConstruct | 使用在方法上标注该方法是Bean的初始化方法 |
| @PreDestroy | 使用在方法上标注该方法是Bean的销毁方法 |
6.2注意:
使用注解进行开发时,需要在applicationContext.xml中配置组件扫描,作用是指定哪个包及其子包下的Bean需要进行扫描以便识别使用解配置的类、字段和方法。
- 配置组件扫描
<context:component-scan base-package="com.kaiyu"/>
6.3区别(@Autowired @Qualifier @ Resource)
@Autowired 按照数据类型从Spring容器中进行匹配的
@Qualifier("userDao") 是按照id值从容器中进行匹配的但是主要此处@Qualifier结合@Autowired一起使用
@Resource(name="userDao")// CResource相当于@Qualifier+@Autowired
6.4Spring新注解
| 注解 | 说明 |
|---|---|
| @Configuration | 用于指定当前类是一个Spring 配置类,当创建容器时会从该类上加载注解 |
| ComponentScan | 用于指定Spring在初始化容器时要扫描的包。 作用和在Spring的xml配置文件中的 <context:component-scan base-package="com.itheima"/>一样 |
| Bean | 使用在方法上,标注将该方法的返回伯存储到Spring容器中 |
| @PropertySource | 用于加载.properties文件中的配置 |
| @lmport | 用于导入其他配置类 |
6.5.小结
xml 与注解:
o xml更加万能,适用于任何场合!维护简单方便。注解不是自己类使用不了,维护相对复杂!xml与注解最佳实践:
o xml用来管理bean;
。 注解只负责完成属性的注入;
。我们在使用的过程中,只需要注意一个问题:必须让注解生效,就需要开启注解的支持
<!--指定扫描的包,注解才会生效-->
<context:component-scan base-package="com.heima"></context:component-scan>
<context:annotation-config/>
7.代理模式
7.1静态代理
- 模拟一个简单的代理模式 ---租房
1.代理步骤
1.1接口
//租房
public interface Rent {
//租房方法
void rent();
}
1.2真实角色
//房东
public class Host implements Rent{
@Override
public void rent() {
System.out.println("房东出租房子........");
}
}
1.3.代理角色
public class Proxy implements Rent{
//房东
private Host host;
public Proxy() {
}
public Proxy(Host host) {
this.host = host;
}
@Override
public void rent() {
seeHouse();
host.rent();
fee();
contract();
}
//看房子方法
void seeHouse(){
System.out.println("中介带你看房子");
}
//中介费用
void fee(){
System.out.println("支付中介费用");
}
//签合同
void contract(){
System.out.println("和中介签合同");
}
}
1.4客户端访问代理角色
public class People {
public static void main(String[] args) {
//房东要租房
Host host = new Host();
//代理,中介帮房东租房
Proxy proxy = new Proxy(host);
//不需要见房东,直接找中介就可
proxy.rent();
}
}
2. 代理模式优缺点
2.1代理模式的好处:
- ·可以使真实角色的操作更加纯粹!不用去关注一些公共的业务·
- 公共也就就交给代理角色!实现了业务的分工!
- ·公共业务发生扩展的时候,方便集中管理!
2.2缺点:
- 一个真实角色就会产生一个代理角色;代码量会翻倍开发效率会变低
7.2加深静态代理
7.2.1.一个增删改查的小案例
-
接口
-
package com.kaiyu.demo02; public interface UserService { public void add(); public void delete(); public void update(); public void query(); }
-
-
真实角色
-
package com.kaiyu.demo02; public class UserServiceImpl implements UserService{ @Override public void add() { System.out.println("添加了一个用户"); } @Override public void delete() { System.out.println("删除了一个用户"); } @Override public void update() { System.out.println("修改了一个用户"); } @Override public void query() { System.out.println("查询了一个用户"); } }
-
-
代理角色
-
package com.kaiyu.demo02; public class UserServiceProxy implements UserService{ private UserService userService; public UserServiceProxy() { } public UserServiceProxy(UserService userService) { this.userService = userService; } @Override public void add() { log("add"); userService.add(); } @Override public void delete() { log("delete"); userService.delete(); } @Override public void update() { log("update"); userService.update(); } @Override public void query() { log("query"); userService.query(); } //日志方法 public void log(String msg ){ System.out.println("[bug]:使用了"+msg+"方法"); } }
-
-
客户端调用代理角色
-
package com.kaiyu.demo02; public class Client { public static void main(String[] args) { UserServiceImpl userService = new UserServiceImpl(); UserServiceProxy userServiceProxy = new UserServiceProxy(userService); userServiceProxy.add(); userServiceProxy.delete(); } }
-
7.3动态代理
万能模板
-
public class ProxyInvocationHandler implements InvocationHandler { //被代理的接口 private Object target; public void setTarget(Object target) { this.target = target; } //生成得到代理类 public Object getProxy(){ return Proxy.newProxyInstance(this.getClass().getClassLoader(), target.getClass().getInterfaces(),this); } //处理代理实例,并返回结果 @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object result = method.invoke(target, args); return result; } }public class Client { public static void main(String[] args) { //真实角色 UserServiceImpl userService = new UserServiceImpl(); //代理对象 不存在 ProxyInvocationHandler pih = new ProxyInvocationHandler(); pih.setTarget(userService);//设置要代理的对象 //动态生成代理类 UserService proxy = (UserService) pih.getProxy(); proxy.add(); proxy.query(); } }
动态代理的好
- ·可以使真实角色的操作更加纯粹!
- 不用去关注一些公共的业务·公共也就就交给代理角色!实现了业务的分工!
- ·公共业务发生扩展的时候,方便集中管理!
- 。一个动态代理类代理的是一个接口,一般就是对应的一类业务
8.Spring实现Aop
8.1概念
AOP为Aspect oriented Programming的缩写,意为:面向切面编程。他是一种可以在不修改原来的核心代码的情况下给程序动态统—进行增强的一种技术。
SpringAOP:批量对Spring容器中bean的方法做增强,并且这种增强不会与原来方法中的代码耦合。
1【重点】使用AOP织入,需要导入一个依赖包!
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.3.16</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.9</version>
</dependency>
</dependencies>
2.相关bean要注入容器中
-
开启组件扫描
-
<context:component-scan base-package="com.kaiyu"></context:component-scan>
-
-
加入@Service
-
@Service public class UserService { public void deleteAll(){ System.out.println("UserService中deleteAll的核心代码"); } } -
@Service public class PhoneService { public void deleteAll(){ System.out.println("PhoneService中的deleteAll的核心代码"); } }
-
3.实现AOP
-
开启AOP注解
-
xmlns:aop="http://www.springframework.org/schema/aop" http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd <!--开启注解支持--> <aop:aspectj-autoproxy/>
-
-
创建切面类
- 创建一个类,在类上加上@component和@Aspect使用@Pointcut注解来指定要被增强的方法
使用@Before注解来给我们的增强代码所在的方法进行标识,并且指定了增强代码是在被增强方法执行之前执行的。
- 创建一个类,在类上加上@component和@Aspect使用@Pointcut注解来指定要被增强的方法
4.切点
1.4.1切点表达式
- 可以使用切点表达式来表示要对哪些方法进行增强。
- 写法: execution([修饰符]返回值类型包名.类名.方法名(参数))
- ·访问修饰符可以省略,大部分情况下省略
- ·返回值类型、包名、类名、方法名可以使用星号* 代表任意
- ·包名与类名之间一个点.代表当前包下的类,两个点..表示当前包及其子包下的类·
- 参数列表可以使用两个点..表示任意个数,任意类型的参数列表
1.4.2切点函数@annotation
我们也可以在要增强的方法上加上注解。然后使用@annotation来表示对加了什么注解的方法进行增强。
写法:@annotation(注解的全类名)
- 定义注解如下 创建一个@annotation
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
public @interface InvokeLog {
}
- 给需要增强的方法加入注解
@Repository
public class UserService {
@InvokeLog
public void deleteAll(){
System.out.println("UserService中deleteAll的核心代码");
}
}
- 切面类中使用@annotation来确定要增强的方法
@Component
@Aspect
public class MyAspect{
//用Pointcut注解中的属性来指定对哪些方法进行增强
@Pointcut("@annotation(com.kaiyu.Aspect.InvokeLog)")
public void pt(){
}
@Before("pt()")
public void methodBefore(){
System.out.println("方法呗调用了");
}
@After("pt()")
public void methodAfter(){
System.out.println("方法后被调用");
}
}
1.5通知分类
- ·@Before:前置通知,在方法执行前执行
- .@AfterReturning:返回后通知,在目标方法执行后执行,如果出现异常不会执行
- @After:后置通知,在目标方法返回结果之后执行,无论是否出现异常都会执行·
- @AfterThrowing:异常通知,在目标方法抛出异常后执行
- Around:环绕通知,围绕着方法执行
9.Spring整合Mybatis
9.1步骤:
1.导入相关jar包
- junit
- mybatis
- mysql数据库
- spring相关的
- aop织入
- mybatis-spring 【new]
⒉编写配置文件
3.测试
9.2回忆mybatis
1.编写实体类
2.编写核心配置文件
3.编写接口
4.编写Mapper.xml
5.测试
10.整合Mybatis-Spring
1.创建mybatis内容
1.1User实体类
@Data
public class User {
private int id;
private String username;
private String password;
private int age;
private String sex;
private String email;
}
1.2mybatis-config.xml
<configuration>
<!-- <!–引入properties-->
<properties resource="jdbc.properties"/>
<!--类型别名-->
<typeAliases>
<package name="com.kaiyu.mybatis.pojo"/>
</typeAliases>
</configuration>
1.3 jdbc.properties
jdbc.Driver = com.mysql.cj.jdbc.Driver
jdbc.url = jdbc:mysql://localhost:3306/mybatis
jdbc.username = root
jdbc.password = root
1.4 UserMapper 接口
public interface UserMapper {
List<User> selectAll();
}
1.5UserMapper.xml
<mapper namespace="com.kaiyu.mybatis.mapper.UserMapper">
<!--List<User> selectAll();-->
<select id="selectAll" resultType="User">
select *
from mybatis.user;
</select>
</mapper>
1.6 applicationContext.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"
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">
<context:component-scan base-package="com.kaiyu"></context:component-scan>
<context:annotation-config></context:annotation-config>
<!--引入jdbc配置文件-->
<context:property-placeholder location="classpath:jdbc.properties"></context:property-placeholder>
<!--DataSource 使用spring的数据源来替代mybatis配置-->
<bean class="com.alibaba.druid.pool.DruidDataSource" id="dataSource">
<property name="driverClassName" value="${jdbc.driver}"></property>
<property name="url" value="${jdbc.url}"></property>
<property name="username" value="${jdbc.username}"></property>
<property name="password" value="${jdbc.password}"></property>
</bean>
<!--SqlSessionFactoryBean-->
<bean class="org.mybatis.spring.SqlSessionFactoryBean" id="sqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"></property>
<!--绑定mybatis-->
<property name="configLocation" value="classpath:mybatis-config.xml"></property>
<!--mapper-->
<property name="mapperLocations" value="com/kaiyu/mybatis/mapper/UserMapper.xml"></property>
</bean>
<!--SqlSessionTemplate:就是我们使用的sqlSession-->
<bean class="org.mybatis.spring.SqlSessionTemplate" id="sqlSession">
<!--只能使用构造器注入 因为没有set方法-->
<constructor-arg index="0" ref="sqlSessionFactoryBean"/>
</bean>
<bean class="com.kaiyu.mybatis.mapper.UserMapperImpl">
<property name="sqlSession" ref="sqlSession"></property>
</bean>
</beans>
1.7UserMapperImpl 实现接口类
@Repository("userMapper")
public class UserMapperImpl implements UserMapper {
//我们的所有操作 都是用sqlSession来执行在原来 现在都是用sqlSessionTemplate
private SqlSessionTemplate sqlSession;
public UserMapperImpl(SqlSessionTemplate sqlSession) {
this.sqlSession = sqlSession;
}
@Override
public List<User> selectAll() {
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
return mapper.selectAll();
}
public void setSqlSession(SqlSessionTemplate sqlSession) {
this.sqlSession = sqlSession;
}
public SqlSessionTemplate getSqlSession() {
return sqlSession;
}
}
1.8 测试类
@Test
public void test1(){
ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
UserMapper userMapper = app.getBean("userMapper", UserMapper.class);
for (User user : userMapper.selectAll()) {
System.out.println(user);
}
}
11.声明事物
1、回顾事务
- ·把一组业务当成一个业务来做;要么都成功,要么都失败!
- ·事务在项目开发中,十分的重要,涉及到数据的一致性问题,不能马虎!
- 确保完整性和一致性;
2.事务ACID原则:
- 原子性。
- 一致性·
- 隔离性
- 多个业务可能操作同一个资源,防止数据损坏
- ·持久性
- 事务一旦提交,无论系统发生什么问题,结果都不会再被影响,被持久化的写到存储器中!

浙公网安备 33010602011771号