【SSM框架 二】Spring
文章目录
- 二、Spring
- 1、简介
- 2、IOC理论思想
- 3、Hello Spring
- 4、IOC创建对象的方式
- 4.1 无参构造构造器注入
- 4.2 有参构造器注入
- 5、Spring的配置
- 5.1 别名
- 5.2 Bean的配置
- 5.3 import
- 6、DI依赖注入
- 6.1 构造方法注入
- 6.2 set方法注入
- 6.3 扩展注入
- 6.4、Bean的作用域
- 7、Bean的自动装配
- 7.1 正常装配
- 7.2 自动装配
- 7.3 使用注解自动装配
- 7.3.1 要使用注解的准备
- 7.3.2 注解解释
- 8、使用注解开发
- 9、使用java的方式配置spring
- 10、代理模式
- 10.1 静态代理
- 10.2 动态代理
- 11、AOP实现方式
- 11.1 什么是AOP
- 11.2 Aop在Spring中的作用
- 11.3 使用Spring实现AOP
- 11.3.1 使用前需要导入依赖包
- 11.3.2 方式一:使用原生的spring api接口
- 11.3.3 方式二:自定义类
- 11.3.4 方式三:使用注解实现
- 12、整合Mybatis
- 12.1 回忆mybatis
- 12.2 mybatis-spring
- 12.3 获得SqlSession的方式二
- 13、声明式事务
- 13.1 spring中的事务管理
二、Spring
1、简介
Spring是一个轻量级的控制反转(IOC)和面向切面编程(AOP)的框架
2002年,首次推出Spring框架的雏形,interface21框架
2004年3月24日,Spring框架以interface21为基础,经过重新设计发布了1.0正式版
开源的免费框架
轻量级非入侵式框架
支持对事务的处理,对框架整合的支持
官方网站:https://spring.io/
5.2.23官方文档:https://docs.spring.io/spring-framework/docs/current/reference/html/
api文档:https://docs.spring.io/spring-framework/docs/current/javadoc-api/
老版本文档:https://docs.spring.io/spring-framework/docs/5.0.10.RELEASE/spring-framework-reference/(更改地址中间的版本号访问响应版本)
老版本jar包下载地址:https://repo.spring.io/ui/native/release/org/springframework/spring
github下载地址:https://github.com/spring-projects/spring-framework
maven仓库
<!-- 使用该库可以帮你下载其他spring的库(包含aop,beans,context,core,expression,web) --> <!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc --> <dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId><version>5.3.23</version> </dependency>
<!-- 和Mybatis整合时,需要的库 --> <!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc --> <dependency><groupId>org.springframework</groupId><artifactId>spring-jdbc</artifactId><version>5.3.23</version> </dependency>
2、IOC理论思想
IOC全称是Inversion of Control,控制反转
它是一种设计思想,由容器将设计好的对象交给容器控制,而非对象内部直接new
传统的Java设计中,直接会在对象的内部通过new进行对象的创建,是程序主动创建以来对象;
对Ioc来说,有一个专门的容器专门管理这些对象的生命周期,控制对象的创建;所以在Ioc中,是通过Ioc容器控制对象,由Ioc容器控制外部资源的获取
3、Hello Spring
bean.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/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd"><!-- id为bean对象的名字,可以随便取,和getbean()的参数保持一致-->
<!-- class为该bean对象的类型全限名--><bean id="hello1" class="com.daban.pojo.Hello">
<!-- 该对象里的属性赋值,实体类里必须有set方法,才可以-->
<!-- name为属性名-->
<!-- value为属性值(基本类型使用)-->
<!-- ref为引用另一个对象的bean的id(非基本类型使用)--><property name="str" value="我是注入的字符串"/><property name="t" ref="tid"/></bean><bean id="tid" class="com.daban.pojo.T"><property name="i" value="1"/></bean>
</beans>
测试类
import com.daban.pojo.Hello;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;public class Mytest {public static void main(String[] args) {// 获取spring的上下文对象// 参数可以有多个xml文件ApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans.xml");// 由上下文对象得到bean对象// 第一个参数为对象的名字(对应xml的bean标签中的id值)// 第二个参数为该bean对象的类型,避免了强制类型转换Hello hello = applicationContext.getBean("hello1", Hello.class);System.out.println(hello.toString());}
}
4、IOC创建对象的方式
4.1 无参构造构造器注入
默认使用无参构造器
4.2 有参构造器注入
三种方式,只能使用其中之一
变量索引+值的方式
<constructor-arg index="0" value="野山鸡">
类型+值的方式,如果两个String就不太好分辨,不推荐
<constructor-arg type="java.lang.String" value="野山鸡"/>
变量名+值的方式
<constructor-arg name="name" value="野山鸡"/>
总结:在配置文件被加载的时候,容器中管理的对象就已经被初始化了
5、Spring的配置
5.1 别名
给bean的id取一个别名。设置别名后,使用别名和原先的名字都可以
<alias name="user" alias="user2"/>
5.2 Bean的配置
属性 | 作用 | 备注 |
---|---|---|
id | bean的唯一标识,类似与对象名 | |
class | bean所对应的类全限名 | |
name | 取别名,可以取多个,和alisa标签类似 |
5.3 import
一般用于团队开发使用,把其他多个配置文件合并到一个配置文件中,加载配置文件时,只加载一个就行
<import resource="bean2.xml"/>
6、DI依赖注入
6.1 构造方法注入
详看《IOC创建对象的方式》
6.2 set方法注入
<?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"><bean id="student" class="com.daban.pojo.Student"><!--基本类型--><property name="name" value="青山"/><!--类类型--><property name="address" ref="address"/><!--数组类型--><property name="book"><array><value>西游记</value><value>三国演义</value><value>红楼梦</value><value>水浒传</value></array></property><!--列表类型--><property name="hobbys"><list><value>唱歌</value><value>弹吉他</value><value>骑行</value></list></property><!--map类型--><property name="card"><map><entry key="身份证" value="12345512351512553"/><entry key="银行卡" value="662522512525221"/></map></property><!--set类型--><property name="games"><set><value>吃鸡</value><value>LOL</value></set></property><!--properties类型--><property name="info"><props><prop key="username">张三</prop><prop key="password">112233</prop></props></property><!--null类型--><property name="wife"><null/></property></bean><bean id="address" class="com.daban.pojo.Address"><property name="address" value="陕西西安"/></bean>
</beans>
6.3 扩展注入
p命名空间注入(和set方法注入作用一样)
需要加入p的命名空间
xmlns:p=“http://www.springframework.org/schema/p”<bean id="user" class="com.daban.pojo.User" p:age="12" p:name="雪山"/>
c命名空间注入(和构造器方法注入作用一样)
需要加入c的命名空间
xmlns:c=“http://www.springframework.org/schema/c”<bean id="user" class="com.daban.pojo.User" c:age="12" c:name="青山"/> <bean id="user" class="com.daban.pojo.User" c:_0="青山" c:_1="13" />
6.4、Bean的作用域
bean标签的属性中设置scope
作用域 | 描述 | 备注 |
---|---|---|
singleton | 单例模式 | 每次从容器中get,就会的到同一个对象 |
prototype | 原型模式 | 每次从容器中get,就会的到一个新对象 |
request | 再一次请求中 | |
session | 再一次会话中 | |
application | 在一个应用中 |
7、Bean的自动装配
Spring中装配的三种方式
- 在xml中显式的配置
- 在java中显式的配置
- 隐式的自动装配
7.1 正常装配
<bean id="person" class="com.daban.pojo.Person"><property name="name" value="川崎"/><property name="cat" ref="cat"/><property name="dog" ref="dog"/>
</bean>
<bean id="cat" class="com.daban.pojo.Cat"/>
<bean id="dog" class="com.daban.pojo.Dog"/>
7.2 自动装配
<!-- 使用autowire属性来自动装配byName:查找该对象set方法后的值对应的beanid(保证id唯一)byType:查找该对象和自己属性类型相同的bean(有多个同类型,将无法装配,对应属性bean的id可以省略)
--><bean id="person" class="com.daban.pojo.Person" autowire="byName"><property name="name" value="川崎"/></bean><bean id="cat" class="com.daban.pojo.Cat"/><bean id="dog" class="com.daban.pojo.Dog"/>
7.3 使用注解自动装配
7.3.1 要使用注解的准备
导入需要的约束context
xm<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/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsd">
配置注解支持,加入如下,开能开启注解
<context:annotation-config/>
7.3.2 注解解释
注解 | 解释 | 备注 |
---|---|---|
@Autowired | 直接使用在需要装配的属性上 | 使用后可以省去set方法 |
@Qualifier(value = “xxx”) | 匹配id为value值的bean | 自动装配环境复杂bean不唯一时使用 |
@Resource | java的自动装配 | 先用名字查询,查不到使用类型 |
@Nullable | 该字段可以为null |
8、使用注解开发
使用注解必须保证aop包的导入
必须导入约束context
<?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/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsd"><!-- 驱动支持,相当于开关--><context:annotation-config/>
<!-- 指定要扫描的包,这个包下的注解会生效--><context:component-scan base-package="com.daban.pojo"/>
注解 | 描述 | 备注 |
---|---|---|
@Component | 放在类上,说明被spring管理,将该类放在容器中 | 就是bean |
@Value(“XXX”) | 属性注入,属性上 | 复杂的属性建议使用配置文件 |
@Repository | 和@Component一样,只是在dao层使用这个 | |
@Service | 和@Component一样,只是在Service层使用这个 | |
@Controller | 和@Component一样,只是在Controller层使用这个 | |
@Scope(“xxx”) | bean的作用域 |
9、使用java的方式配置spring
实体类
package com.daban.pojo;import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
//@Component注册一个组件,在这里可以省略
@Component
public class User {@Value("hhhhh")private String name;public String getName() {return name;}public void setName(String name) {this.name = name;}@Overridepublic String toString() {return "User{" +"name='" + name + '\'' +'}';}
}
配置类
package com.daban.config;import com.daban.pojo.User;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;//@Configuration代表这是一个配置类,可省略
//@Bean相当于注册一个bean,id就是方法名,class就是方法返回值
@Configuration
public class MyConfig {@Beanpublic User getUser(){return new User();}
}
测试类
import com.daban.config.MyConfig;
import com.daban.pojo.User;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;public class MyTest {public static void main(String[] args) {ApplicationContext context = new AnnotationConfigApplicationContext(MyConfig.class);User user = context.getBean("getUser", User.class);System.out.println(user.toString());}
}
10、代理模式
SpringAOP的底层就使用代理模式
10.1 静态代理
角色分析:
- 抽象角色:一般会使用接口或抽象类来实现
- 真是角色:被代理的对象
- 代理角色:去代理正式角色,代理的过程中,会做一些附属操作
- 客户:访问代理对象的人
静态代理模式的优点:
- 可以是真是角色操作更加纯粹,不用关心一些公共业务
- 公共业务交给代理角色,实现了业务的分工
- 公共业务发生扩展时,方便集中管理
静态代理模式的缺点:
- 一个真实角色就要产生一个代理角色,代码量会翻倍,开发效率变低(使用动态代理解决)
代码步骤:
1、接口
package com.daban.demo01;public interface Rent {public void rent();
}
2、真实角色
package com.daban.demo01;public class Host implements Rent {private int NO;public Host() {}public Host(int NO) {this.NO = NO;}@Overridepublic void rent() {System.out.println(NO+"号房东要出租房子");}
}
3、代理角色
package com.daban.demo01;public class Proxy implements Rent{private Host host;public Proxy() {}public Proxy(Host host) {this.host = host;}@Overridepublic void rent() {seeHouse();fare();host.rent();}public void seeHouse(){System.out.println("中介带你看房");}public void fare(){System.out.println("收取中介费");}
}
4、客户端访问代理角色
package com.daban.demo01;public class Client {public static void main(String[] args) {Proxy proxy = new Proxy(new Host(2));proxy.rent();}
}
10.2 动态代理
- 动态代理和静态代理角色一样
- 动态代理类是动态生成的,不是我们创建的
- 动态代理分为两大类:
- 基于接口的动态代理:JDK动态代理【这里使用这个】
- 基于类的动态代理:cglib
基本示例:
接口:
package com.daban.demo02;public interface Rent {public void rent();
}
实现类:
package com.daban.demo02;public class Host implements Rent {private int NO;public Host() {}public Host(int NO) {this.NO = NO;}@Overridepublic void rent() {System.out.println(NO+"号房东要出租房子");}
}
动态生成类:
package com.daban.demo02;import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;//使用这个类自动生成代理类
public class ProxyInvocationHandler implements InvocationHandler {//被代理的接口private Rent rent;public void setRent(Rent rent) {this.rent = rent;}//生成得到的代理类public Object getProxy(){return Proxy.newProxyInstance(this.getClass().getClassLoader(), rent.getClass().getInterfaces(),this);}//处理代理实例,并返回结果@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {seeHouse();Object result = method.invoke(rent, args);fare();return result;}public void seeHouse(){System.out.println("中介带你看房");}public void fare(){System.out.println("收取中介费");}
}
测试类:
package com.daban.demo02;public class Client {public static void main(String[] args) {//真实角色Host host = new Host(3);//用这个来生成代理类ProxyInvocationHandler handler = new ProxyInvocationHandler();handler.setRent(host);//生成代理类Rent proxy =(Rent)handler.getProxy();proxy.rent();}
}
通用示例:
接口:
package com.daban.demo03;public interface UserService {void add();void delete();void update();void select();
}
实现类
package com.daban.demo03;public class UserServiceImp implements UserService{@Overridepublic void add() {System.out.println("增加用户");}@Overridepublic void delete() {System.out.println("删除用户");}@Overridepublic void update() {System.out.println("修改用户");}@Overridepublic void select() {System.out.println("查询用户");}
}
动态生成类(通用了):
package com.daban.demo03;import com.daban.demo02.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);}//处理代理实例,并返回结果@Overridepublic 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+"方法");}
}
测试类:
package com.daban.demo03;public class Client {public static void main(String[] args) {UserServiceImp userServiceImp = new UserServiceImp();ProxyInvocationHandler handler = new ProxyInvocationHandler();handler.setTarget(userServiceImp);UserService proxy = (UserService) handler.getProxy();proxy.add();}
}
11、AOP实现方式
11.1 什么是AOP
什么是AOP:面向切面编程
11.2 Aop在Spring中的作用
名词:
- 横切关注点:跨越应用程序多个模块的方法和功能。如日志,安全,缓存,事务
- 切面(ASPECT):横切关注点被模块化的对象,他是一个类。(例如Log类)
- 通知(Advice):切面必须要完成的工作,即它类中的一个方法。(例如Log类中的方法)
- 目标(Target):被通知对象。(接口)
- 代理(Proxy):向目标对象应用通知之后创建的对象。(生成的代理类)
- 切入点(PointCut):切面通知执行地点的定义
- 连接点(JointPoint):与切入点匹配的执行点
SpringAOP中,通过Advice定义横切逻辑,支持五种类型的Advice
通知类型 | 连接点 | 实现接口 |
---|---|---|
前置通知 | 方法方法前 | org.springframework.aop.MethodBeforeAdvice |
后置通知 | 方法后 | org.springframework.aop.AfterReturningAdvice |
环绕通知 | 方法前后 | org.aopalliance.intercept.MethodInterceptor |
异常抛出通知 | 方法抛出异常 | org.springframework.aop.ThrowsAdvice |
引介通知 | 类中增加新的方法属性 | org.springframework.aop.IntroductionInterceptor |
即,AOP在不改变源代码的情况下,增加新功能
11.3 使用Spring实现AOP
11.3.1 使用前需要导入依赖包
<!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver -->
<dependency><groupId>org.aspectj</groupId><artifactId>aspectjweaver</artifactId><version>1.9.9.1</version><scope>runtime</scope>
</dependency>
11.3.2 方式一:使用原生的spring api接口
- 准备业务接口
package com.daban.service;public interface UserService {void add();void delete();void update();void select();
}
- 准备业务实现类
package com.daban.service;public class UserServiceImp implements UserService{@Overridepublic void add() {System.out.println("增加了一个用户");}@Overridepublic void delete() {System.out.println("删除了一个用户");}@Overridepublic void update() {System.out.println("改变了一个用户");}@Overridepublic void select() {System.out.println("查询了一个用户");}
}
- 准备需要切入的类
package com.daban.log;
import org.springframework.aop.MethodBeforeAdvice;
import java.lang.reflect.Method;
//需要切入的类需要实现相应的接口,11.2中五种接口都可以,扮演不同的方式
public class Log implements MethodBeforeAdvice {/*** method:要执行的目标对象的方法* args:参数* target:目标对象*/@Overridepublic 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/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop.xsd"><!--注册bean--><bean id="userService" class="com.daban.service.UserServiceImp"/><bean id="log" class="com.daban.log.Log"/><bean id="afterLog" class="com.daban.log.AfterLog"/><!--方式一、使用原生的spring api接口--><!--配置aop,需要导入aop的约束--><aop:config><!--切入点配置--><!--expression表达式:execution(* com.daban.service.UserServiceImp.*(..))--><!--id为切入点的名字--><aop:pointcut id="pointcut" expression="execution(* com.daban.service.UserServiceImp.*(..))"/><!--执行环绕增加--><!--advice-ref:要切入的类--><!--pointcut-ref:要切入的位置--><aop:advisor advice-ref="log" pointcut-ref="pointcut"/><aop:advisor advice-ref="afterLog" pointcut-ref="pointcut"/></aop:config>
- 测试类
import com.daban.service.UserService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;public class MyTest {public static void main(String[] args) {ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");//动态代理类代理的是接口,所以这里使用UserService接口,而不使用实现类UserService userService = context.getBean("userService", UserService.class);userService.add();}
}
11.3.3 方式二:自定义类
- 准备业务接口,和方式一相同
- 准备业务接口的实现,和方式一相同
- 自定义一个类(切面)
package com.daban.diy;public class DiyPointcut {public void before(){System.out.println("********方法执行前********");}public void after(){System.out.println("========方法执行后========");}
}
- 准备配置文件
<?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/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop.xsd"><!--注册bean--><bean id="userService" class="com.daban.service.UserServiceImp"/><bean id="log" class="com.daban.log.Log"/><bean id="afterLog" class="com.daban.log.AfterLog"/><!--方式二、自定义类--><bean id="diy" class="com.daban.diy.DiyPointcut"/><aop:config><!-- 自定义切面,ref是要引用(切入)的类--><aop:aspect ref="diy"><!--切入点--><aop:pointcut id="pointcut" expression="execution(* com.daban.service.UserServiceImp.*(..)))"/><!-- method:要切入的方法,pointcut-ref:切入点--><aop:after method="after" pointcut-ref="pointcut"/><aop:before method="before" pointcut-ref="pointcut"/></aop:aspect></aop:config>
</beans>
- 测试类,和方式一相同
11.3.4 方式三:使用注解实现
- 准备业务接口,和方式一相同
- 准备业务接口的实现,和方式一相同
- 自定义一个类(切面)
package com.daban.diy;import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;@Aspect//标注这个类是一个切面
public class AnnotationPointCut {//设置切入点在要切入的方法上@Before("execution(* com.daban.service.UserServiceImp.*(..)))")public void before(){System.out.println("********注解方式方法执行前********");}@After("execution(* com.daban.service.UserServiceImp.*(..)))")public void after(){System.out.println("========注解方式方法执行后========");}
}
- 准备配置文件
<!--方式三、使用注解-->
<bean id="anntation" class="com.daban.diy.AnnotationPointCut"/>
<!-- 开启注解支持-->
<aop:aspectj-autoproxy/>
- 测试类,和方式一相同
12、整合Mybatis
12.1 回忆mybatis
步骤:
- 导入jar包
junit,mybatis,mysql数据库,spring相关,aop植入,mybatis-spring
<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.11</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId><version>5.3.23</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-jdbc</artifactId><version>5.1.9.RELEASE</version></dependency><dependency><groupId>org.aspectj</groupId><artifactId>aspectjweaver</artifactId><version>1.9.9.1</version></dependency><dependency><groupId>org.mybatis</groupId><artifactId>mybatis-spring</artifactId><version>2.0.2</version></dependency>
</dependencies>
- 写实体类
package com.daban.pojo;import lombok.Data;@Data
public class User {private int id;private String name;private String pwd;
}
- 写mybatis核心配置文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""https://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration><typeAliases><package name="com.daban.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/mybatis?useSSL=true&useUnicode=true&characterEncoding=utf-8"/><property name="username" value="root"/><property name="password" value="123456"/></dataSource></environment></environments><mappers><mapper resource="UserMapper.xml"/></mappers>
</configuration>
- 编写接口
package com.daban.mapper;import com.daban.pojo.User;import java.util.List;public interface UserMapper {public List<User> getUser();
}
- 编写接口对应的mapper文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Config 3.0//EN""https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.daban.mapper.UserMapper"><select id="getUser" resultType="user">select * from mybatis.user</select>
</mapper>
- 测试
import com.daban.mapper.UserMapper;
import com.daban.pojo.User;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Test;import java.io.IOException;
import java.io.InputStream;
import java.util.List;public class MyTest {@Testpublic void test() throws IOException {String resources = "mybatis-config.xml";InputStream resource = Resources.getResourceAsStream(resources);SqlSessionFactory build = new SqlSessionFactoryBuilder().build(resource);SqlSession sqlSession = build.openSession(true);UserMapper mapper = sqlSession.getMapper(UserMapper.class);List<User> user = mapper.getUser();for (User user1 : user) {System.out.println(user1);}}
}
12.2 mybatis-spring
- 导入jar包
- 写实体类
- 写mybatis核心配置文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""https://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration><typeAliases><package name="com.daban.pojo"/></typeAliases>
</configuration>
- 编写接口
package com.daban.mapper;import com.daban.pojo.User;import java.util.List;public interface UserMapper {public List<User> getUser();
}
- 编写接口对应的mapper文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Config 3.0//EN""https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.daban.mapper.UserMapper"><select id="getUser" resultType="user">select * from mybatis.user</select>
</mapper
- 编写接口的实现类
package com.daban.mapper;import com.daban.pojo.User;
import org.mybatis.spring.SqlSessionTemplate;import java.util.List;public class UserMapperImp implements UserMapper{private SqlSessionTemplate sqlSession;public void setSqlSession(SqlSessionTemplate sqlSession) {this.sqlSession = sqlSession;}@Overridepublic List<User> getUser() {UserMapper mapper = sqlSession.getMapper(UserMapper.class);return mapper.getUser();}
}
- 编写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"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"><!--使用DataSource数据源代理mybatis配置--><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?useSSL=true&useUnicode=true&characterEncoding=utf-8"/><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"/><!-- 绑定mybatis配置文件--><property name="configLocation" value="classpath:mybatis-config.xml"/><!-- 代替了在mybatis配置文件中的mapper注册--><property name="mapperLocations" value="classpath:UserMapper.xml"/></bean><!--这就是我们使用的sqlSession--><bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate"><!--由于没有set方法只能使用构造器注入--><constructor-arg index="0" ref="sqlSessionFactory"/></bean><bean id="userMapper" class="com.daban.mapper.UserMapperImp"><property name="sqlSession" ref="sqlSession"/></bean>
</beans>
- 测试
import com.daban.mapper.UserMapper;
import com.daban.pojo.User;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
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 {@Testpublic void test() throws IOException {ApplicationContext context = new ClassPathXmlApplicationContext("spring-dao.xml");UserMapper bean = context.getBean("userMapper",UserMapper.class);List<User> user = bean.getUser();for (User user1 : user) {System.out.println(user1);}}
}
12.3 获得SqlSession的方式二
参见官网http://mybatis.org/spring/zh/sqlsession.html#SqlSessionDaoSupport
13、声明式事务
13.1 spring中的事务管理
- 声明式事务:aop
<!-- 配置声明式事务-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><constructor-arg ref="dataSource"/>
</bean>
<!-- 结合aop实现事务的植入-->
<!-- 配置事务通知,需要导入tx约束-->
<tx:advice id="txAdvice" transaction-manager="transactionManager"><!-- 给哪些方法配置事务--><!-- 配置事务的传播特性,默认REQUIRED--><tx:attributes><tx:method name="add" propagation="REQUIRED"/><!-- 给所有方法配置--><tx:method name="*" propagation="REQUIRED"/></tx:attributes>
</tx:advice>
<!-- 配置事务的切入点-->
<aop:config><aop:pointcut id="txPointCut" expression="execution(* com.daban.mapper.*.*(..))"/><aop:advisor advice-ref="txAdvice" pointcut-ref="txPointCut"/>
</aop:config>
- 编程式事务:需要在代码中进行事务管理(需要改源代码)
【SSM框架 二】Spring相关推荐
- SSM框架:Spring
SSM框架:Spring 文章目录 前言 一.Spring 1. 简介 2. 优点 3. 组成 4. 拓展 二.IOC理论推导 1. IOC原型引入 2. IOC本质(基本思想) 三.HelloSpr ...
- JavaWeb学习之路——SSM框架之Spring(五)
前情提要请看JavaWeb学习之路--SSM框架之Spring(四) 整合Spring和Mybatis框架 1.在项目的 ...
- 超详细整合SSM框架--(Spring + Spring MVC + MyBatis)
超详细整合SSM框架--(Spring + Spring MVC + MyBatis) SpringMVC框架--文章跳转 Spring框架--文章跳转 Mybatis框架--文章跳转 整合思路 设计 ...
- JavaWeb学习之路——SSM框架之Spring(四)
SSM框架学习-Spring01 1,.Spring介绍 Spring 是一个开源框架,是为了解决企业应用程序开发复杂性而创建的.框架的主要优势之一就是其分层架构,分层架构允许您选择使用哪一个组件,同 ...
- ssm框架搭建连接mysql_从零开始搭建SSM框架(Spring + Spring MVC + Mybatis)
最近在回顾和总结一些技术,想到了把之前比较火的 SSM 框架重新搭建出来,作为一个小结,同时也希望本文章写出来能对大家有一些帮助和启发,因本人水平有限,难免可能会有一些不对之处,欢迎各位大神拍砖指教, ...
- 如何部署SSM框架(Spring+SpringMVC+MyBatis)到SAE(新浪云服务器)图文教程
在学习cocos2dx手游开发的过程中,为了实现用户注册.用户登陆和世界排行榜这些模块,需要用到服务器来搭建平台.以前都是 在本地搭建服务器,在本科期间使用过IIS和Tomcat,感觉在本地搭建服务器 ...
- SSM框架之Spring
1.Spring 1.1.简介 Spring: 春天,给软件行业带来了春天! 2002年, 首次推出了Spring框架的雏形: interface21框架! Spring框架即以interface21 ...
- 一步步教你整合SSM框架(Spring MVC+Spring+MyBatis)详细教程重要
前言 SSM(Spring+SpringMVC+Mybatis)是目前较为主流的企业级架构方案,不知道大家有没有留意,在我们看招聘信息的时候,经常会看到这一点,需要具备SSH框架的技能:而且在大部分教 ...
- SSM框架之Spring MVC(二)常用注解说明
一.常用注解 1.1RequestParam 1.1.1 使用说明 作用: 把请求中指定名称的参数给控制器中的形参赋值. 属性: value:请求参数中的名称. required:请求参数中是否必须 ...
最新文章
- redis key命名规范_Redis几个实战经验积累
- 使用C++实现Socket编程图片打包传输(修改)
- golang值为nil的channel
- 计算机将成为学生们的老师英语,七年级英语(牛津版)第一学期7A完成句子练习题...
- html5 json转字符串,web前端-js小记(5)-字符串及json
- Faceware 面部捕捉在Unity中的应用
- Qt for Android环境配置
- Python与机器视觉(x)图像差分-图像相减
- 关于VS 2008和.NET 3.5 Beta2新特性介绍
- oracle单列索引和组合索引性能测试
- 29muduo_net库源码分析(五)
- 14.链表中倒数第k个结点
- python的整数类型_Python 标准数据类型:Bytes
- IDEA相对路径没有效果的问题
- xxx科技有限公司_公司管理制度
- Matplot 常用函数总结
- 人间烟火气 最抚凡人心
- day01_xUtils+注解+动画
- idea 代码格式化 谷歌_Google Docsmaklet格式化代码
- SparkStreaming之Offset管理、胖包和瘦包提交
热门文章
- PICO-8学习日志Week2.0【利用PICO-8制作Pong】
- linux系统浏览器安装失败怎么办,Ubuntu 13.04 无法安装Chrome浏览器解决
- 拼多多的农研大赛,正在撬动下一个未来市场
- 243 mysql获取某个表中除了某个字段名外的所有字段名
- php技术座右铭,励志座右铭
- Js读取Cookie中指定字段的值,Js中读取某个Cookie,Js中根据Cookie的key得到对应的value,Js正则表达式匹配指定的Cookie
- 苹果手机邮箱怎么设置_企业邮箱怎么设置别名
- 阳光系统下载 移动硬盘打开很慢怎么办
- oracle重做日志详解,Oracle的重做日志
- iOS比较常用的第三方及实例