文章目录
文档: Spring Framework Reference Documentation
官网下载地址:repo.spring.io
Github:Releases · spring-projects/spring-framework (github.com)
导包:
直接导入一个比较大的包,让maven去帮助我们导入它的依赖
<!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.0.RELEASE</version>
</dependency>
<!-- 整合jdbc -->
<!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.2.0.RELEASE</version>
</dependency>
优点
- 开源的免费的框架(容器)
- 轻量级的、非入侵式
- 控制反转(IOC)和面向切面(AOP)
- 支持事务处理,对框架整合支持
弊端
- 经过了长久的发展,整合了许多框架,配置很多。于是出现了springBoot来简化spring的配置
组成
七大核心功能模块
IOC理论推导
在以往的程序中,我们需要使用哪个dao层业务就需要在业务层代码中进行修改。当程序体量十分庞大的时候,再手动修改代码的代价十分的昂贵。于是有了这一种思想,通过在业务层添加一个方法set,让用户调用set方法来主动选择需要哪一种业务代码。这种方式降低了系统耦合性。这就是IOC的原型
IOC本质
控制反转是一种思想,依赖注入(DI)是实现控制反转的一种方式
spring中实现控制反转的是IoC容器,它的实现方式也是依赖注入
HelloSpring(第一个spring程序)
实体
package com.zhong.pojo;
public class Hello {
private String str;
public String getStr() {
return str;
}
public void setStr(String str) {
this.str = str;
}
@Override
public String toString() {
return "Hello{" +
"str='" + str + '\'' +
'}';
}
}
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
https://www.springframework.org/schema/beans/spring-beans.xsd">
<!--使用spring来创建对象,在spring中这些对象都叫做bean-->
<bean id="hello" class="com.zhong.pojo.Hello">
<!--通过properties标签来对一个对象的值赋值-->
<property name="str" value="Spring" />
</bean>
</beans>
测试
import com.zhong.pojo.Hello;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MyTest {
public static void main(String[] args) {
//这里,如果使用xml来创建对象的话,必须使用new ClassPathXmlApplicationContext来加载xml文件
//这个方法的参数是可变长参数,我们可以传入多个值
//获取spring的上下文对象(拿到spring容器)
ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");
//对象都在spring中进行管理,如果要使用,要取出来
Hello hello = (Hello) context.getBean("hello");
System.out.println(hello.toString());
}
}
IOC创建对象的方式
-
默认使用无参构造方法创建对象(在拿到spring容器的时候,会自动创建xml里配置的所有对象)
-
有惨构造方式
-
下标
<!-- 有参构造方式_下标赋值--> <bean id="user" class="com.zhong.dao.User"> <constructor-arg index="0" value="123" /> </bean>
-
类型
<!--通过类型匹配来使用有参构造--> <!--参数多个类型相同会出问题。所以不建议使用--> <!--类型相同的时候,相同类型的参数会按照标签顺序进行赋值--> <bean id="user" class="com.zhong.dao.User"> <constructor-arg type="java.lang.String" value="123"></constructor-arg> </bean>
-
参数名
<!--直接通过参数名赋值--> <bean id="user" class="com.zhong.dao.User"> <constructor-arg name="name" value="123"></constructor-arg> </bean>
在配置文件加载的时候,spring容器中的对象会被初始化(也就是自动的new出来放在容器中等待我们去取)
-
Spring配置
1.别名
别名,可以给容器创建出来的对象起一个别名,用户可以通过创建的对象的id和别名(两者可同时使用,取的都是一个对象)来获取同一个对象。
但个人感觉多次一举
<alias name="user" alias="user2"></alias>
2.配置
id:用户可以取到的这个对象的名字(也就是变量名)
class:bean标签该去创建一个什么类型的对象(也就是对象类型)
name:对象别名,通过name可以对同一个对象取多个别名,分隔符可以是逗号,分号,空格
<bean id="userTest" class="com.zhong.dao.UserT" name="t,userT2 u3;u4">
<property name="name" value="123"></property>
</bean>
3.import
import一般用于团队开发,可以将多个配置文件导入到一个配置文件中,这样可以通过这个总的配置文件拿到各个配置文件中初始化的对象。
问题:id相同怎么办?
当出现导入的两个配置文件中的对象的id相同,那么后导入的配置文件会覆盖前导入的配置文件
依赖注入(DI)
1.构造器注入
2.Set方式注入
测试环境搭建
-
复杂类型
package com.zhong.pojo; public class Address { private String address; public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } }
-
真实对象
package com.zhong.pojo; import java.util.*; public class Student { private String name; private Address address; private String[] books; private List<String> hobbies; private Map<String, String> cards; private Set<String> games; private Properties info; private String wife; public String getName() { return name; } public void setName(String name) { this.name = name; } public Address getAddress() { return address; } public void setAddress(Address address) { this.address = address; } public String[] getBooks() { return books; } public void setBooks(String[] books) { this.books = books; } public List<String> getHobbies() { return hobbies; } public void setHobbies(List<String> hobbies) { this.hobbies = hobbies; } public Map<String, String> getCards() { return cards; } public void setCards(Map<String, String> cards) { this.cards = cards; } public Set<String> getGames() { return games; } public void setGames(Set<String> games) { this.games = games; } public Properties getInfo() { return info; } public void setInfo(Properties info) { this.info = info; } public String getWife() { return wife; } public void setWife(String wife) { this.wife = wife; } @Override public String toString() { return "Student{" + "name='" + name + '\'' + ", address=" + address + ", books=" + Arrays.toString(books) + ", hobbies=" + hobbies + ", cards=" + cards + ", games=" + games + ", info=" + info + ", wife='" + wife + '\'' + '}'; } }
-
beans.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 https://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="student" class="com.zhong.pojo.Student"> <!--set注入,普通值直接使用value进行注入--> <property name="name" value="123" /> </bean> </beans>
注入
<bean id="address" class="com.zhong.pojo.Address"></bean>
<bean id="student" class="com.zhong.pojo.Student">
<!--set注入,普通值直接使用value进行注入-->
<property name="name" value="123" />
<!--bean注入,使用ref-->
<property name="address" ref="address" />
<!--数组-->
<property name="books">
<array>
<value>红楼梦</value>
<value>水浒传</value>
<value>西游记</value>
</array>
</property>
<!--list-->
<property name="hobbies">
<list>
<value>唱</value>
<value>跳</value>
<value>写代码</value>
<value>篮球</value>
</list>
</property>
<!--map-->
<property name="cards">
<map>
<entry key="身份证" value="123456789012345678" />
<entry key="银行卡" value="123456789012345678" />
</map>
</property>
<!--set-->
<property name="games">
<set>
<value>LOL</value>
<value>CSGO</value>
</set>
</property>
<!--null-->
<property name="wife">
<null/>
</property>
<!--properties-->
<property name="info">
<props>
<prop key="学号">2008030201</prop>
<prop key="性别">男</prop>
</props>
</property>
</bean>
3.拓展方式注入
c命名空间和p命名空间注入
<?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命名空间注入(properties就是set注入)-->
<bean id="user" class="com.zhong.pojo.User" p:age="18" p:name="123" />
<!--c命名空间注入(构造器注入)-->
<bean id="user2" class="com.zhong.pojo.User" c:age="18" c:name="123" />
</beans>
导入xml约束
xmlns:p="http://www.springframework.org/schema/p"
xmlns:c="http://www.springframework.org/schema/c"
bean作用域
1.单例模式(默认)
bean的作用域默认都是单例模式,我们也可以显式的定义为单例模式
<bean id="user2" class="com.zhong.pojo.User" c:age="18" c:name="123" scope="singleton" />
2.原型模式
每次从容器中取出来的对象都是一个新的对象,尽管这些对象的属性值相同
<bean id="user2" class="com.zhong.pojo.User" c:age="18" c:name="123" scope="prototype" />
Bean的自动装配
spring中有三种装配方式
- 在xml种显式配置(手动)
- 在java中显示配置
- 隐式自动装配
byName自动装配
<!--byname:通过setXXX()这个方法set后面的名字来查找进行自动装配-->
<bean id="people" class="com.zhong.pojo.People" autowire="byName">
<property name="name" value="123" />
</bean>
byType
<!--byType:通过查找类型自动装配,但是要保证类型全局唯一-->
<bean id="people" class="com.zhong.pojo.People" autowire="byType">
<property name="name" value="123" />
</bean>
注解实现自动装配
注解实现自动装配是@Autowired。它的工作原理是先使用byType在beans.xml中上下文查找,如果类型数量大于1,再使用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"
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>
然后在我们需要自动装配的类的属性上写上@Autowired
package com.zhong.pojo;
import org.springframework.beans.factory.annotation.Autowired;
public class People {
@Autowired
private Cat cat;
@Autowired
private Dog dog;
private String name;
}
@Autowired(request = false)这样被标注的属性可以为null。同时也可以使用@nullable使属性可以为null
@Autowired优先按照类型匹配,@Qualifier(value=“xxx”)这个注解则会优先使用byName进行匹配。@Resource java自带的注解,也可以实现自动装配,但在java11取消
使用注解开发
在spring4之后使用注解开发需要导入aop的包
1.bean
@component:放在类上,在配置文件中配置组件扫描的指定的包下起作用,说名该类是一个bean,需要被spring容器管理
2.属性如何注入
@Value(“xxx”):放在属性上,直接给属性注入值。复杂类型不适用,只用于普通值的注入
3.衍生如何注入
@component有衍生注解,在web开发中,按照mvc三层架构
- dao @Repository:功能和@Component一样只是为了和实体类进行区分
- service @Service
- controller @Controller
4.自动装配
5.作用域
@Scope(“xxx”)singleton单例模式
使用java的方式配置spring
package com.zhong.config;
import com.zhong.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 //被spring托管,注册到容器中,它本身也是一个@Component。并且这个注解的意思是标志这个类是原来的配置.xml文件
//既然是原来的xml文件,那么原来的一些功能也可以通过注解来使用
@ComponentScan("com.zhong.pojo")
@Import(comfig2.class)
public class MyConfig {
//注册一个bean,方法的名字就是bean标签里的id
//返回值就是bean标签里的class
//1.@Bean和2.在实体类上加上@Component配置类加上扫描,选择其一
@Bean
public User getUser() {
return new User();//返回要注入到bean的对象
}
}
package com.zhong.pojo;
import org.springframework.beans.factory.annotation.Value;
public class User {
@Value("123")
private String name;
public User(String name) {
this.name = name;
}
public User() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
'}';
}
}
代理模式
SpringAOP的底层就是代理模式
1.静态代理
好处
- 让被代理角色更加纯粹
- 公共业务交给代理角色实现
- 公共业务拓展时,便于集中管理
坏处
- 一个被代理会产生一个代理
2.动态代理
动态代理的底层是反射。动态代理分为两大类:基于接口的动态代理,基于类的动态代理
- 基于接口 JDK动态代理(原生)
- 基于类 cglig
- java字节码实现 Javasist
这里我们使用原生的jdk动态代理,需要了解两个类proxy:代理、invocationhandler :调用处理程序
package demo02;
import demo01.Rent;
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);
}
//处理代理实例,并返回结果
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object invoke = method.invoke(target, args);
return invoke;
}
}
package demo01;
public class Client {
public static void main(String[] args) {
//被代理角色
Host host = new Host();
//代理角色
ProxyInvocationHandler proxyInvocationHandler = new ProxyInvocationHandler();
//调用程序处理对象来处理要调用的接口对象
proxyInvocationHandler.setRent(host);
Rent proxy = (Rent) proxyInvocationHandler.getProxy();
proxy.rent();
}
}
SpringAOP
springAOP的底层实现还是代理模式,其实就是代理模式的spring封装,我们只需要去使用。
首先,使用sprinAOP需要导入
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.4</version>
</dependency>
-
使用spring的api接口
<?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: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/aop https://www.springframework.org/schema/aop/spring-aop.xsd"> <bean id="userService" class="com.zhong.service.UserServiceImpl"></bean> <bean id="log" class="com.zhong.log.Log"></bean> <bean id="afterLog" class="com.zhong.log.AfterLog"></bean> <!-- xmlns:aop="http://www.springframework.org/schema/aop" http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd" 这里配置aop约束 --> <!--原生api接口--> <!--需要导入aop约束--> <aop:config> <!--配置切入点--> <!--expression:表达式execution(要执行的位置 修饰词(public等) 返回值 类名 方法名 参数)--> <aop:pointcut id="pointcut" expression="execution(* com.zhong.service.UserServiceImpl.*(..))"/> <!--执行环绕增加--> <aop:advisor advice-ref="log" pointcut-ref="pointcut" /> <aop:advisor advice-ref="afterLog" pointcut-ref="pointcut" /> </aop:config> </beans>
需要注册的bean继承某些类才能够被切入点配置
package com.zhong.log; import org.springframework.aop.MethodBeforeAdvice; import java.lang.reflect.Method; public class Log implements MethodBeforeAdvice { //args 方法需要调用的参数 //method 被代理类需要被调用的方法 //target 被代理类 public void before(Method method, Object[] args, Object target) throws Throwable { System.out.println(target.getClass().getName()+"的"+method.getName()+"准备执行了"); } }
-
使用自定义类
<?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: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/aop https://www.springframework.org/schema/aop/spring-aop.xsd"> <bean id="userService" class="com.zhong.service.UserServiceImpl"></bean> <!--自定义切面--> <bean id="diy" class="com.zhong.diy.DiyPointCut"></bean> <aop:config> <!--引用自定义切面--> <aop:aspect ref="diy"> <!--切入点--> <aop:pointcut id="point" expression="execution(* com.zhong.service.UserServiceImpl.*(..))"/> <!--通知--> <aop:before method="before" pointcut-ref="point" /> <aop:after method="after" pointcut-ref="point" /> </aop:aspect> </aop:config> </beans>
package com.zhong.diy; public class DiyPointCut { public void before () { System.out.println("======================before"); } public void after() { System.out.println("======================after"); } }
-
使用注解实现
<?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: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/aop https://www.springframework.org/schema/aop/spring-aop.xsd"> <bean id="userService" class="com.zhong.service.UserServiceImpl"></bean> <bean id="log" class="com.zhong.log.Log"></bean> <bean id="afterLog" class="com.zhong.log.AfterLog"></bean> <!--使用注解AOP--> <bean id="annotationPointCut" class="com.zhong.diy.AnnotationPointCut"></bean> <!--开启自动代理--> <aop:aspectj-autoproxy/> </beans>
package com.zhong.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; @Aspect//标记该类是切面 public class AnnotationPointCut { @Before("execution(* com.zhong.service.UserServiceImpl.*(..))") public void before() { System.out.println("==============================before"); } @After("execution(* com.zhong.service.UserServiceImpl.*(..))") public void after() { System.out.println("=================================after"); } //环绕中,使用参数获得连接点 @Around("execution(* com.zhong.service.UserServiceImpl.*(..))") public void around(ProceedingJoinPoint jp) throws Throwable { System.out.println("环绕前"); Signature signature = jp.getSignature(); System.out.println(signature); Object proceed = jp.proceed();//真正执行方法 System.out.println("环绕后"); System.out.println(proceed); } }
这里可以通过方法注释配置切入点
/** * 切面类:注解的切面类 */ @Aspect public class MyAspectAnno { //通过@Pointcut注释在方法上配置切入点,之后在@Before通过value=方法名的方式调用该切入点 @Pointcut(value="execution(* com.itheima.spring.demo1.OrderDao.find(..))") private void pointcut(){} //前置通知 @Before(value="MyAspectAnno.pointcut()") public void before(){ System.out.println("前置通知======"); } //后置通知 @AfterReturning(value="MyAspectAnno.pointcut()", returning="result") public void afterReturning(Object result){ System.out.println("后置通知====="+result); } //环绕通知 @Around(value="MyAspectAnno.pointcut()") public Object around(ProceedingJoinPoint joinPoint) throws Throwable{ System.out.println("环绕前增强====="); Object obj = joinPoint.proceed(); System.out.println("环绕后增强====="); return obj; } //异常抛出通知 @AfterThrowing(value="MyAspectAnno.pointcut()" , throwing="e") public void find(Throwable e ){ System.out.println("异常抛出通知======"+e.getMessage()); } // 最终通知: @After(value="MyAspectAnno.pointcut()") public void after( ){ System.out.println("最终通知======"); } }
整合mybatis
相关jar包
<dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.47</version> </dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.5.7</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.3.22</version> </dependency> <!--spring操作数据库需要spring-jdbc--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>5.3.22</version> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.9.4</version> </dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>2.0.2</version> </dependency> </dependencies>
1.编写数据源配置
spring-dao.xml
<!--使用context读取db.properties文件的数据-->
<context:property-placeholder location="classpath:db.properties"/>
<!--dataSource 使用spring的数据源替换mybatis的数据源
这里使用spring的jdbc
-->
<!--使用驱动管理数据源-->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url"
value="jdbc:mysql://localhost:3306/mybatis?useUnicode=true&characterEncoding=utf8&useSSL=false"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</bean>
2.编写sqlSessionFactory
spring-dao.xml
<!--配置sqlSessionFactory-->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="configLocation" value="classpath:mybatis-config.xml"/>
<property name="mapperLocations" value="classpath:com/zhong/mapper/UserMapper.xml"/>
</bean>
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>
<settings>
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
<typeAliases>
<package name="com.zhong.pojo"/>
</typeAliases>
</configuration>
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="com.zhong.mapper.UserMapper">
<select id="selectUser" resultType="user">
select *
from mybatis.user;
</select>
</mapper>
3.编写sqlSessionTemplate
spring-dao.xml
<!--调用sqlSession还需要一个sqlSessionTemplate-->
<bean id="sqlSessionTemplate" class="org.mybatis.spring.SqlSessionTemplate">
<!--SqlSessionTemplate这个类没有set方法,只能使用构造器注入-->
<constructor-arg name="sqlSessionFactory" ref="sqlSessionFactory"/>
</bean>
4.给接口加实现类
UserMapperImpl.java
package com.zhong.mapper;
import com.zhong.pojo.User;
import org.mybatis.spring.SqlSessionTemplate;
import java.util.List;
public class UserMapperImpl implements UserMapper {
private SqlSessionTemplate sqlSessionTemplate = null;
public void setSqlSessionTemplate(SqlSessionTemplate sqlSessionTemplate) {
this.sqlSessionTemplate = sqlSessionTemplate;
}
/*从使用xml文件写sql语句转变成使用SqlSessionTemplate*/
public List<User> selectUser() {
UserMapper mapper = sqlSessionTemplate.getMapper(UserMapper.class);
return mapper.selectUser();
}
}
5.实现类注入spring中
spring-dao.xml
<!---->
<bean id="userMapper" class="com.zhong.mapper.UserMapperImpl">
<property name="sqlSessionTemplate" ref="sqlSessionTemplate"/>
</bean>
6.测试
import com.zhong.mapper.UserMapper;
import com.zhong.pojo.User;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.io.IOException;
import java.util.List;
public class MyTest {
@Test
public void test() throws IOException {
ApplicationContext context = new ClassPathXmlApplicationContext("spring-dao.xml");
UserMapper userMapper = context.getBean("userMapper", UserMapper.class);
List<User> userList = userMapper.selectUser();
for (User user : userList) {
System.out.println(user);
}
}
}
总配置文件,这个文件写好之后可以通过import导入到applicationContext使用,之后就不必改动了
spring-dao.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:aop="http://www.springframework.org/schema/aop"
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/aop
https://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd">
<!--使用context读取db.properties文件的数据-->
<context:property-placeholder location="classpath:db.properties"/>
<!--dataSource 使用spring的数据源替换mybatis的数据源
这里使用spring的jdbc
-->
<!--使用驱动管理数据源-->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url"
value="jdbc:mysql://localhost:3306/mybatis?useUnicode=true&characterEncoding=utf8&useSSL=false"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</bean>
<!--配置sqlSessionFactory-->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="configLocation" value="classpath:mybatis-config.xml"/>
<property name="mapperLocations" value="classpath:com/zhong/mapper/UserMapper.xml"/>
</bean>
<!--调用sqlSession还需要一个sqlSessionTemplate-->
<bean id="sqlSessionTemplate" class="org.mybatis.spring.SqlSessionTemplate">
<!--SqlSessionTemplate这个类没有set方法,只能使用构造器注入-->
<constructor-arg name="sqlSessionFactory" ref="sqlSessionFactory"/>
</bean>
<!---->
<bean id="userMapper" class="com.zhong.mapper.UserMapperImpl">
<property name="sqlSessionTemplate" ref="sqlSessionTemplate"/>
</bean>
</beans>
方式2
使用类继承
package com.zhong.mapper;
import com.zhong.pojo.User;
import org.apache.ibatis.session.SqlSession;
import org.mybatis.spring.support.SqlSessionDaoSupport;
import java.util.List;
public class UserMapperImpl2 extends SqlSessionDaoSupport implements UserMapper {
public List<User> selectUser() {
return getSqlSession().getMapper(UserMapper.class).selectUser();
}
}
<?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:aop="http://www.springframework.org/schema/aop"
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/aop
https://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd">
<!--使用context读取db.properties文件的数据-->
<context:property-placeholder location="classpath:db.properties"/>
<!--dataSource 使用spring的数据源替换mybatis的数据源
这里使用spring的jdbc
-->
<!--使用驱动管理数据源-->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url"
value="jdbc:mysql://localhost:3306/mybatis?useUnicode=true&characterEncoding=utf8&useSSL=false"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</bean>
<!--配置sqlSessionFactory-->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="configLocation" value="classpath:mybatis-config.xml"/>
<property name="mapperLocations" value="classpath:com/zhong/mapper/UserMapper.xml"/>
</bean>
<bean id="userMapper2" class="com.zhong.mapper.UserMapperImpl2">
<property name="sqlSessionFactory" ref="sqlSessionFactory"/>
</bean>
</beans>
声明式事务
spring事务分为两种
- 編程式事务
- 声明式事务
<!--配置声明式事务-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<!--结合AOP实现事务织入-->
<!--配置事务通知-->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<!--给哪些方法配置事务-->
<tx:attributes>
<tx:method name="add"/>
<tx:method name="delete"/>
<tx:method name="update"/>
</tx:attributes>
</tx:advice>
<!--配置事务切入-->
<aop:config>
<aop:pointcut id="txPointCut" expression="execution(* com.zhong.mapper.*.*(..))"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="txPointCut"/>
</aop:config>