Day14 学习Spring框架的简单使用

学习Spring框架的简单使用

官方文档:https://docs.spring.io/spring-framework/docs/current/spring-framework-reference/core.html#spring-core
中文文档:https://www.docs4dev.com/docs/zh/spring-framework/5.1.3.RELEASE/reference

  1. Spring框架的重点是Spring容器,将所有对象注册到容器中,需要用的时候再取
  2. 将原来需要new 的对象,直接在配置文件中注册,如果需要修改,就直接修改配置文件,而不需要修改程序,实现解耦
  3. 在配置文件中每一个对象,就是一个bean
  4. 配置文件application-config.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="对象的标识" class="对象的完全限定的类名">  
        <!-- 内部的参数(属性的设置),实际上采用的是set方法进行设置属性 -->
        <!-- ref标识引用类型  value表示基本类型和String类型 -->
        <property name="daouse" ref="daoimpl3"/>
    </bean>
</beans>

1. IOC(控制反转)

  1. 不是什么技术,而是一种设计思想
  2. Ioc意味着将你设计好的对象交给容器控制,而不是传统的在你的对象内部直接控制(new),实现解耦
  3. 简单使用,需要导入Spring的 maven依赖(maven会进行依赖导入,直接导入最大的就行)
<dependencies>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>5.0.18.RELEASE</version>
    </dependency>
</dependencies>
<bean id="daoimpl" class="com.xxx.dao.daoimpl"/>
<bean id="daoimpl2" class="com.xxx.dao.daoimpl2"/>
<bean id="daoimpl3" class="com.xxx.dao.daoimpl3"/>
<bean id="serviceimpl" class="com.xxx.service.serviceimpl">
	<!-- 这里可以修改ref的引用,就能修改程序的对象 -->
    <property name="daouse" ref="daoimpl2"/>
</bean>
  1. 使用时需要读取主配置文件,获取想要的对象
// 加载配置文件
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
// 在容器中获取id为serviceimpl的对象
serviceimpl simpl= (serviceimpl) context.getBean("serviceimpl");
simpl.show();

2. spring创建对象的方式(默认是单例,获取的是同一个对象)

  1. 默认使用无参构造创建对象
  2. 使用有参构造创建对象的几种形式
    - 根据类型传参 如果类型相同则按顺序赋值
<bean id="u2" class="com.xxx.pojo.User">
     <constructor-arg type="java.lang.String" value="xx1"/>
     <constructor-arg type="java.lang.String" value="1xx"/>
 </bean>
		- 根据索引传参(从0开始)
<bean id="u2" class="com.xxx.pojo.User">
 	<constructor-arg index="0" value="xx1"/>
    <constructor-arg index="1" value="1xx"/>
</bean>
		- 根据参数名称传参
<bean id="u2" class="com.xxx.pojo.User">
 	<constructor-arg name="add" value="xx1"/>
    <constructor-arg name="name" value="1xx"/>
</bean>

3. spring的简单配置

					- 别名   **既可以使用别名获取对象,也可以使用原来的**
<alias name="u1" alias="uuu"/>
					-  bean 的简单配置
<bean id="u1" class="com.xxx.pojo.User" name="可以取多个别名,用,/;/空格分隔" scope="作用范围常用的是singleton(单例,是同一个对象)/prototype(每次都会创建对象)">

scope官方介绍:

https://docs.spring.io/spring-framework/docs/current/spring-framework-reference/core.html#beans-factory-scopes

在这里插入图片描述

					- import 导入xml 进行合并
<import resource="bean1.xml"/>
<import resource="bean2.xml"/>

4. 依赖注入(DI)通过set 和 P命名空间(相当于set)和C命名空间(构造器)

  1. 复杂属性的注入(普通类型/String,null值,对象,数组,list,map,set,properties)
<bean id="" class="">
	<property name="基本类型和String" value=""/>
	<property name="String">
		<null/>
	</property>
	<property name="对象类型" ref="引用别的Bean"/>
	<property name="数组类型属性名">
		<array>
			<value>值1</value>
			<value>值2</value>
			<value>值3</value>
		</array>
	</property>
	<property name="list列表">
		<list>
			<value>值1</value>
			<value>值2</value>
			<value>值3</value>
		</list>
	</property>
	<property name="map类型">
		<map>
			<entry key="键1" value="值1"/>
			<entry key="键2" value="值2"/>
		</map>
	</property>
	<property name="set类型">
		<set>
	         <value>值1</value>
	         <value>值2</value>
	     </set>
	</property>
	<property name="properties类型">
        <props>
            <prop key="键1">值1</prop>
            <prop key="键2">值2</prop>
        </props>
    </property>
</bean>

p命名空间 在xml 中需要配置xml约束,才能使用

<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"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd">

<!-- 简化了<property name="" value=""> -->
<bean id="" class="" p:属性="value值" p:属性-ref="引用类型"/>   

c命名空间 在xml 中需要配置xml约束,才能使用

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    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">

<!-- 简化了<constructor-arg name="" value=""> -->
<bean id="" class="" c:属性="value值" c:属性-ref="引用类型"/>   

5. 在<bean autowire="">中设置自动装配

  1. autowire=“byName” :根据名字自动装配,但是需要beanid和set方法后面的属性相同
  2. autowire=“byType” : 根据类型自动装配,但是需要确保类型唯一,且和set方法的类型一致

6. 使用注解实现 自动装配(jdk1.9好像不支持@Resource)

  1. JDK1.9 使用@Resource 需要导入maven依赖
<dependency>
    <groupId>org.apache.tomcat</groupId>
    <artifactId>tomcat-annotations-api</artifactId>
    <version>9.0.13</version>
</dependency>
  1. 需要使用注解的约束
<?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>
  1. 使用固定的一句,支持注解
    context:annotation-config/
  2. 使用**@Autowired,@Qualifier,@Resource**
// 默认先按ByType进行匹配,如果太多,则按ByName进行匹配,找id为cat2的 
@Autowired
private Cat cat2;

// 默认required为true,在容器中找不到就报错,选择false则找不到不注入,但是使用时该对象是null
@Autowired(required = false)
private Cat cat2;

// 搭配 @Qualifier 可以指定查找id为cac的
@Autowired
@Qualifier("cac")
private Cat cat2;

// 默认先按ByName进行匹配,找id为dog2的,如果不匹配,则按ByType进行匹配,再不匹配就为null 
@Resource
private Dog dog2;

7. 其他重要注解(注册bean的,代替配置文件的。。)

  1. 产生Bean的注解,等价于
    **需要扫描包,进行使用注解对bean在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"
       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/>
    <!-- 扫描包,对使用注解的进行注册到容器中 等价于多个<bean ....>  -->
    <context:component-scan base-package="com.xxx.pojo"/>
    
</beans>

这4个注解作用一样,都能在spring容器中注册bean,

		- @Component  加在类上,产生bean   默认id为类名首字母小写
		- @Repository  
		- @Service    
		- @Controller
  1. 普通属性的注入 @Value 能作用在属性上也能作用在set方法上
@Value("xxx")
private String name;
@Value("xxx")
public void setName(String name) {
    this.name = name;
}
  1. 可以完全不用xml文件,使用配置类实现
@Configuration   // 表示该类是配置类,
@ComponentScan("com.xxx.pojo")   // 扫描包,注册bean,相当于<context:component-scan base-package="com.xxx.pojo"/>
@Import({xxx.class,ccc.class})  // 导入别的配置类,进行合并  相当于 <import resource=""/> 
public class MyConfig {
    @Bean   // 注册bean(一般用于非自己创建的类),默认的bean的id是方法名
    public User u(){
        System.out.println(123);
        return new User();
    }
}

@Component("u")      // 注册id为u的bean 且是单例的
@Scope("singleton")  // 单例模式
//@Scope("prototype")  // 每次都会创建一个新的对象
public class User {
    public User() {
        System.out.println(111);
    }

    @Value("xsw")   // 普通属性注入
    private String name;

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                '}';
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

// 使用注解读取配置的类    
ApplicationContext context = new AnnotationConfigApplicationContext(MyConfig.class);
User getuser = (User) context.getBean("u");
System.out.println(getuser);

8. aop(切面编程)

  1. 代理模式:静态代理模式在这里插入图片描述
public class Real implements CommomInterface{
	public void show(){
			System.out.println("真实对象的业务功能");
		}
}

public class StaticProxy implements CommomInterface{
		private Real real; // 真实对象 也实现了CommomInterface接口
		public void setReal(Real real){  // 注入真实对象
			this.real = real;
		}
		
		// 公共业务接口
		public void show(){
			System.out.println("代理做的额外的事情,如日志输出。。");
			real.show();  // 代理对象的show方法
		}
}

// 使用时
Real real = new Real();   // 创建真实对象
StaticProxy sp = new StaticProxy();  // 创建代理对象
sp.setReal(real);  // 将真实对象传给代理对象
sp.show();   // 此时代理对象 既能实现真实对象的方法也能实现额外的功能
  1. 动态代理模式(有基于类的和基于接口的)
    基于接口的实现
  • 第一步写公共接口
  • 第二步写真实对象
  • 第三步写调用处理器(传入真实对象,为真实对象的方法添加功能),这里实现之前静态代理的公共方法部分(实现接口InvocationHandler)
  • 第四步依靠调用处理器,生成动态代理类(通过Proxy动态生成
  • 执行真实对象的方法,会增加在调用处理器增加的功能
// 1. 公共接口
public interface Inter {
    void show();
    void find();
}
// 2.真实对象的类实现公共接口
public class web implements Inter {
    public void show() {
        System.out.println("web show");
    }
    public void find() {
        System.out.println("web find");
    }
}
// 3. 实现调用处理器接口 InvocationHandler 
public class proxyjdk implements InvocationHandler {
	// 真实对象
    private Object obj;
	// 使用有参构造 传入真实对象,即被代理对象
    public proxyjdk(Object obj){
        this.obj=obj;
    }
    // 动态实现代理方法
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("====== in proxy ======");
        // method 为调用什么方法 method就是什么 args 表示该方法的参数
        // 本质利用反射  
        result = method.invoke(obj,args);
        return result;
    }
}
//  测试
public static void main(String[] args) {
        // 生成被代理类
        Inter web = new web();
        // 调用处理器,传入被代理对象
        proxyjdk pj = new proxyjdk(web);
        // 4. 动态生成代理类实例对象(前两个参数固定,一个类加载器,一个真实对象的接口对象    只有最后一个参数不同,需要传入真实对象的处理器)
        Inter it = (Inter) Proxy.newProxyInstance(web.getClass().getClassLoader(), web.getClass().getInterfaces(), pj);
		
        it.find();
        System.out.println("=================");
        it.show();
    }
// 结果
====== in proxy ======
web find
=================
====== in proxy ======
web show

9. AOP实现动态代理(注意使用接口来接收生成的动态代理类)

  1. 增强类实现对应的接口,重写该方法
public class afterLog implements AfterReturningAdvice {
    public void afterReturning(Object o, Method method, Object[] objects, Object o1) throws Throwable {
        System.out.println(method.getName()+"方法执行了,返回值为: "+ o);
    }
}
/*
void afterReturning(@Nullable
                    Object returnValue,
                    Method method,
                    Object[] args,
                    @Nullable
                    Object target)
             throws Throwable
*/
<bean id="po" class="com.xxx.pojo"/>
<bean id="log" class="com.xxx.afterLog"/>
<!-- execution()表达式 返回值类型 包名.类名.方法名(参数类型)  * 表示任意类型 ..表示参数任意个 -->
<aop:config>
    <aop:pointcut id="point" expression="execution(* com.xxx.pojo.*(..))"/>
    <aop:advisor advice-ref="log" pointcut-ref="point"/>
</aop:config>
  1. 写普通类,使用切面定义
public class strong {
    public void beforeStrong(){
        System.out.println("before");
    }
    public void afterStrong(){
        System.out.println("after");
    }
    public void afterreturnStrong(){
        System.out.println("afterreturn");
    }
    //  环绕方法比较特殊 , 需要传入切点的对象, pj.proceed() 表示原方法的执行,并得到返回结果
    public Object around(ProceedingJoinPoint pj) throws Throwable {
        System.out.println("around");
        int proceed = (Integer)pj.proceed();
        return proceed;
    }
}
<bean id="po" class="com.xxx.pojo"/>
<bean id="str" class="com.xxx.strong"/>

<aop:config>
    <!-- 定义切面 (对象) -->
    <aop:aspect ref="str">
    	<!-- 定义切点 -->
        <aop:pointcut id="pointcut" expression="execution(* com.xxx.pojo.*(..))"/>
        <!-- 对切面的方法进行设置 前置增强 后置增强 after after-returning的执行顺序与配置的顺序有关 等等 -->
        <aop:before method="beforeStrong" pointcut-ref="pointcut"/>
        <aop:after method="afterStrong" pointcut-ref="pointcut"/>
        <aop:after-returning method="afterreturnStrong" pointcut-ref="pointcut"/>
        <aop:around method="around" pointcut-ref="pointcut"/>
    </aop:aspect>
</aop:config>
  1. 注解实现**(需要注解支持)** 需要将切面类在spring容器中注册为Bean对象
<!-- 注解支持 -->
<aop:aspectj-autoproxy/>
// 表示这是一个切面类
@Aspect
public class strong {
    @Before("execution(* com.xxx.pojo.*(..))")
    public void beforeStrong(){
        System.out.println("before");
    }
    @After("execution(* com.xxx.pojo.*(..))")
    public void afterStrong(){
        System.out.println("after");
    }
    //(after-returning先执行 after后执行)
    @AfterReturning("execution(* com.xxx.pojo.*(..))")
    public void afterreturnStrong(){
        System.out.println("afterreturn");
    }
    @Around("execution(* com.xxx.pojo.*(..))")
    public Object around(ProceedingJoinPoint pj) throws Throwable {
        System.out.println("around");
        int proceed = (Integer)pj.proceed();   // 执行真实对象的方法
        return proceed;  // 返回真实对象的执行结果
    }
}

10. 整合Mybatis-spring

mybatis-spring文档: http://mybatis.org/spring/zh/index.html

  1. 需要导入的jar包:
    数据库mysql驱动包,spring的包,mybatis的包,mybatis-spring的包,asj动态代理织入包,spring-jdbc操作数据库的包
<dependencies>
    <!-- 导入spring核心包(maven会依赖导入,直接导入最大的) -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>5.0.18.RELEASE</version>
    </dependency>
    <!--jdk1.9 的@Resource 注解支持-->
    <dependency>
        <groupId>org.apache.tomcat</groupId>
        <artifactId>tomcat-annotations-api</artifactId>
        <version>9.0.13</version>
    </dependency>
    <!--mysql驱动包-->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.47</version>
    </dependency>
    <!--mybatis的包 -->
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis</artifactId>
        <version>3.4.0</version>
    </dependency>
    <!--spring操作数据库的包-->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-jdbc</artifactId>
        <version>5.1.2.RELEASE</version>
    </dependency>
    <!--mybatis和spring整合的包-->
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis-spring</artifactId>
        <version>1.3.3</version>
    </dependency>
    <!-- aspectJ AOP 织入器 -->
    <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjweaver</artifactId>
        <version>1.8.6</version>
    </dependency>
</dependencies>

在这里插入图片描述
2. 先测试使用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="com.xxx.pojo"/>
    </typeAliases>
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/smbms?useUnicode=true&amp;characterEncoding=utf-8"/>
                <property name="username" value="root"/>
                <property name="password" value="123456"/>
            </dataSource>
        </environment>
    </environments>
    <!-- 注册映射器 -->
    <mappers>
        <mapper resource="userMapper.xml"/>
    </mappers>
</configuration>
<!-- 映射器配置文件 -->
<?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.xxx.mapper.UserMapper">
    <select id="selectAll" resultType="user">
        select * from user
    </select>
</mapper>
// 映射器对应的接口
public interface UserMapper {
    List<User> selectAll();
}
// pojo实体类
public class User {
    private int id;
    private String name;
    private String address;
}
// 测试代码
public static void main(String[] args) throws IOException {
	// 读取Mybatis的主配置文件, 最后得到 sqlSession 数据库连接对象
    InputStream ris = Resources.getResourceAsStream("mybatis-config.xml");
    SqlSessionFactory build = new SqlSessionFactoryBuilder().build(ris);
    SqlSession sqlSession = build.openSession();
	// 指定映射器的接口,执行对应的方法
    UserMapper mapper = sqlSession.getMapper(UserMapper.class);
    List<User> users = mapper.selectAll();
    for (User user : users) {
        System.out.println(user);
    }
}
  1. 第一步整合(省略sqlsessionFactory,sqlsession的创建,直接在容器中)

官网实例:http://mybatis.org/spring/zh/factorybean.html
3.1 第一步,先创建数据源对象(这里使用spring的)
3.2 第二步,创建sqlsessionFactory对象,传入数据源(必须要),可以设置别的(抛弃配置文件)或者导入配置文件
3.3 第三步,根据sqlsessionFactory对象,创建SqlSessionTemplate的对象(本质是sqlsession) 只能使用构造器注入
3.4 第四部, 就和使用Mybatis相似,获取mapper对象

<!-- 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"
       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
">
    <!-- 1.数据源,使用spring的 -->
    <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/smbms?useUnicode=true&amp;characterEncoding=utf-8"/>
        <property name="username" value="root"/>
        <property name="password" value="123456"/>
    </bean>
    <!-- 2.生成sqlsessionFactory对象 -->
    <bean id="sqlsessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="datasource"/>
        <property name="configLocation" value="classpath:mybatis-config.xml"/>
    </bean>
    <!-- 3.生成sqlsessinTemplent对象 即本质上是sqlsession对象 -->
    <bean id="sqlsession" class="org.mybatis.spring.SqlSessionTemplate">
        <!-- 只能通过构造器注入 -->
        <constructor-arg index="0" ref="sqlsessionFactory"/>
    </bean>
</beans>
<!-- mybatis的配置文件(其实可以全部在spring中设置) -->
<?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="com.xxx.pojo"/>
    </typeAliases>
    <mappers>
        <mapper resource="userMapper.xml"/>
    </mappers>
</configuration>
<!-- 映射器文件 -->
<?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.xxx.mapper.UserMapper">
    <select id="selectAll" resultType="user">
        select * from user
    </select>
</mapper>
// 测试代码
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
SqlSessionTemplate sqlsession = (SqlSessionTemplate) context.getBean("sqlsession");
UserMapper mapper = sqlsession.getMapper(UserMapper.class);
List<User> users = mapper.selectAll();
for (User user : users) {
  System.out.println(user);
}
  1. 使用接口的实现类丢到spring容器中,注入SqlSessionTemplate对象
<bean id="rere" class="com.xxx.mapper.aabbcc">
		<property name="sqlSession" ref="sqlsession"/>
</bean>
public class aabbcc implements UserMapper {
    private SqlSessionTemplate sqlSession;
    public void setSqlSession(SqlSessionTemplate sqlSession){
        this.sqlSession = sqlSession;
    }
   
    public List<User> selectAll(){
        return sqlSession.getMapper(UserMapper.class).selectAll();
    }
}
// 测试
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
aabbccabc = (aabbcc) context.getBean("rere");
List<User> users = abc.selectAll();
for (User user : users) {
    System.out.println(user);
}
  1. 使用接口自动生成映射器对象**(导入对应的约束)**

https://www.cnblogs.com/likeju/p/5323705.html

<?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:mybatis="http://mybatis.org/schema/mybatis-spring"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://mybatis.org/schema/mybatis-spring http://mybatis.org/schema/mybatis-spring.xsd
">
<!-- 配置自动扫描注解,base-package 扫描的包   mybatis:scan 需要容器中有sqlsessionFactory或者sqlsessionTemplate对象 -->
<mybatis:scan base-package="com.xxx.mapper"/>
<!-- 这两种自动扫描接口 动态生成实现类  效果相同 -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
    <property name="basePackage" value="com.inter"/>
    <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
</bean>

// 通过上面的自动扫描  将接口注册到spring中,动态生成映射器类
// 默认名字为首字母小写的类名,可以通过类型查找getBean(UserMappper.class)
public interface UserMapper {
    List<User> selectAll(User user);
    int addUser(User user);
    int deleteUser(int id);
}
// 测试代码
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
UserMapper bean = context.getBean(UserMapper.class);
// UserMapper bean = context.getBean("userMapper");
List<User> users = bean.selectAll(new User());
for (User user : users) {
    System.out.println(user);
}

11. 事务

http://mybatis.org/spring/zh/transactions.html

  1. 使用事务需要在spring的xml文件中加入tx约束
  2. 步骤1:要开启 Spring 的事务处理功能,在 Spring 的配置文件中创建一个 DataSourceTransactionManager 对象:
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
 	 <property name="datasource" ref="dataSource"/>
</bean>
  1. 步骤2 : 使用AOP实现动态添加事务
<!-- 配置事务管理器 -->
<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*" propagation="REQUIRED"/>
        <!--<tx:method name="select*" read-only="true"/>-->
        <tx:method name="*" propagation="REQUIRED"/>
    </tx:attributes>
</tx:advice>


<!-- 配置事务织入  -->
<aop:config>
    <aop:pointcut id="pointcut" expression="execution(* com.xxx.mapper.*.*(..))"/>
    <aop:advisor advice-ref="txadvice" pointcut-ref="pointcut"/>
</aop:config>
public class aabbcc implements UserMapper {

    private SqlSessionTemplate sqlSession;
    public void setSqlSession(SqlSessionTemplate sqlSession){
        this.sqlSession = sqlSession;
    }

    public List<User> selectAll(User user){
        addUser(user);
        deleteUser(8);
        return sqlSession.getMapper(UserMapper.class).selectAll(user);
    }

    public int addUser(User user) {
        return sqlSession.getMapper(UserMapper.class).addUser(user);
    }

    public int deleteUser(int id) {
        return sqlSession.getMapper(UserMapper.class).deleteUser(id);
    }
}
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
UserMapper abc = (UserMapper) context.getBean("rere");   // 需要使用接口来接收,因为生成了动态代理类
List<User> users = abc.selectAll(new User(0,"aaa","eeeee"));
for (User user : users) {
    System.out.println(user);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值