文章目录
- 1.Spring的组成
- 2.Spring优点
- 3.IOC理论推导
- 4.IOC本质
- 5.IOC实现:xml或者注解或者自动装配(零配置)。
- 6.hellospring
- 6.1beans.xml的结构为:
- 6.2.Spring容器
- 6.3对象的创建和控制反转
- 7.IOC创建对象方式
- 7.1以有参构造的方式创建对象:
- 8.spring配置说明
- 8.1别名
- 8.2Bean的配置
- 8.3import
- 9.依赖注入方式
- 9.1三种注入方式
- 9.2.set注入方式(`重点`)
- 9.3.p命名空间和c命名空间注入:
- 9.4.bean的作用域:
- 10.Bean的自动装配
- 11.注解实现自动装配
- 11.1 在beans.xml中加入注解支持:
- 11.2注解实例
- 11.3@Resource和@Autowired的区别
- 12.使用注解开发
- 12.1注解的应用场景
- 12.2注解说明:
- 13.使用javaconfig实现配置
- 13.1配置类实现配置的步骤:
- 13.2回顾:
- 14.代理
- 14.1.静态代理模式:
- 14.2.动态代理:
- 14.3代理类ProxyInvocationHandler.java
- 15.AOP
- 15.1.什么是AOP?
- 15.2.使用spring实现AOP
- 15.2.1方式一:使用原生的Spring API接口
- 15.2.2方式二:自定义diy类
- 15.2.3方式三:使用注解方式实现AOP
- 16.整合Mybatis
- 1.导入相关jar包:
- 2.编写配置文件
- 3.实体类,Mapper及xml文件和实现类
- 1.UserMapperImpl
- 2.UserMapperImpl2
- 17.Spring声明式事务
- 17.1回顾事务
- 17.2配置声明式事务
- 17.3spring中的事务管理
1.Spring的组成
2.Spring优点
3.IOC理论推导
IOC(控制反转):获得依赖对象的方式反转了。
控制反转后,主动权交给用户了,不在程序员手上了。
4.IOC本质
ioc容器把他们解耦了。通过接口的调用就没有原来的强联系了。
5.IOC实现:xml或者注解或者自动装配(零配置)。
6.hellospring
spring核心配置文件官方名:applicationContext.xml。
这里记为beans.xml。
6.1beans.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-3.0.xsd ">
</beans>
Hello.java
public class Hello {
public String str;
public String getStr() {
return str;
}
public void setStr(String str) {
this.str = str;
}
@Override
public String toString() {
return "hello{" +
"str='" + str + '\'' +
'}';
}
}
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
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd ">
<!--使用spring创建对象,在spring中这些都成为bean-->
<bean id="hello" class="com.kuang.pojo.Hello">
<property name="str" value="SPRING"/>
</bean>
</beans>
MyTest测试:
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());
}
}
6.2.Spring容器
这里的spring容器:
6.3对象的创建和控制反转
7.IOC创建对象方式
默认走的 无参构造 创建对象。
7.1以有参构造的方式创建对象:
测试类User.java
public class User {
private String name;
//public User(){
// System.out.println("默认构造器");
//}
public User(String name){
this.name=name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void show(){
System.out.println("name="+name);
}
}
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
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd ">
<!-- 1.无参构造器创建对象-->
<!--<bean id="user" class="com.kuang.pojo.User">-->
<!-- <property name="name" value="请见"/>-->
<!--</bean>-->
<!-- 2.有参构造器通过下标-->
<!--<bean id="user" class="com.kuang.pojo.User">-->
<!-- <constructor-arg index="0" value="123"/>-->
<!--</bean>-->
<!--3.有参构造器通过类型 创建对象,【不推荐使用】-->
<!-- <bean id="user" class="com.kuang.pojo.User">-->
<!-- <constructor-arg type="java.lang.String" value="345"/>-->
<!-- </bean>-->
<!--4.有参构造通过参数名【推荐】-->
<bean id="user" class="com.kuang.pojo.User">
<constructor-arg name="name" value="777"/>
</bean>
</beans>
8.spring配置说明
8.1别名
<alias name="user" alias="user2"/>
8.2Bean的配置
8.3import
9.依赖注入方式
9.1三种注入方式
9.2.set注入方式(重点
)
Student:
public class Student {
private String name;
private Address address;
private String[] books;
private List<String> hobbys;//List<Address>
private Map<String, String> card;
private Set<String> games;
private String wife;
private Properties info;
}
Address
public class Address {
private String address;
}
User
public class User {
private String name;
private int age;
}
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
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd ">
<bean id="address" class="com.kuang.pojo.Address">
<property name="address" value="中安路风华街123号"/>
</bean>
<bean id="student" class="com.kuang.pojo.Student">
<property name="name" value="李明"/>
<property name="address" ref="address"/>
<property name="books">
<array>
<value>十四号书</value>
<value>传奇书</value>
<value>史诗书</value>
</array>
</property>
<property name="hobbys" >
<list>
<value>足球</value>
<value>篮球</value>
<value>羽毛球</value>
</list>
</property>
<property name="card">
<map>
<entry key="蓝色" value="大海"/>
<entry key="金色" value="太阳"/>
<entry key="黑色" value="夜晚"/>
</map>
</property>
<property name="games">
<set>
<value>按此</value>
<value>阿斯顿</value>
<value>雪国</value>
</set>
</property>
<property name="wife">
<null/>
</property>
<property name="info">
<props>
<prop key="1">123</prop>
<prop key="2">456</prop>
<prop key="3">789</prop>
</props>
</property>
</bean>
</beans>
9.3.p命名空间和c命名空间注入:
9.4.bean的作用域:
10.Bean的自动装配
11.注解实现自动装配
11.1 在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"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd ">
<!-- 指定扫描的包,这个包下的注解就会生效。-->
<context:component-scan base-package="com.kuang.pojo"/>
<context:annotation-config/>
</beans>
11.2注解实例
<?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-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd ">
<!-- 加入注解支持。3个约束,1个标签。-->
<context:annotation-config/>
<bean id="cat111" class="com.kuang.pojo.Cat"/>
<bean id="cat11" class="com.kuang.pojo.Cat"/>
<bean id="dog111" class="com.kuang.pojo.Dog"/>
<bean id="dog11" class="com.kuang.pojo.Dog"/>
<!-- <bean id="people" class="com.kuang.pojo.People"/>-->
<bean id="people" class="com.kuang.pojo.People">
<property name="name" value="奥斯"/>
</bean>
<!-- 虽然在容器中没有写autowired,但是因为在People中对属性使用了@Autowired的注解,也是实现了自动注入。-->
</beans>
public class People {
private String name;
// @Autowired按类型自动注入。类型相同时,加入@Qualifier加入ByName方式.
// 表示使用对应bean的对象作为属性注入。
// @Resource不能指定name,在通过Type和Name都失败的情况下,才会报错。可通过name指定
@Resource(name = "dog11")
private Dog dog;
@Autowired
@Qualifier(value = "cat11")
private Cat cat;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Dog getDog() {
return dog;
}
public void setDog(Dog dog) {
this.dog = dog;
}
public Cat getCat() {
return cat;
}
public void setCat(Cat cat) {
this.cat = cat;
}
@Override
public String toString() {
return "People{" +
"name='" + name + '\'' +
", dog=" + dog +
", cat=" + cat +
'}';
}
}
11.3@Resource和@Autowired的区别
12.使用注解开发
12.1注解的应用场景
aop包查看是否存在。
//等价于<bean id="user" class="com.kuang.pojo.User"/>
@Component
@Scope("singleton")
public class User {
// 相当于<property name="name" value="kuangshen"/>
@Value("8888")
public String name;
}
一些复杂的还是建议走配置文件,比如:
12.2注解说明:
-
自动装配的注解:
-
@Autowired:自动装配,通过类型,名字。
如果名字不唯一: @Qualifier(value = “cat11”) -
@Nullable:字段标记这个注解,说明这个注解可以为null。
-
@Resource(name = “dog11”):自动装配,通过名字,类型。
-
@Component:组件,说明这个类被spring管理了,作为一个bean。
- 属性的注入: @Value(“”) :为bean组件注入值。
- 三个衍生注解:@Controller,@Service,@Repository作用都和@Component一样,只是起一个标识的作用。
- @Scope() singleton,prototype
13.使用javaconfig实现配置
13.1配置类实现配置的步骤:
使用这样一个java配置类等价于配置文件:
package com.kuang.config;
import com.kuang.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;
//这个也会被spring托管,注册到容器,底层也是@Component
@Configuration //@Configuration表示这是一个配置类,类似之前的beans.xml
@ComponentScan("com.kuang.pojo")
@Import(MyConfig2.class)
public class MyConfig {
@Bean
public User getUser(){
return new User();
}
}
User类:
@Component
public class User {
private String name;
public String getName() {
return name;
}
@Value("萨科理解的")
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
'}';
}
}
测试类MyTest.java
import com.kuang.config.MyConfig;
import com.kuang.pojo.User;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class MyTest {
public static void main(String[] args) {
// 如果完全使用了配置类的方式去做,就只能通过AnnotationConfig 上下文来获取容器,通过配置类的class对象加载。
ApplicationContext context = new AnnotationConfigApplicationContext(MyConfig.class);
User user = context.getBean("getUser",User.class);
System.out.printf(user.getName());
}
}
这种纯java的配置方式,在SpringBoot中随处可见。
注解学习尽量去看源码,是在平时的学习中去养成。
13.2回顾:
1.所有的类都要放到bean里面。
2.所有的bean都要通过容器去取。
3.容器中的bean取出后就是一个对象。
Mybatis建议用xml去配,因为能够适应复杂的情况。
14.代理
代理模式是SpringAOP的底层【SpringAOP和SpringMVC】
代理模式的分类:
- 静态代理
- 动态代理
14.1.静态代理模式:
程序的一个原则:尽量不去改变原有的代码。
14.2.动态代理:
14.3代理类ProxyInvocationHandler.java
package com.kuang.demo04;
import com.kuang.demo03.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 setRent(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+"方法");
}
}
Client.java
public class Client {
public static void main(String[] args) {
//真实角色
UserServiceImpl userService = new UserServiceImpl();
//生成代理角色的类
ProxyInvocationHandler pih = new ProxyInvocationHandler();
//通过调用程序处理角色来处理我们要调用的接口对象
pih.setRent(userService);
UserService proxy = (UserService) pih.getProxy();
proxy.add();
}
}
别人问可以知道有InvocationHandler和Proxy这两个类,
- InvocationHandler这个类是用于生成动态实例的,通过设置要代理的对象(真实角色),动态生成代理类。
- InvocationHanler调用处理程序并返回一个结果。
- Proxy:提供动态代理类的静态方法。
15.AOP
15.1.什么是AOP?
15.2.使用spring实现AOP
使用AOP需要导入织入包:
<!-- 使用aop织入,需要导入的包-->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.4</version>
</dependency>
</dependencys>
在beans.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:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
</beans>
15.2.1方式一:使用原生的Spring API接口
定义后置日志:
package com.kuang.log;
import org.springframework.aop.AfterReturningAdvice;
import java.lang.reflect.Method;
public class AfterLog implements AfterReturningAdvice {
@Override
public void afterReturning(Object returnValue, Method method, Object[] objects, Object o1) throws Throwable {
System.out.println("执行了"+method.getName()+"方法,返回结果为:"+returnValue);
}
}
定义前置日志:
package com.kuang.log;
import org.springframework.aop.MethodBeforeAdvice;
import java.lang.reflect.Method;
public class Log implements MethodBeforeAdvice {
//method:要执行目标对象的方法
//objects:参数
//o:目标对象
@Override
public void before(Method method, Object[] objects, Object o) throws Throwable {
System.out.println(o.getClass().getName()+"的"+method.getName()+"被执行了");
}
}
在beans.xml中配置:
<!-- 方式一:使用原生的Spring API接口
配置aop:需要导入aop的约束 -->
<aop:config>
<!-- 切入点 expression表达式,execution(要执行的位置(修饰词 返回值 类名 方法名 参数))类.*(..)表示该类下的所有方法带参数-->
<aop:pointcut id="pointcut" expression="execution(* com.kuang.service.UserServiceImpl.*(..))"/>
<!-- 执行环绕增加,即要增加哪个类?切入到哪里?-->
<aop:advisor advice-ref="log" pointcut-ref="pointcut"/>
<aop:advisor advice-ref="afterlog" pointcut-ref="pointcut"/>
</aop:config>
切入点:在哪个地方去执行方法。
执行UserServiceImpl类的所有方法。两个点代表可以有任意的参数。
aop:advisor:执行环绕增加,即要增加哪个类?切入到哪里?
MyTest测试类:
import com.kuang.service.UserService;
import com.kuang.service.UserServiceImpl;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MyTest {
public static void main(String[] args) {
ApplicationContext cpx = new ClassPathXmlApplicationContext("beans.xml");
UserService userservice = cpx.getBean("userservice", UserService.class);
userservice.del();
}
}
15.2.2方式二:自定义diy类
public class DiyPointCut {
public void before(){
System.out.println("方法执行前");
}
public void after(){
System.out.println("方法执行后");
}
}
<!-- 方式二:自定义类 -->
<bean id="diy" class="com.kuang.diy.DiyPointCut"/>
<aop:config>
<!-- 自定义切面,ref:要引用的类-->
<aop:aspect ref="diy">
<!-- 切入点-->
<aop:pointcut id="pointcut" expression="execution(* com.kuang.service.UserServiceImpl.*(..))"/>
<!-- 通知-->
<aop:before method="before" pointcut-ref="pointcut"/>
<aop:after method="after" pointcut-ref="pointcut"/>
</aop:aspect>
</aop:config>
15.2.3方式三:使用注解方式实现AOP
package com.kuang.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.kuang.service.UserServiceImpl.*(..))")
public void before(){
System.out.println("====方法执行前=====");
}
@After("execution(* com.kuang.service.UserServiceImpl.*(..))")
public void after(){
System.out.println("=====方法执行后=====");
}
@Around("execution(* com.kuang.service.UserServiceImpl.*(..))")
public void around(ProceedingJoinPoint jp) throws Throwable {
System.out.println("环绕前");
Object proceed = jp.proceed();
Signature signature = jp.getSignature();//获得签名
System.out.println("signature:"+signature);
System.out.println("环绕后");
}
}
在beans.xml中注册并开启注解支持:
<!-- 注册注解方式的类-->
<bean id="annotationPointCut" class="com.kuang.diy.AnnotationPointCut"/>
<!-- 开启注解支持-->
<aop:aspectj-autoproxy/>
16.整合Mybatis
1.导入相关jar包:
整合Mybatis需要引入依赖:
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>2.0.2</version>
</dependency>
<!-- spring操作数据库,还需要一个spring-jdbc-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.2.0.RELEASE</version>
</dependency>
mybatis跟谁整合就-谁就行了
2.编写配置文件
2.1引入mybatis核心配置文件: 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核心配置文件-->
<configuration>
<typeAliases>
<package name="com.kuang.pojo"/>
</typeAliases>
<!-- Environments:多套环境,default可以选择其中一个环境作为默认的环境。-->
<!-- <environments default="development">-->
<!-- <environment id="development">-->
<!-- <transactionManager type="JDBC"/>-->
<!-- <dataSource type="POOLED">-->
<!-- <property name="driver" value="com.mysql.jdbc.Driver"/>-->
<!-- <!– 在xml文件中,&不能用,需要转义&。–>-->
<!-- <property name="url" value="jdbc:mysql://localhost:3306/mybatis?useSSL=true&useUnicode=true&characterEncoding=UTF-8"/>-->
<!-- <property name="username" value="root"/>-->
<!-- <property name="password" value="123456"/>-->
<!-- </dataSource>-->
<!-- </environment>-->
<!-- </environments>-->
<!-- <mappers>-->
<!-- <!– 注册xxxMapper.xml文件, 路径以/代替.–>-->
<!-- <mapper resource="com/kuang/mapper/UserMapper.xml"/>-->
<!-- </mappers>-->
</configuration>
注释的地方由整合后的spring(spring-dao.xml) 实现,mybatis配置文件中这部分的内容可以删掉,一般会留别名和设置(日志开启) 在mybatis-config.xml文件中。
2.2引入spring整合mybatis的配置文件: 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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
<!--DataSource:使用Spring的数据源替换Mybatis的配置
这里使用Spring提供的JDBC,有了数据源,自然要有数据源的属性-->
<bean id="datasource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="url" value="jdbc:mysql://localhost:3306/mybatis?useSSL=true&useUnicode=true&characterEncoding=UTF-8"/>
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</bean>
<!-- sqlSessionFactory :通过datasource得到sqlSessionFactory-->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="datasource"/>
<!-- 绑定mybatis配置文件-->
<property name="configLocation" value="classpath:mybatis-config.xml"/>
<property name="mapperLocations" value="classpath:com/kuang/mapper/*.xml"/>
</bean>
<!-- SqlSessionTemplate就是sqlSession :通过 sqlSessionFactory得到sqlSession-->
<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
<!-- 只能使用构造器注入sqlSessionFactory,因为它没有Set方法-->
<constructor-arg index="0" ref="sqlSessionFactory"/>
</bean>
<!-- 注入sqlSession-->
<bean id="userMapper" class="com.kuang.mapper.UserMapperImpl">
<property name="sqlSession" ref="sqlSession"/>
</bean>
</beans>
2.3引入spring的核心配置文件: 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:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
<import resource="spring-dao.xml"/>
<bean id="userMapper" class="com.kuang.mapper.UserMapperImpl">
<property name="sqlSession" ref="sqlSession"/>
</bean>
<bean id="userMapper2" class="com.kuang.mapper.UserMapperImpl2">
<property name="sqlSessionFactory" ref="sqlSessionFactory"/>
</bean>
</beans>
applicationContext.xml中调userMapper,然后调里面的方法就可以了。 spring-dao.xml以后就用于专注的操作数据库。
3.实体类,Mapper及xml文件和实现类
User
public class User {
private int id;
private String name;
private String pwd;
}
UserMapper
public interface UserMapper {
public List<User> selectUsers();
}
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">
<!--configuration核心配置文件-->
<mapper namespace="com.kuang.mapper.UserMapper">
<select id="selectUsers" resultType="user">
select * from User;
</select>
</mapper>
两种实现类,选择一种即可
为什么写实现类?
用来替换原来mybatis的操作(原来Mybatis在测试类中实现,现在移到实现类中了)。
两种实现类的区别?
第二中继承了SqlSessionDaoSupport ,里面自带有getSqlSession()方法
两个实现类都做原来mybatis做的事情。
1.UserMapperImpl
package com.kuang.mapper;
import com.kuang.pojo.User;
import org.mybatis.spring.SqlSessionTemplate;
import java.util.List;
public class UserMapperImpl implements UserMapper{
//所有的操作原来都使用sqlSession来执行,现在是SqlSessionTemplate,两者等价。
private SqlSessionTemplate sqlSession;
public void setSqlSession(SqlSessionTemplate sqlSession) {
this.sqlSession = sqlSession;
}
//原来在测试类中,现在mybatis的操作在这里面
@Override
public List<User> selectUsers() {
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
return mapper.selectUsers();
}
}
注册实现类:
<!-- 注入sqlSession-->
<bean id="userMapper" class="com.kuang.mapper.UserMapperImpl">
<property name="sqlSession" ref="sqlSession"/>
</bean>
2.UserMapperImpl2
package com.kuang.mapper;
import com.kuang.pojo.User;
import org.mybatis.spring.support.SqlSessionDaoSupport;
import java.util.List;
public class UserMapperImpl2 extends SqlSessionDaoSupport implements UserMapper{
@Override
public List<User> selectUsers() {
return getSqlSession().getMapper(UserMapper.class).selectUsers();
}
}
注册实现类:
<bean id="userMapper2" class="com.kuang.mapper.UserMapperImpl2">
<property name="sqlSessionFactory" ref="sqlSessionFactory"/>
</bean>
测试:
public class MyTest {
@Test
public void tets1() throws IOException {
// String resource = "mybatis-config.xml";
// InputStream is = Resources.getResourceAsStream(resource);
// SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
// SqlSession sqlSession = sqlSessionFactory.openSession(true);
// UserMapper mapper = sqlSession.getMapper(UserMapper.class);
// List<User> users = mapper.selectUsers();
// for (User user : users) {
// System.out.println(user);
// }
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
UserMapper userMapper = context.getBean("userMapper2", UserMapper.class);
for (User user : userMapper.selectUsers()) {
System.out.println(user);
}
}
}
17.Spring声明式事务
17.1回顾事务
事务的实现:要么改变原来的类,要么横切AOP去实现。
17.2配置声明式事务
在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:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
</beans>
tx就是事务的缩写。
配置事务:
<!-- 配置声明式事务-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="datasource"/>
</bean>
<!-- 结合AOP实现事务的织入-->
<!-- 配置事务的通知:-->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<!-- 给哪些方法配置事务?-->
<!-- 配置事务的传播特性:new propagation=-->
<tx:attributes>
<tx:method name="add" propagation="REQUIRED"/>
<tx:method name="delete" propagation="REQUIRED"/>
<tx:method name="update" propagation="REQUIRED"/>
<tx:method name="query" propagation="REQUIRED"/>
<tx:method name="*" propagation="REQUIRED"/>
</tx:attributes>
</tx:advice>
<!-- 配置事务切入-->
<aop:config>
<aop:pointcut id="txPointCut" expression="execution(* com.kuang.*.*(..))"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="txPointCut"/>
</aop:config>
这些代码是固定的,今后可以直接拿来用,只需要改动execution里面的切入类就可以了。
了解即可。