Spring
spring 是什么:
- Spring框架是一个开放源代码的J2EE应用程序框架,Spring是Java EE编程领域的一个轻量级开源框架,
- Spring是一个开源容器框架,它集成各类型的工具,通过核心的Bean factory实现了底层的类的实例化和生命周期的管理。
- Spring不仅仅能应用于J2EE应用程序之中,也可以应用于桌面应用程序以及小应用程序之中。Spring框架主要由七部分组成,分别是 Spring Core、 Spring AOP、 Spring ORM、 Spring DAO、Spring Context、 Spring Web和 Spring Web MVC。
spring 要学什么:
简化开发: Spring框架中提供了两个大的核心技术,分别是:
-
1.Spring的简化操作都是基于这两块内容,所以这也是Spring学习中最为重要的两个知识点。
-
2.事务处理属于Spring中AOP的具体应用,可以简化项目中的事务管理,也是Spring技术中的一大亮点。
-
- 事务处理
- IOC
- AOP
-
框架整合: Spring在框架整合这块已经做到了极致,它可以整合市面上几乎所有主流框架,比如:
这些框架中,我们目前只学习了MyBatis,所以在Spring框架的学习中,主要是学习如何整合MyBatis。
综上所述,对于Spring的学习,主要学习四块内容:
(1)IOC,(2)整合Mybatis(IOC的具体应用),(3)AOP,(4)声明式事务(AOP的具体应用)
-
- MyBatis
- MyBatis-plus
- Struts
- Struts2
- Hibernate
- ……
spring 的特点:
- 轻量——从大小与开销两方面而言Spring都是轻量的。完整的Spring框架可以在一个大小只有1MB多的JAR文件里发布。并且Spring所需的处理开销也是微不足道的。此外,Spring是非侵入式的:典型地,Spring应用中的对象不依赖于Spring的特定类。
- 控制反转——Spring通过一种称作控制反转(IoC)的技术促进了低耦合。
- 面向切面——Spring提供了面向切面编程的丰富支持,允许通过分离应用的业务逻辑与系统级服务(例如审计(auditing)和事务(transaction)管理)进行内聚性的开发。应用对象只实现它们应该做的——完成业务逻辑——仅此而已。它们并不负责(甚至是意识)其它的系统级关注点,例如日志或事务支持。
- 容器——Spring包含并管理应用对象的配置和生命周期,在这个意义上它是一种容器,你可以配置你的每个bean如何被创建——基于一个可配置原型(prototype),你的bean可以创建一个单独的实例或者每次需要时都生成一个新的实例——以及它们是如何相互关联的。然而,Spring不应该被混同于传统的重量级的EJB容器,它们经常是庞大与笨重的,难以使用。
- 框架——Spring可以将简单的组件配置、组合成为复杂的应用。在Spring中,应用对象被声明式地组合,典型地是在一个XML文件里。Spring也提供了很多基础功能(事务管理、持久化框架集成等等),将应用逻辑的开发留给了你。
- MVC——Spring的作用是整合,但不仅仅限于整合,Spring 框架可以被看做是一个企业解决方案级别的框架。客户端发送请求,服务器控制器(由DispatcherServlet实现的)完成请求的转发,控制器调用一个用于映射的类HandlerMapping,该类用于将请求映射到对应的处理器来处理请求。
maven导包
<!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.3.23</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.3.23</version>
</dependency>
总结:总结一句话: Spring就是一个轻量级的控制反转(IOC)和面向切面(AOP)编程的框架!
IOC理论推导
IOC是一种编程思想
所谓的IOC就是一句话 对象由Spring来创建,管理,装配
我们彻底不用再程序里面修改,只需要修改配置文件
beans.xml
property 属性 name 如果是基本属性的话 后面的就能直接用value赋值 但是如果是其他的 bean 的类型的话 就需要使用 ref 来引用
<?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="getMySql" class="jer.study.spring.dao.MySqlContext"/>
<bean id="getOracle" class="jer.study.spring.dao.OracleContext"/>
<bean id="getUser" class="jer.study.spring.service.UserServiceImp">
<property name="getUser" ref="getMySql"/>
</bean>
<bean id="hello" class="jer.study.spring.pojo.Hello">
<property name="str" value="Hello Spring"/>
</bean>
</beans>
默认是使用无参构造创建参数
使用有参构造的话有三种方法:
- 使用下标赋值
<bean id="hello" class="jer.study.spring.pojo.Hello">
<constructor-arg index="0" value="Hello Spring"/>
<constructor-arg index="1" value="1"/>
</bean>
- 使用类型赋值(不建议使用,不方便并且如果两个属性是一样的类型不方便赋值)
<bean id="hello" class="jer.study.spring.pojo.Hello">
<constructor-arg type="java.lang.String" value="Hello Spring"/>
<constructor-arg type="int" value="1"/>
</bean>
- 使用直接通过参数名赋值 (建议使用这种)
<bean id="hello" class="jer.study.spring.pojo.Hello">
<constructor-arg name="str" value="Hello Spring"/>
<constructor-arg name="id" value="1"/>
</bean>
在配置文件加载的时候 beans 管理的对象 不管你用不用,他们都已经被实例化,并且获取到的都是同一份对象
配置参数
别名
<alias name="hello" alias="hi"/>
这样的话 id = hello 的bean使用hello 或者 hi 都可以获取到
bean
id :bean 的唯一标识符,相当于Java的对象名
class : bean对象所对应的全限命名
name : 也是别名,并且更高级,能取多个别名,并且能用 ” “, ”,“ ,”;“ 空格 逗号 分号分割都是可以的
import
这个import,一把用于团队开发,可以将多个配置文件导入合并为一个文件
依赖注入(DI)
构造器注入
上面学了
Set注入【重点】
<bean id = "address" class="jer.study.spring.pojo.Address">
<property name="address" value="湖北大学知行学院"/>
</bean>
<bean id="student" class="jer.study.spring.pojo.Student">
<!-- 普通值注入-->
<property name="name" value="曹英杰"/>
<!-- bean值注入-->
<property name="address" ref="address"/>
<!-- 数组注入-->
<property name="books">
<array>
<value>红楼梦</value>
<value>水浒传</value>
<value>西游记</value>
<value>三国演义</value>
</array>
</property>
<!-- list集合注入-->
<property name="hobbies">
<list>
<value>编程</value>
<value>看电影</value>
<value>编程</value>
</list>
</property>
<!-- map注入-->
<property name="card">
<map>
<entry value="林冲" key="豹子头"/>
<entry value="吴用" key="智多星"/>
<entry value="李逵" key="黑旋风"/>
</map>
</property>
<!-- Set集合注入-->
<property name="game">
<set>
<value>张三</value>
<value>李四</value>
<value>张三</value>
</set>
</property>
<!-- null注入-->
<property name="wife">
<null/>
</property>
<!-- properties 注入-->
<property name="info">
<props>
<prop key="myName">ZiYangKing</prop>
<prop key="age">21</prop>
</props>
</property>
</bean>
拓展方式注入
都需要导入xml约束
p:xmlns:p=“http://www.springframework.org/schema/p”
c:xmlns:c=“http://www.springframework.org/schema/c”
p 命名空间注入(property)
类似于简化的Set注入
<bean id="user" class="jer.study.spring.pojo.Student" p:name="王子杨" p:address-ref="address"/>
c 命名空间注入(constructor-arg)
类似与简化的构造器注入
必须有参无参的构造器都存在
<bean id="user" class="jer.study.spring.pojo.Student" c:wife="曹英杰" />
Bean作用域
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-B7BGCshv-1668092192741)(C:\Users\86156\AppData\Roaming\Typora\typora-user-images\image-20221104102315874.png)]
单例模式:singleton (Spring 默认机制)
- 所有人使用的是同一个对象
也可以这样使用
<bean id="hello" class="jer.study.spring.pojo.Hello" scope="singleton">
<constructor-arg name="str" value="Hello Spring"/>
<constructor-arg name="id" value="1"/>
</bean>
原型模式:prototype
- 每个人都有属于自己的对象
<bean id="hello" class="jer.study.spring.pojo.Hello" scope="prototype">
<constructor-arg name="str" value="Hello Spring"/>
<constructor-arg name="id" value="1"/>
</bean>
其余的是在web开发中使用到的和 Servlet 中的 request,session,application类似,websocet
Bean的自动装配
有三种自动装配的方式
搭建环境是:一个人拥有两个宠物,分别是一只猫和一直狗
-
在xml中显示装配
<bean id="cat" class="jer.study.spring.pojo.Cat"/> <bean id="dog" class="jer.study.spring.pojo.Dog"/> <bean id="people" class="jer.study.spring.pojo.People"> <property name="name" value="王子杨"/> <property name="dog" ref="dog"/> <property name="cat" ref="cat"/> </bean>
-
在Java中显示装配
-
隐示的自动装配bean**【重要】**
- byName:是在上下文中查找和Set方法名字一样的bean
<bean id="people" class="jer.study.spring.pojo.People" autowire="byName"> <property name="name" value="王子杨"/> </bean>
- byType:是在上下文中查找和自己对象的bean的类型相同的bean
注解使用自动装配
正式与官方接轨
jdk1.5 Spring2.5开始支持注解
开启注解自动配置要有两步准备工作
-
导入约束
<?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"> </beans>
-
配置注解支持
<!--配置这一句就是开启了注解自动装配--> <context:annotation-config/>
@Autowired @Qualifier
可以写在引用数据上面,也可以放在对应的Set方法头上。
//用这种的话甚至连Set方法都不需要
public class People {
//只要加上这个的话,可以允许这俄格属性为null不会报错
//通常@Autowired 和 @Qualifier匹配和使用
@Autowired(required = false)
@Qualifier(value = "cat")
Cat cat;
@Autowired
Dog dog;
String name;
}
@Autowired
public void setCat(Cat cat) {
this.cat = cat;
}
@Autowired
public void setDog(Dog dog) {
this.dog = dog;
}
有这个图标就说明设置成功了
import javax.annotation.Resource;
@Resoure
这个是java原生注解,功能性会比 @Autowired 强大一点,效率上稍微慢一点点,但是大多数情况下也是使用 @Autowired注解
区别
- @Autowired 是默认是通过 byType 进行分配,然后报错
- @Resoure 是默认是通过byName进行分配,但是如果byName找不到,就会通过byType再找,然后再报错
使用注解开发
使用注解开发必须要保证有这个外部库 aop
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gB7uu4kt-1668092192742)(C:\Users\86156\AppData\Roaming\Typora\typora-user-images\image-20221104215408975.png)]
1.bean
@Component
public class User {
String name;
}
2.属性如何注入
@Component
public class User {
@Value("王子杨")
String name;
}
3.衍生注解
他们四个的作用是一样的,只是为了区分三层架构,对不同层取不同名字,注册到Spring中装配Bean
@Component 【pojo】
- @Repository 【Dao层/Mapper层】
- @Controller 【Controller层】
- @Service 【Service层】
4.作用域
@Scope(“singleton”) //单例模式
@Component
@Scope("singleton")
public class User {
@Value("王子杨")
String name;
}
5.小结
xml与注解:
- xml更加万能,适用于任何场合!维护更加方便
- 注解不是自己的类使用不了,维护相对复杂!
xml与注解最佳实践:
- xml是来管理bean
- 注解只负责完成属性的注入
代理
代理模式的笔记 文件路径 : D:\下载\OneDrive\桌面\idea的学习\第二阶段\javaEE\设计模式\代理模式.md
AOP
1.1什么是AOP
面向切面编程,通过预编译方式和运行期动态代理程序功能的统一维护的一种技术
提供声明式事务;允许用户自定义切面
- 横切关注点:跨越应用程序多个模块的方法或功能。即是与我们业务逻辑无关的,但是我们需要关注的部分,就是横切关注点,如日志,安全,缓存,事务等等
- 切面(Aspect):横切关注点被模块化的特殊对象,比如日志类
- 通知(Adivice):切面必须要完成的工作,他是切面类中的一个方法,比如日志类中的方法
- 目标(Target):被通知对象。一个接口或一个方法
- 代理(Proxy):向目标对象应用通知之后创建的对象。比如生成的代理类
- 切入点(PointCut):切面通知执行的地点的定义,比如invoke方法
- 连接点(JointPoint):与切入点匹配的执行点
1.2 AOP原生代码实现
UserService.java 动态代理实现的接口
public interface UserService {
void add();
void delete();
void insert();
void select();
}
UserServiceImp.java 接口的一种实现类
import org.springframework.stereotype.Service;
@Service
public class UserServiceImp implements UserService{
@Override
public void add() {
System.out.println("执行增加操作");
}
@Override
public void delete() {
System.out.println("执行增加操作");
}
@Override
public void insert() {
System.out.println("执行增加操作");
}
@Override
public void select() {
System.out.println("执行增加操作");
}
}
ApplicationContext.xml 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"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
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/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<!--
这里的context是配置自动装配的
aop是配置aop的约束
-->
<!--自动装配-->
<!--
方式一:
使用原生的SpringAPI接口
-->
<context:component-scan base-package="jer.study.spring"/>
<context:annotation-config/>
<!-- AOP-->
<aop:config>
<!-- 切入点:execution表达式 execution(要执行的位置!* * * * *)第一个*后面有一个空格-->
<aop:pointcut id="log" expression="execution(* jer.study.spring.UserServiceImp.*(..))"/>
<aop:advisor advice-ref="afterLog" pointcut-ref="log"/>
<aop:advisor advice-ref="beforeLog" pointcut-ref="log"/>
</aop:config>
</beans>
MyTest.java 测试类
import jer.study.spring.UserService;
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MyTest {
@Test
public void test(){
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("ApplicationContext.xml");
//这个地方类型要写返回的接口类型
UserService bean = context.getBean("userServiceImp", UserService.class);
bean.select();
}
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Sj4rQHU9-1668092192744)(C:\Users\86156\AppData\Roaming\Typora\typora-user-images\image-20221107230730643.png)]
1.3自定义类实现AOP
diy.java 自定义类
import org.springframework.stereotype.Component;
@Component
public class diy {
public void methodBefore(){
System.out.println("========之前=======");
}
public void methodAfter(){
System.out.println("========之后=======");
}
}
ApplicationContext.xml Spring配置类
<aop:config>
<aop:aspect ref="diy">
<aop:pointcut id="index" expression="execution(* jer.study.spring.UserServiceImp.*(..))"/>
<aop:before method="methodBefore" pointcut-ref="index"/>
<aop:after method="methodAfter" pointcut-ref="index"/>
</aop:aspect>
</aop:config>
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-495lSbsh-1668092192745)(C:\Users\86156\AppData\Roaming\Typora\typora-user-images\image-20221107230618821.png)]
1.4注解实现AOP
使用JavaConfig的方式实现AOP
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
//@EnableAspectJAutoProxy 等价与 ApplicationContext.xml 里面的 <aop:aspectj-autoproxy/>
//作用是开启注解支持
@EnableAspectJAutoProxy
@Configuration
@ComponentScan("jer.study.spring")
public class JavaConfig {
}
使用ApplicationContext.xml实现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
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/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<!--
这里的context是配置自动装配的
aop是配置aop的约束
-->
<!--自动装配-->
<!--
方式一:
使用原生的SpringAPI接口
-->
<context:component-scan base-package="jer.study.spring"/>
<context:annotation-config/>
<aop:aspectj-autoproxy/>
</beans>
AnnotationPointcut类 这个类是切面注入的类
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
@Component //注入bean
@Aspect //标记这个类是一个切面
public class AnnotationPointcut {
@Pointcut("execution(* jer.study.spring.UserServiceImp.*(..))")
public void performance(){}
@Before("performance()")
public void methodBefore(){
System.out.println("========之前=======");
}
@After("performance()")
public void methodAfter(){
System.out.println("========之后=======");
}
}
@After @Before @Around 的执行顺序
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Dasj0yeI-1668092192746)(C:\Users\86156\AppData\Roaming\Typora\typora-user-images\image-20221108173334032.png)]
配置依赖
- junit
- mysql
- mybatis
- aspectj
- lombok
- spring-webmvc
- spring-jdbc
- mybatis-spring
<dependencies>
<!-- junit-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13</version>
</dependency>
<!--mysql-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.11</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.2</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.9.1</version>
</dependency>
<!--lombok插件-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.10</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.3.23</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.3.23</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis-spring -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>2.0.7</version>
</dependency>
</dependencies>
整合Mybatis 和Spring
dao层
UserMapper 接口
import jer.study.spring.pojo.User;
import java.util.List;
public interface UserMapper {
List<User> select();
}
UserMapper.xml 实现类
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!-- 映射配置-->
<mapper namespace="jer.study.spring.dao.UserMapper">
<select id="select" resultType="user">
select *
from `User`;
</select>
</mapper>
UserMapperImp.java
import jer.study.spring.pojo.User;
import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public class UserMapperImp implements UserMapper{
private SqlSessionTemplate SqlSessionTemplate;
// @Autowired JavaConfig使用这个自动注入
public void setSqlSession(SqlSessionTemplate sqlSession) {
this.SqlSessionTemplate = sqlSession;
}
@Override
public List<User> select() {
return SqlSessionTemplate.getMapper(UserMapper.class).select();
}
}
mybatis-config.xml //Mybatis的配置文件
<?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>
<typeAliases>
<!-- 扫描包-->
<package name="jer.study.spring.pojo"/>
<!-- 单个设置别名-->
</typeAliases>
</configuration>
pojo层
import lombok.Data;
@Data
public class User {
int id;
String UserName;
String UserPwd;
int sex;
String ExamID;
String School;
boolean Del;
@Override
public String toString() {
return "User{" +
"id=" + id +
", UserName='" + UserName + '\'' +
", UserPwd='" + UserPwd + '\'' +
", sex=" + sex +
", ExamID='" + ExamID + '\'' +
", School='" + School + '\'' +
", Del=" + Del +
'}';
}
}
ApplicationText.xml 版本
总的ApplicationText.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">
<import resource="spring-mybatis.xml"/>
</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"
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">
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/api?useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</bean>
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<!-- 绑定Mybatis配置文件-->
<property name="mapperLocations" value="classpath:jer/study/spring/dao/*.xml"/>
<property name="configLocation" value="classpath:mybatis-config.xml"/>
</bean>
<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
<constructor-arg index="0" ref="sqlSessionFactory"/>
</bean>
<bean id="userMapperImp" class="jer.study.spring.dao.UserMapperImp">
<property name="sqlSession" ref="sqlSession"/>
</bean>
<!-- 开启扫描包-->
<context:component-scan base-package="jer.study.spring"/>
<context:annotation-config/>
</beans>
MyText
import jer.study.spring.Config.JavaConfig;
import jer.study.spring.dao.UserMapperImp;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MyTest {
@Test
public void test(){
// ApplicationContext context = new AnnotationConfigApplicationContext(JavaConfig.class);
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("ApplicationContext.xml");
UserMapperImp mapperImp = context.getBean("userMapperImp", UserMapperImp.class);
System.out.println(mapperImp.select());
}
}
JavaConfig版本
总JavaConfig
package jer.study.spring.Config;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
@Configuration
@Import(springMybatisConfig.class)
public class JavaConfig {
}
子JavaConfig
package jer.study.spring.Config;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import java.sql.Connection;
import java.sql.SQLException;
@Configuration
@ComponentScan("jer.study.spring")
public class springMybatisConfig {
//这里使用Spring数据源替换Mybatis的数据源:c3p0 , dbcp , druid
//这里使用 org.springframework.jdbc.datasource.DriverManagerDataSource
@Bean
public DriverManagerDataSource dataSource() throws SQLException {
DriverManagerDataSource ds = new DriverManagerDataSource();
ds.setDriverClassName("com.mysql.cj.jdbc.Driver");
ds.setUrl("jdbc:mysql://localhost:3306/api?useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC");
ds.setUsername("root");
ds.setPassword("123456");
Connection actualCon = ds.getConnection();
return ds;
}
// SqlSessionFactory : SqlSession工厂
@Bean
public SqlSessionFactory sqlSessionFactory() throws Exception {
SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
factoryBean.setDataSource(dataSource());
//绑定Mybatis配置文件
factoryBean.setConfigLocation(new ClassPathResource("mybatis-config.xml"));
factoryBean.setMapperLocations(new ClassPathResource("jer/study/spring/dao/UserMapper.xml"));
factoryBean.setTypeAliasesPackage("jer.study.spring.pojo");
return factoryBean.getObject();
}
//SqlSessionTemplate :SqlSession模板就不用SqlSession对象了,使用SqlSessionTemplate
@Bean SqlSessionTemplate SqlSessionTemplate()throws Exception {
//只能使用构造器注入
return new SqlSessionTemplate(sqlSessionFactory());
}
}
MyText
import jer.study.spring.Config.JavaConfig;
import jer.study.spring.dao.UserMapperImp;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MyTest {
@Test
public void test(){
ApplicationContext context = new AnnotationConfigApplicationContext(JavaConfig.class);
// ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("ApplicationContext.xml");
UserMapperImp mapperImp = context.getBean("userMapperImp", UserMapperImp.class);
System.out.println(mapperImp.select());
}
}
测测试结果:
[User{id=1, UserName='WZY', UserPwd='123456', sex=1, ExamID='10010', School='华中科技大学', Del=false}, User{id=2, UserName='CYJ', UserPwd='456789', sex=0, ExamID='10086', School='武汉大学', Del=false}, User{id=4, UserName='ZS', UserPwd='110110', sex=1, ExamID='119119', School='????', Del=true}, User{id=5, UserName='LS', UserPwd='123', sex=1, ExamID='465564', School='????', Del=false}]
使用SqlSessionDaoSupport简化
UserMapperImp2.java
import jer.study.spring.pojo.User;
import org.mybatis.spring.support.SqlSessionDaoSupport;
import java.util.List;
public class UserMapperImp2 extends SqlSessionDaoSupport implements UserMapper {
public List<User> select() {
return getSqlSession().getMapper(UserMapper.class).select();
}
}
注册Bean
@Bean
public UserMapperImp2 UserMapperImp2() throws Exception {
UserMapperImp2 imp2 = new UserMapperImp2();
imp2.setSqlSessionFactory(sqlSessionFactory());
return imp2;
}
测试类
public class MyTest {
@Test
public void test(){
ApplicationContext context = new AnnotationConfigApplicationContext(JavaConfig.class);
// ApplicationContext context = new ClassPathXmlApplicationContext("ApplicationContext.xml");
UserMapperImp2 mapperImp = context.getBean("UserMapperImp2", UserMapperImp2.class);
System.out.println(mapperImp.select());
}
}
声明式事务
事务在项目开发中十分的重要,
- 把一组业务当成一个业务来实现,要么成功要么都失败
ACID原则
- 原子性:确保要么都成功,要么都失败
- 一致性:确保要么都被提交要么都失败
- 隔离性:多个业务操作同一个资源,防止数据损坏
- 持久性:事务一旦提交,无论发生什么事情,都不能再被影响,被持久化到存储器中
7种事务传播机制
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZCOCWdc1-1668092192747)(C:\Users\86156\AppData\Roaming\Typora\typora-user-images\image-20221110202021303.png)]