1Spring
1.1简介
- Spring:春天
- 在各个层面提供选择。Spring允许您尽可能推迟设计决策。 例如,您可以通过配置切换持久性提供程序,而无需更改 你的代码对于许多其他基础设施关注点和与 第三方API。
- 容纳不同的观点。春天拥抱灵活,不固执己见 事情应该怎么做它支持广泛的应用需求 不同的视角。
- 保持强大的向后兼容性。Spring的进化经过精心管理 以在版本之间强制进行少量破坏性更改。Spring支持精心选择的范围 JDK版本和第三方库,以促进应用程序的维护和 依赖Spring的库。
- 关注API设计。Spring团队花了很多心思和时间来制作API 这些都是直观的,并且在许多版本和许多年中都能保持。
- 为代码质量设定高标准。Spring框架强调 有意义的、最新的和准确的javadoc。这是为数不多的项目之一,可以索赔 干净的代码结构,包之间没有循环依赖关系。
- SSM:SpringMvc + Spring + Mybatis
官网: https://springio/projects/spring-framework#overview
官方下载地址: http://repo.spring.io/release/org/springframework/spring
依赖maven导包
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.2.0.RELEASE</version>
</dependency>
1.2优点
- Spring是一个开源的免费框架
- Spring是一个轻量级的非入侵的框架
- 控制反转(IOC),面向切面编程(AOP)
- 支持事务的处理,对框架整合的支持
1.3组成
1.4拓展
- Spring Boot
- 快速开发的脚手架
- 基于SpringBoot快速开发单个微服务
- 约定大于配置
- Spring Cloud
- SpringCloud是基于SpringBoot实现的
大多数公司使用SpringBoot进行快速开发,学习SpringBoot的前提,学习SpringMvc
弊端:发展了太久,配置十分繁琐,人称“配置地狱”
2 IOC理论推导
public class UserServiceImpl implements UserService{
private UserDao userDao;
//利用set进行动态实现值的
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
@Override
public void getUser() {
userDao.getUser();
}
}
程序员不用管理对象的创建。系统得耦合性降低,可以专注业务的实现。这是IOC的原型
3 HelloSpring IOC应用
对象由Spring创建配置和管理
1类定义
package com.ren.pojo;
import lombok.Data;
@Data
public class Hello {
private String str;
@Override
public String toString() {
return "Hello{" +
"str='" + str + '\'' +
'}';
}
public String getStr() {
return str;
}
public void setStr(String str) {
this.str = str;
}
}
2为Spring配置创建对象
<?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
https://www.springframework.org/schema/beans/spring-beans.xsd">
<!--使用Spring来创建对象-->
<bean id="hello" class="com.ren.pojo.Hello">
<property name="str" value="Spring"/>
</bean>
</beans>
3从SPring获得对象并应用
import com.ren.pojo.Hello;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MyTest {
public static void main(String[] args) {
//获取Spring的上下文对象
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
//我们的对象现在都在Spring中管理了,我们要使用,直接去里面取就可以了
Hello hello = (Hello) context.getBean("hello");
System.out.println(hello.toString());
}
}
4 IOC创建对象的方式
1使用无参构造创建对象,默认
2使用有参构造创建
- 下标有参构造赋值:
<bean id="user" class="com.ren.pojo.User">
<!-- <property name="name" value="wei"/>-->
<constructor-arg index="0" value="大人说"/>
</bean>
- 类型匹配传参:不建议使用,同一个类型的两个参数不能处理
<bean id="user" class="com.ren.pojo.User">
<constructor-arg type="java.lang.String" value="张三"/>
</bean>
- 参数名称:重点推荐
<bean id="user" class="com.ren.pojo.User">
<constructor-arg name="name" value="李四"/>
</bean>
总结:Spring容器加载,其内部的对象就被创建了。
5 Spring配置
5.1 别名
<alias name="user" alias="user2"/>
5.2 Bean的配置
<bean id="user" class="com.ren.pojo.User">
<constructor-arg name="name" value="李四"/>
</bean>
5.3 Import
一般用于团队开发使用,把多个
<?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
https://www.springframework.org/schema/beans/spring-beans.xsd">
<import resource="beans.xml"/>
</beans>
6 依赖注入
6.1 构造器注入
6.2 Set方式注入
-
依赖注入 set
- 依赖:容器
- 属性,容器注入
环境搭建
1复杂类型
package com.ren.pojo;
public class Address {
private String address;
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
2真实测试对象
package com.ren.pojo;
import java.util.*;
public class Student {
private String name;
private Address address;
private String[] books;
private List<String> hobbies;
private Map<String,String> card;
private Set<String> games;
private Properties info;
}
3beans
<?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
https://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="student" class="com.ren.pojo.Student">
<!-- 第一种:普通值注入-->
<property name="name" value="任宪伟"/>
</bean>
</beans>
4测试类
public class MyTest {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
Student student = (Student)context.getBean("student");
System.out.println(student.getAddress());
}
}
完善注入信息xml
<bean id="address" class="com.ren.pojo.Address" >
<property name="address" value="青岛"/>
</bean>
<bean id="student" class="com.ren.pojo.Student">
<!-- 第一种:普通值注入-->
<property name="name" value="任宪伟"/>
<!-- 第2种:bean注入(引用对象注入?)-->
<property name="address" ref="address"/>
<!-- 第3种:数组注入)-->
<property name="books">
<array>
<value>红楼梦</value>
<value>西游记</value>
<value>水浒传</value>
<value>三国演义</value>
</array>
</property>
<!-- 第4种:List注入)-->
<property name="hobbies">
<list>
<value>听歌</value>
<value>看电影</value>
<value>写代码</value>
</list>
</property>
<!-- 第5种:Map注入)-->
<property name="card">
<map>
<entry key="身份证" value="37028419880839"/>
<entry key="银行卡" value="12453464473775"/>
</map>
</property>
<!-- 第6种:Set注入)-->
<property name="games">
<set>
<value>LOL</value>
<value>COC</value>
<value>BOB</value>
</set>
</property>
<!-- 第7种:null注入)-->
<property name="wife" >
<null></null>
</property>
<!-- 第8种:props注入)-->
<property name="info" >
<props>
<prop key="driver">20190525</prop>
<prop key="url">20190525</prop>
<prop key="username">root</prop>
<prop key="password">123456</prop>
</props>
</property>
</bean>
完善测试类
public class MyTest {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
Student student = (Student)context.getBean("student");
// System.out.println(student.getAddress());
System.out.println(student.toString());
/*Student{
name='任宪伟',
address=Address{address='青岛'},
books=[红楼梦, 西游记, 水浒传, 三国演义],
hobbies=[听歌, 看电影, 写代码],
card={身份证=37028419880839, 银行卡=12453464473775},
games=[LOL, COC, BOB],
wife='null',
info={password=123456,
url=20190525,
driver=20190525,
username=root}}*/
}
}
6.3 拓展
可以使用p或者c命名空间进行注入
<?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命名空间 xmlns:p="http://www.springframework.org/schema/p"-->
<!--引入c命名空间 xmlns:c="http://www.springframework.org/schema/c"-->
<!--p命名空间注入,可以直接注入属性的值-->
<bean id="user" class="com.ren.pojo.User" p:name="张展" p:aeg="13"/>
<!-- c命名空间注入,通过构造器注入-->
<bean id="user2" class="com.ren.pojo.User" c:age="18" c:name="大神"/>
</beans>
测试:
@Test
public void test2(){
ApplicationContext context = new ClassPathXmlApplicationContext("userbeans.xml");
User user = context.getBean("user", User.class);
User user2 = context.getBean("user2", User.class);
System.out.println(user.toString());
System.out.println(user2.toString());
}
注意点:需要先引入命名空间
xmlns:p="http://www.springframework.org/schema/p"
xmlns:c="http://www.springframework.org/schema/c"
6.4 bean的作用域
1单例模式,默认的模式
2原型模式:每次产生一个新对象
<bean id="accountService" class="com.something.DefaultAccountService" scope="prototype"/>
3其余的request、session、application只能在web开发中使用
7 Bean的自动装配
- 自动装配是Spring满足bean的一种方式
三种装配方式:
1 在xml中显示配置
2 在java中显示配置
3 隐式的自动装配(重要)
7.1 自动装配
1环境搭建: 一个人两个动物
7.2 ByName
<?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
https://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="cat" class="com.ren.pojo.Cat"/>
<bean id="dog" class="com.ren.pojo.Dog"/>
<bean id="person" class="com.ren.pojo.People" autowire="byName">
<property name="name" value="大神"/>
<!-- <property name="cat" ref="cat"/>-->
<!-- <property name="dog" ref="dog"/>-->
</bean>
</beans>
7.3 byType
<!--
byName:会自动在容器上下文中查找,和自己对象set方法后面的值对应的beanid
byType:会自动在容器上下文中查找,和自己对象属性类型相同的bean
-->
<bean id="person" class="com.ren.pojo.People" autowire="byName">
<property name="name" value="大神"/>
<!-- <property name="cat" ref="cat"/>-->
<!-- <property name="dog" ref="dog"/>-->
</bean>
小结:
byName:id唯一
byType:类型唯一
7.4 使用注解实现自动装配
The introduction of annotation-based configuration raised the question of whether this approach is “better” than XML. The short answer is “it depends.”
使用注解须知:
1导入约束
2配置注解的支持
<context:annotation-config/>
注解 @Autowired
可以
public class People {
@Autowired
private Cat cat;
@Autowired
private Dog dog;
<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:aop="http://www.springframework.org/schema/aop"
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
http://www.springframework.org/schema/aop
https://www.springframework.org/schema/aop/spring-aop.xsd">
<context:annotation-config/>
<bean id="cat" class="com.ren.pojo.Cat"/>
<bean id="dog" class="com.ren.pojo.Dog"/>
<bean id="person" class="com.ren.pojo.People">
</bean>
</beans>
使用@Qualifier(value = “cat111”)指定自动装配对象
@Autowired
@Qualifier(value = "cat111")
private Cat cat;
<bean id="cat" class="com.ren.pojo.Cat"/>
<bean id="cat111" class="com.ren.pojo.Cat"/>
@Resource注解
@Resource
private Cat cat;
@Resource
private Dog dog;
小结:
@Resource与@Autowired的区别
- 都可以放属性字段实现自动装配
- @Autowired默认byname方式实现
- @Resource首先byname方式实现,找不到再通过byType类型
- 执行顺序不同
8 使用注解开发
1bean
2属性注入
@Component
public class User {
@Value("wei")
public String name;
}
3衍生的注解
@Component有几个衍生的注解,我们在web开发中,会按照mvc三层架构分层
- dao @Repository
- service @Service
- controller@Controller
这四个功能是一样的,把类注册到Spring中装配
4自动装配
@Autowired
@Resource
@Nullable
5作用域
@Component
@Scope("prototype")
public class User {
@Value("wei")
public String name;
}
6小结
xml更加万能,适用于各种场合
注解只能用于本类,维护相对复杂,不符合解耦的原则,使用更简单一些
功能结合:注解只注入属性
注意:配置开启注解的支持
9 使用java的方式配置Spring
完全不实用Spring的xml配置了,全权交给java来做
JavaConfig是Spring的一个子项目,spring4之后,成为了核心功能
实体类
package com.ren.pojo;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
//注解说明这个类被spring托管
@Component
public class User {
private String name;
public String toString() {
return "User{" +
"name='" + name + '\'' +
'}';
}
public String getName() {
return name;
}
@Value("大神")
public void setName(String name) {
this.name = name;
}
}
配置文件
package com.ren.config;
import com.ren.pojo.User;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
@Configuration
@ComponentScan("com.ren.pojo")
@Import(RenConfig2.class)
public class RenConfig {
@Bean
public User getUser(){
return new User();
}
}
测试:
import com.ren.config.RenConfig;
import com.ren.pojo.User;
import com.sun.deploy.appcontext.AppContext;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class MyTest {
public static void main(String[] args) {
ApplicationContext context = new AnnotationConfigApplicationContext(RenConfig.class);
User user = (User)context.getBean("user");
System.out.println(user.getName());
}
}
10 代理模式AOP
为什么学习代理模式
因为这就是springAOP的底层!
SpringAOP
SpringMVC
代理模式的分类
- 静态代理
- 动态代理
10.1 静态代理
角色分析
- 抽象角色:接口或者抽象类
- 真实角色
- 代理角色:代理真实角色,附加操作
- 客户
代码步骤:
1 接口
package com.ren.demo01;
public interface Rent {
public void rent();
}
2 真实角色
package com.ren.demo01;
public class Host implements Rent{
@Override
public void rent() {
System.out.println("房东要出租房子");
}
}
3 代理角色
package com.ren.demo01;
public class Proxy {
private Host host;
public Proxy() {
}
public Proxy(Host host) {
this.host = host;
}
public void rent(){
seeHouse();
host.rent();
hetong();
fare();
}
public void seeHouse(){
System.out.println("中介带你看房");
}
public void hetong(){
System.out.println("签租赁合同");
}
public void fare(){
System.out.println("收中介费");
}
}
4 客户端访问代理角色
package com.ren.demo01;
public class Client {
public static void main(String[] args) {
Host host = new Host();
//
Proxy proxy = new Proxy(host);
proxy.rent();
}
}
代理模式的好处:
- 真实角色的操作更纯粹
- 公共交给代理
- 方便几种管理
缺点
一个真实角色产生一个代理,代码量翻倍,开发效率变低
10.2 加深了解
一、开闭原则
对扩展开放,对修改关闭。最基础,最重要的一个原则。顾名思义,对一个类允许扩展其功能,但是不能影响到现有的功能模块。对提供方开放,对使用方关闭。
二、单一职责原则
控制类的粒度大小,将对象解耦、提高其内聚性。一个类做好自己的事情,尽量不要与其他类建立联系。一个类中的方法只做一件事情。
三、接口隔离原则
要为各个类建立它们需要的专用接口。不同的类使用同一个接口的部分方法时,应该将每个类对应的方法从接口中抽离出来分别实现。
四、依赖倒置原则
要面向接口编程,不要面向实现编程。高层模块不应该依赖底层模块,二者都依赖其抽象。程序要依赖于抽象接口,不要依赖于具体实现。简单的说就是要求对抽象进行编程,不要对实现进行编程,这样就降低了客户与实现模块间的耦合。
五、里氏替换原则
继承必须确保超类所拥有的性质在子类中仍然成立。超类能出现的地方,可以用子类代替,子类拥有超类的所有属性和方法,通俗来说子类拥有超类的功能,可以拓展超类的功能,但是不能修改超类的功能。
六、迪米特法则
也叫最少知道原则。只与你的直接朋友交谈,不跟“陌生人”说话。两个对象之间有耦合关系,说明对象间是朋友关系。出现在成员变量,方法参数,方法返回值中的类为直接朋友;出现在局部变量中的类就是陌生朋友。
七、合成复用原则
尽量先使用组合或者聚合等关联关系来实现,其次才考虑使用继承关系来实现。判断组合和聚合关系的一个简单方法就是:看整体与部分的生命周期是否一致,部分能够独立于整体而存在则属于聚合;整体消失部分不复存在则属于组合。
10.3 动态代理
- 动态代理和静态代理的角色一样
- 动态代理的类是动态生成的,不是直接写好的
- 动态代理分为两大类:基于接口的动态代理,基于类的动态代理
- 基于接口—JDK动态代理
- 基于类:cglib
- java字节码实现:javasist
需要了解两个类:Proxy 代理, InvocationHandler调用处理程序
动态代理的好处: - 真实角色的操作更纯粹
- 公共交给代理
- 方便几种管理
- 一个动态代理类代理的是一个接口,一般就是对应的一类业务
- 一个动态代理类可以代理多个类,只要是实现了一个接口即可
动态代理工具:
package com.ren.demo04;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
//自动生成代理类
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 {
//动态代理的机制本质,用反射机制实现
log(method.getName());
Object result = method.invoke(target, args);
return result;
}
public void log(String msg){
System.out.println("执行了"+msg+"方法");
}
}
接口类:
package com.ren.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.ren.demo04;
import com.ren.demo02.UserService;
import com.ren.demo02.UserServiceImpl;
public class Client {
public static void main(String[] args) {
UserServiceImpl userService=new UserServiceImpl();
ProxyInvocationHandler handler = new ProxyInvocationHandler();
handler.setTarget(userService);
UserService proxy = (UserService)handler.getProxy();
proxy.delete();
}
}
11 AOP
11.1 什么是AOP
AOP (Aspect Oriented Programming)意为: 面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的羯合度降低,提高程序的可重用性,同时提高了开发的效率。
11.2 Aop在Spring中的作用
提供声明式事务;允许用户自定义切面
横切关注点:跨越应用程序多个模块的方法或功能。即是,与我们业务逻辑无关的,但是我们需要关注的部分,就是横切关注点。如日志,安全,缓存,事务等等 …
。切面(ASPECT): 横切关注点 被模块化 的特殊对象。即,它是一个类
。通知 (Advice): 切面必须要完成的工作。即,它是类中的一个方法
。目标 (Target) : 被通知对象
。代理(Proxy): 向目标对象应用通知之后创建的对象
。切入点 (PintCut) : 切面通知 执行的“地点”的定义
。连接点 (ointPoint) : 与切入点匹配的执行点
11.3 使用Spring实现Aop
使用AOP注入,需要导入一个依赖包
<dependency>
<groupId></groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.4</version>
</dependency>
方式一:使用Spring的API接口(主要是SpringAPI接口来实现)
<!-- 指定要扫描的包,这个包下的注解就会生效-->
<context:component-scan base-package="com.ren"/>
<context:annotation-config/>
<!-- 注册bean-->
<bean id="userService" class="com.ren.service.UserServiceImpl"/>
<bean id="log" class="com.ren.log.Log"/>
<bean id="afterLog" class="com.ren.log.AfterLog"/>
<!-- 方式一:使用原生的SpringAPI接口-->
<!--配置aop:需要导入aop的约束-->
<aop:config>
<!-- 切入点:expression:表达式,execution(要执行的位置) -->
<aop:pointcut id="pointcut" expression="execution(* com.ren.service.UserServiceImpl.*(..))"/>
<!-- 执行环绕增加-->
<aop:advisor advice-ref="log" pointcut-ref="pointcut"/>
<aop:advisor advice-ref="afterLog" pointcut-ref="pointcut"/>
</aop:config>
方式二:自定义来实现AOP(主要是切面定义)
public class DiyPointCut {
public void before(){
System.out.println("============方法执行前=============");
}
public void after(){
System.out.println("============方法执行后=============");
}
}
<!--方式二:自定义类-->
<bean id="diy" class="com.ren.diy.DiyPointCut"/>
<aop:config>
<aop:aspect ref="diy">
<!-- 切入点-->
<aop:pointcut id="point" expression="execution(* com.ren.service.UserServiceImpl.*(..))"/>
<!-- 通知-->
<aop:before method="before" pointcut-ref="point"/>
<aop:after method="after" pointcut-ref="point"/>
</aop:aspect>
</aop:config>
方式三:使用注解实现
注解切面类:
package com.ren.diy;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
//使用注解方式实现AOP
@Aspect//标注这个类是一个切面
public class AnnotationPointCut {
@Before("execution(* com.ren.service.UserServiceImpl.*(..))")
public void before(){
System.out.println("============A方法执行前=============");
}
@After("execution(* com.ren.service.UserServiceImpl.*(..))")
public void after(){
System.out.println("============A方法执行后=============");
}
@Around("execution(* com.ren.service.UserServiceImpl.*(..))")
public void around(ProceedingJoinPoint jp) throws Throwable {
System.out.println("============环绕前=============");
Signature signature = jp.getSignature();//获得签名
System.out.println("signature"+signature);
//执行方法
Object proceed = jp.proceed();
System.out.println(proceed);
System.out.println("============环绕后=============");
}
}
xml配置:
<!--方式三:-->
<bean id="annotationPointCut" class="com.ren.diy.AnnotationPointCut"/>
<!-- 开启注解并支持 -->
<aop:aspectj-autoproxy/>
12 整合Mybatis
1 导入相关jar包
- junit
- mybatis
- mysql数据库
- spring相关的
- AOP织入
- mybatis-spring
2 编写配置文件
3 测试
12.1 回忆Mybatis
1编写实体类
2编写核心配置文件
3编写接口
4编写Mapper.xml
5.测试
12.2 Mybatis-Spring
1 编写数据源
2 sqlSessionFactory
3 sq;SessionTemplate
4 需要给接口加实现类
5 测试
13 声明式事务
- 要么都成功,要么都失败
- 项目开发中十分重要,数据一致性
- 确保完整性和一致性
事务的ACID原则:
- 原子性
- 一致性
- 隔离性
- 持久性
spring中的事务管理
交由容器管理事务
编程式事务管理