SSM - Spring - Concepts
1. Spring 简介
2002年,推出 interface21框架;Spring框架雏形基于interface21框架,于2004年发布 by Rod Johnson (音乐学博士)。
Spring是一个开源免费的框架/容器;轻量级的、非入侵式的框架;控制反转(IoC) 面向切面(AOP)。其有七大组件构成.
Spring下载路径:
- Spring 各个版本下路径:@ https://repo.spring.io/ui/native/release/org/springframework/spring
- Spring GitHub源代码下载路径: @ GitHub - spring-projects/spring-framework: Spring Framework
SSH&SSM:
- SSH: Structs + Sping + Hibernate
- SSM: Spring MVC + Spring + Mybatis
依赖包: Spring Web MVC, (必须是5.3.xx或者更低版本,6.xx系列需要JDK17) Spring JDBC (必须是5.3.xx版本,6.xx系列需要JDK17)
<!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.3.28</version> </dependency>
AOP 依赖
<!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver --> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.9.19</version> <scope>runtime</scope> </dependency>
Spring JDBC依赖
<!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>5.3.29</version> </dependency>
2. IOC 控制反转
通过用于的set设置调用的最终接口,从而实现用户控制(控制反转到用户这边)
- 控制:谁来控制对象的创建,传统引用程序的对象是有程序本身控制创建的,使用Spring后,对象是由Spring来创建的。
- 反转:程序本身不创建对象,而变成被动的接收对象
- 依赖注入:就是利用set方法来进行注入的
IOC是一种编程思想,由主动的编程变成被动的接收。我们彻底不用在程序中去改动了,要实现不同的操作,只需要在xml配置文件中进行修改。
所谓的IOC,一句话就是:对象由Spring来创建、管理、装配。
IoC创建对象的方式
- 默认使用无参构造创建对象;如果通过有参构造,有三种方式(下标赋值、类型赋值、直接参数名赋值)
3. Spring 配置
别名、配置、导入
<!--name 也是别名,而且更加高级--> <bean id="usert" class="com.crevew.pojo.UserT" name="usertAlias别名 usertAlias别名2, usertAlias别名3"/> <alias name="user" alias="userAlias别名"/>
4. DI 依赖注入
DI注入有三种方式,分别是:构造器,set,p/c标签
4.1 构造器注入
等同于上述的 “IoC创建对象的方式”
4.2 Set方式注入(重点)
- 依赖:bean对象的创建依赖于容器
- 注入:bean对象中的所有属性,由容器来注入
<bean id="student" class="com.crevew.pojo.Student"> <!--<property name="name" value="zjfun"/>--> <!--1. 下标赋值--> <!--<constructor-arg index="0" value="zjfun1"/>--> <!--2. 类型赋值--> <!--<constructor-arg type="java.lang.String" value="zjfun2"/>--> <!--3. 直接通过参数名--> <!--第一种:普通值注入--> <property name="name" value="zjfun"/> <!--第二种:Bean注入--> <property name="address" ref="address"/> <!--第三种:数组注入--> <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="123123123123"/> <entry key="银行卡" value="111111111111"/> </map> </property> <!--Set注入--> <property name="games"> <set> <value>LOL</value> <value>COC</value> <value>BOB</value> </set> </property> <!--NULL注入--> <property name="wife"> <null/> </property> <!--Properties注入--> <property name="info"> <props> <prop key="学号">04970314</prop> <prop key="性别">男</prop> <prop key="姓名">曳明</prop> </props> </property> </bean>
4.3 扩展方式注入
可以使用p (property)命名空间 (等同于set注入)和c (contructor)命名空间 (等同于constructor-arg)实现注入。
<?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命名空间注入,可以直接注入属性的值:Property--> <bean id="user" class="com.crevew.pojo.User" p:name="ZZZ" p:age="18"/> <!--c命名空间注入,通过构造器注入: construct-args --> <bean id="user2" class="com.crevew.pojo.User" c:age="19" c:name="JJJ"/> </beans>
4.4 bean的作用域
Scope | Description |
---|---|
(Default) Scopes a single bean definition to a single object instance for each Spring IoC container. |
|
Scopes a single bean definition to any number of object instances. |
|
Scopes a single bean definition to the lifecycle of a single HTTP request. That is, each HTTP request has its own instance of a bean created off the back of a single bean definition. Only valid in the context of a web-aware Spring |
|
Scopes a single bean definition to the lifecycle of an HTTP |
|
Scopes a single bean definition to the lifecycle of a |
|
Scopes a single bean definition to the lifecycle of a |
单例模式: 默认
原型模式: 每次从容器中get的时候,产生一个新的对象
其余的request,session, application,这些只是在web开发中使用
<bean id="user2" class="com.crevew.pojo.User" c:age="18" c:name="ZZZ" scope="prototype"/>
5. bean的自动装配
自动装配是Spring满足bean依赖一种方式
Spring会在上下文中自动寻找,并自动给bean装配属性
在Spring中有三种装配的方式:
1. 在xml中显式的配置
2. 在java中显式配置
3. 隐式的自动装配bean【重要】,隐式有三种:
5.1 byName
需要保证所有bean的id唯一,并且这个bean需要和自动注入的属性的set方法一致
<!--byName: 会自动在容器上下文中查找,和自己对象set方法后面的值对应的beanid byType: 会自动在容器上下文中查找,和自己对象类型相同的bean--> <bean id="cat" class="com.crevew.pojo.Cat"/> <bean id="dog" class="com.crevew.pojo.Dog"/> <bean id="people" class="com.crevew.pojo.People" autowire="byName"> <property name="name" value="ZJ"/> </bean>
5.2 byType
需要保证所有bean的class唯一,并且这个bean需要和自动注入的属性类型一致
<bean class="com.crevew.pojo.Cat"/> <bean class="com.crevew.pojo.Dog"/> <bean id="people" class="com.crevew.pojo.People" autowire="byType"> <property name="name" value="ZJ"/> </bean>
5.3 注解 annotation
导入约束 , 且 配置注解的支持
<?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 https://www.springframework.org/schema/beans/spring-beans.xsd"> <context:annotation-config/>
</beans>
@Autowired直接在属性上使用即可,也可以在set方法上使用!Autowired相当于“byName”和“byType”的综合体。
使用Autowired我们可以不用编写Set方法了,前提是你这个自动装配的属性在IOC(Spring)容器中存在,且符合名字byName。
科普一:
@Nullable,字段标记了这个注解,
@Autowired (required=false)如果显式定义了autowired的required属性为false,说明这个对象可以为null,否则不允许为null
@Quailifer(value="xxx")显式引用多个
<bean id="cat" class="com.crevew.pojo.Cat"/> <bean id="dog" class="com.crevew.pojo.Dog"/> <bean id="dog2" class="com.crevew.pojo.Dog"/> <bean id="people" class="com.crevew.pojo.People"/>
//如果显式定义了autowired的required属性为false,说明这个对象可以为null,否则不允许为null
@Autowired(required=false)
private Cat cat;
@Autowired
@Qualifier(value="dog2")
private Dog dog;
科普二:
@Resource 是Java原生的,和@Autowired功能类似都用来自动装配,放在属性上。
@Resource
private Cat cat;
@Resource(name="dog2")
private Dog dog;
默认:@Autowired通过byType方式实现;@Resource通过byName方式实现。
6. 注解开发
在Spring4之后,使用注解开发,必须导入aop jar包 (已经被包含在MVC jar包中了)。
6.1. 配置
<!--指定要扫描的包,这个包下的注解就会生效--> <context:component-scan base-package="com.crevew"/> <!--开启注解的支持--> <context:annotation-config/>
6.2. 属性如何注入
//等价于<bean id="user" class="com.crevew.pojo.User" //@Component 组件 @Component public class User { //相当于 <property name="name" value="zjfun"/> @Value("zjfun") public String name; }
6.3. 衍生的注解
@Component有几个衍生注解,我们在web开发中,按照MVC三层架构分层。
dao ---> @Reponsitory
service ---> @Service
controller ---> @Controller
这四个注解功能都是一样的,都是代表某个类注册到Spring中,装配Bean
6.4. 自动装配配置
@Autowired
@Resource
6.5. 作用域
@Component @Scope("singleton") public class User { //相当于 <property name="name" value="zjfun"/> @Value("zjfun") public String name; }
6.6. 小结
XML与注解
- XML更加万能,适合任何场合
- 注解不是自己的类使用不了,维护相对复杂
最佳实践:
- xml管理bean
- 注解只负责完成属性的注入
- 我们在使用的过程中,只需要注意一个问题,必须要注解生效,就需要开启注解的支持
6.7 总结
@Autowired:自动装配(通过类型、名字);如果不能唯一匹配,通过@Qualifier (name=“xxx”)指定
@Nullable:字段如果标记了这个注解,说明这个字段可以为null;
@Resource:自动装配,通过名字、类型
@Component:组件,放在类上,说明这个类自动被注册到Spring中。
@Service @Controller @Reponsitory
7. JavaConfig
我们现在完全不再使用Spring的xml配置了,全权交给Java来做。
JavaConfig是Spring的一个子项目,在Spring4之后,它成为了一个核心功能。
@Configuration //这个也会被Spring容器托管,注册到容器中,因为它本来也是一个component //@Configuration代表这是一个配置类,和之前的beans.xml是一个意思 @ComponentScan("com.crevew") @Import(CrevewConfig2.class) public class CrevewConfig { //注册一个bean,就相当于我们之前写的一个bean标签 //这个方法的名字,就相当于bean标签中的id属性 //这个方法的返回值,就相当于bean标签中的class属性 @Bean public User getUser() { return new User(); // 就是返回要注入到bean的对象 } }
8. 代理模式
代理模式的分类:
- 静态代理
- 动态代理
8.1 静态代理
角色分析:
- 抽象角色:一般会使用接口或者抽象类来解决
- 真实角色:被代理的角色
- 代理角色:代理真实橘色,代理真实角色后,我们一般会做一些附属操作
- 客户:访问代理对象的人
代理模式的好处:
- 可以使真实角色的操作更加纯粹,不用关系公共的业务
- 公共也就交给了代理角色,实现了业务的分工
- 公共业务发生扩展的时候,方便集中管理
缺点:
- 一个真实角色就会产生一个代理角色,代码量会翻倍,开发效率会变低
8.2 加深理解
8.3 动态代理
动态代理和静态代理角色是一样的。
- 动态代理的代理类是动态生成的,不是我们直接写好的。
动态代理分为两大类:基于接口的动态代理,基于类的动态代理。
- 基于接口---JDK动态代理 [我们在这里使用的方式]
- 基于类---cglib
- java字节码实现---JAVAssist
需要了解两个类:Proxy (代理), InvocationHandler(调用处理程序)
动态代理的好处:
- 包括静态代理的全部好处
- 一般动态代理类代理的是一个接口,一般就是对应的一类业务
- 一个动态代理类可以代理多个类,只要是实现了同一个接口即可
9. AOP (Aspect Oriented Programming)
AOP (Aspect Oriented Programming) 面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。AOP是OOP的延续。
AOP提供声明式事务;允许用户自定义切面。一共有三种方式:
方式一:使用Spring的API接口【主要是SpringAPI接口实现】
<?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: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:component-scan base-package="com.crevew"/> <!--开启注解的支持--> <context:annotation-config/> <!-- 显式注册bean--> <bean id="userService" class="com.crevew.service.UserServiceImpl"/> <bean id="log" class="com.crevew.log.Log"/> <bean id="afterLog" class="com.crevew.log.AfterLog"/> <!-- 方式一:使用原生Spring API接口--> <!--配置aop:需要导入aop的约束--> <aop:config> <!-- 切入点:expression 表达式, execution(要执行的位置!* * * * * )--> <aop:pointcut id="pointcut" expression="execution(* com.crevew.service.UserServiceImpl.*(..))"/> <!-- 执行环绕增加--> <aop:advisor advice-ref="log" pointcut-ref="pointcut"/> <aop:advisor advice-ref="afterLog" pointcut-ref="pointcut"/> </aop:config> </beans>
方式二:使用自定义来实现AOP 【主要是切面定义】---推荐
<?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: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:component-scan base-package="com.crevew"/> <!--开启注解的支持--> <context:annotation-config/> <!-- 显式注册bean--> <bean id="userService" class="com.crevew.service.UserServiceImpl"/> <bean id="log" class="com.crevew.log.Log"/> <bean id="afterLog" class="com.crevew.log.AfterLog"/> <!-- 方式一:使用原生Spring API接口--> <!--配置aop:需要导入aop的约束--> <aop:config> <!-- 切入点:expression 表达式, execution(要执行的位置!* * * * * )--> <aop:pointcut id="pointcut" expression="execution(* com.crevew.service.UserServiceImpl.*(..))"/> <!-- 执行环绕增加--> <aop:advisor advice-ref="log" pointcut-ref="pointcut"/> <aop:advisor advice-ref="afterLog" pointcut-ref="pointcut"/> </aop:config> <!-- 方式二: 自定义切面--> <bean id="diy" class="com.crevew.diy.DiyPointCut"/> <aop:config> <!-- 自定义切面,ref要引用的类--> <aop:aspect ref="diy"> <!-- 切入点--> <aop:pointcut id="point" expression="execution(* com.crevew.service.UserServiceImpl.*(..))"/> <!-- 通知--> <aop:before method="before" pointcut-ref="point"/> <aop:after method="after" pointcut-ref="point"/> </aop:aspect> </aop:config> </beans>
方式三:使用注解实现
<?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: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:component-scan base-package="com.crevew"/> <!--开启注解的支持--> <context:annotation-config/> <!-- 显式注册bean--> <bean id="userService" class="com.crevew.service.UserServiceImpl"/> <bean id="log" class="com.crevew.log.Log"/> <bean id="afterLog" class="com.crevew.log.AfterLog"/> <!-- 方式一:使用原生Spring API接口--> <!--配置aop:需要导入aop的约束--> <aop:config> <!-- 切入点:expression 表达式, execution(要执行的位置!* * * * * )--> <aop:pointcut id="pointcut" expression="execution(* com.crevew.service.UserServiceImpl.*(..))"/> <!-- 执行环绕增加--> <aop:advisor advice-ref="log" pointcut-ref="pointcut"/> <aop:advisor advice-ref="afterLog" pointcut-ref="pointcut"/> </aop:config> <!-- 方式二: 自定义切面--> <bean id="diy" class="com.crevew.diy.DiyPointCut"/> <aop:config> <!-- 自定义切面,ref要引用的类--> <aop:aspect ref="diy"> <!-- 切入点--> <aop:pointcut id="point" expression="execution(* com.crevew.service.UserServiceImpl.*(..))"/> <!-- 通知--> <aop:before method="before" pointcut-ref="point"/> <aop:after method="after" pointcut-ref="point"/> </aop:aspect> </aop:config> <!-- 方式三:通过annotation注解实现--> <bean id="annotationPointCut" class="com.crevew.diy.AnnotationPointCut"/> <!-- 开启注解支持--> <aop:aspectj-autoproxy/> </beans>
调试输出如下:
D:\environ\Java\jdk1.8.0_202\bin\java.exe "-javaagent:D:\environ\JetBrains\IntelliJ IDEA 2023.1.3\lib\idea_rt.jar=3391:D:\environ\JetBrains\IntelliJ IDEA 2023.1.3\bin" -Dfile.encoding=UTF-8 -classpath D:\environ\Java\jdk1.8.0_202\jre\lib\charsets.jar;D:\environ\Java\jdk1.8.0_202\jre\lib\deploy.jar;D:\environ\Java\jdk1.8.0_202\jre\lib\ext\access-bridge-64.jar;D:\environ\Java\jdk1.8.0_202\jre\lib\ext\cldrdata.jar;D:\environ\Java\jdk1.8.0_202\jre\lib\ext\dnsns.jar;D:\environ\Java\jdk1.8.0_202\jre\lib\ext\jaccess.jar;D:\environ\Java\jdk1.8.0_202\jre\lib\ext\jfxrt.jar;D:\environ\Java\jdk1.8.0_202\jre\lib\ext\localedata.jar;D:\environ\Java\jdk1.8.0_202\jre\lib\ext\nashorn.jar;D:\environ\Java\jdk1.8.0_202\jre\lib\ext\sunec.jar;D:\environ\Java\jdk1.8.0_202\jre\lib\ext\sunjce_provider.jar;D:\environ\Java\jdk1.8.0_202\jre\lib\ext\sunmscapi.jar;D:\environ\Java\jdk1.8.0_202\jre\lib\ext\sunpkcs11.jar;D:\environ\Java\jdk1.8.0_202\jre\lib\ext\zipfs.jar;D:\environ\Java\jdk1.8.0_202\jre\lib\javaws.jar;D:\environ\Java\jdk1.8.0_202\jre\lib\jce.jar;D:\environ\Java\jdk1.8.0_202\jre\lib\jfr.jar;D:\environ\Java\jdk1.8.0_202\jre\lib\jfxswt.jar;D:\environ\Java\jdk1.8.0_202\jre\lib\jsse.jar;D:\environ\Java\jdk1.8.0_202\jre\lib\management-agent.jar;D:\environ\Java\jdk1.8.0_202\jre\lib\plugin.jar;D:\environ\Java\jdk1.8.0_202\jre\lib\resources.jar;D:\environ\Java\jdk1.8.0_202\jre\lib\rt.jar;D:\code\project\JavaEE\SSM\Spring\spring-09-aop\target\test-classes;D:\code\project\JavaEE\SSM\Spring\spring-09-aop\target\classes;D:\environ\apache-maven-3.9.3\maven-repo\junit\junit\3.8.1\junit-3.8.1.jar;D:\environ\apache-maven-3.9.3\maven-repo\org\springframework\spring-context\5.3.28\spring-context-5.3.28.jar;D:\environ\apache-maven-3.9.3\maven-repo\org\springframework\spring-aop\5.3.28\spring-aop-5.3.28.jar;D:\environ\apache-maven-3.9.3\maven-repo\org\springframework\spring-beans\5.3.28\spring-beans-5.3.28.jar;D:\environ\apache-maven-3.9.3\maven-repo\org\springframework\spring-core\5.3.28\spring-core-5.3.28.jar;D:\environ\apache-maven-3.9.3\maven-repo\org\springframework\spring-jcl\5.3.28\spring-jcl-5.3.28.jar;D:\environ\apache-maven-3.9.3\maven-repo\org\springframework\spring-expression\5.3.28\spring-expression-5.3.28.jar;D:\environ\apache-maven-3.9.3\maven-repo\org\aspectj\aspectjweaver\1.9.19\aspectjweaver-1.9.19.jar;D:\environ\apache-maven-3.9.3\maven-repo\org\springframework\spring-webmvc\5.3.28\spring-webmvc-5.3.28.jar;D:\environ\apache-maven-3.9.3\maven-repo\org\springframework\spring-web\5.3.28\spring-web-5.3.28.jar;D:\environ\apache-maven-3.9.3\maven-repo\org\junit\jupiter\junit-jupiter-api\5.9.3\junit-jupiter-api-5.9.3.jar;D:\environ\apache-maven-3.9.3\maven-repo\org\opentest4j\opentest4j\1.2.0\opentest4j-1.2.0.jar;D:\environ\apache-maven-3.9.3\maven-repo\org\junit\platform\junit-platform-commons\1.9.3\junit-platform-commons-1.9.3.jar;D:\environ\apache-maven-3.9.3\maven-repo\org\apiguardian\apiguardian-api\1.1.2\apiguardian-api-1.1.2.jar com.crevew.MyTest
方法一:com.crevew.service.UserServiceImpl 的 add 将会被执行
===========方法二:自定方法执行前===========
--------方法三:annotation 方法环绕around前----------
--------方法三:annotation 方法执行前-----------
增加了一个用户
--------方法三:annotation 方法执行后-----------
--------方法三:annotation 方法环绕around后----------
签名是: void com.crevew.service.UserService.add()
============方法二:自定义方法执行后============
方法一:已经执行了 add 返回结果为:null
10. 整合Mybatis
导入jar包,包括:junit, mysql (8.0.33),mybatis(3.5.13), spring-web mvc (5.3.28, 因为JDK1.8不支持6.0+), spring JDBC (5.3.29, 因为Spring的原因不支持6.0+) , aop (1.9.19), mybatis-spring(2.1.1, 因为Spring的原因不支持3.0+), lombok(1.18.28)

<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/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>com.crevew</groupId> <artifactId>Spring</artifactId> <version>1.0-SNAPSHOT</version> </parent> <artifactId>spring-10-mybatis</artifactId> <packaging>jar</packaging> <name>spring-10-mybatis</name> <url>http://maven.apache.org</url> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <dependencies> <!--UNIT Testing: junit--> <!-- https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter-api --> <dependency> <groupId>org.junit.jupiter</groupId> <artifactId>junit-jupiter-api</artifactId> <version>5.9.3</version> </dependency> <!--MySQL--> <!-- https://mvnrepository.com/artifact/com.mysql/mysql-connector-j --> <dependency> <groupId>com.mysql</groupId> <artifactId>mysql-connector-j</artifactId> <version>8.0.33</version> </dependency> <!--MyBatis--> <!-- https://mvnrepository.com/artifact/org.mybatis/mybatis --> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.5.13</version> </dependency> <!--Spring, Spring MVC--> <!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.3.28</version> </dependency> <!--Spring, JDBC--> <!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>5.3.29</version> </dependency> <!--Spring, AOP--> <!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver --> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.9.19</version> <scope>runtime</scope> </dependency> <!--Spring, Mybatis--> <!-- https://mvnrepository.com/artifact/org.mybatis/mybatis-spring --> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>2.1.1</version> </dependency> <!-- https://mvnrepository.com/artifact/org.projectlombok/lombok --> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.28</version> <scope>provided</scope> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.3.28</version> <scope>test</scope> </dependency> </dependencies> <build> <!--配置打包时不过滤非java文件开始 --> <!--说明,在进行模块化开发打jar包时,maven会将非java文件过滤掉, xml,properties配置文件等,但是这些文件又是必需的, 使用此配置可以在打包时将不会过滤这些必需的配置文件。 --> <resources> <resource> <directory>src/main/java</directory> <includes> <include>**/*.properties</include> <include>**/*.xml</include> </includes> <filtering>true</filtering> </resource> <resource> <directory>src/main/resources</directory> <includes> <include>**/*.properties</include> <include>**/*.xml</include> </includes> <filtering>true</filtering> </resource> </resources> </build> </project>
回忆Mybatis:编写实体类,编写核心配置文件、编写接口,编写Mapper.xml, 测试
有两种整合Mybatis的方法
11. 声明式事务
Spring支持两种事务:
- 声明式事务
- 编程式事务
建议一般都使用声明式事务
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧