Spring
准备工作
- spring framework官方文档https://spring.io/projects/spring-framework
- maven导入的jar包,导这个包maven可以帮助我们导入很多其他的包。
<!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.3.22</version>
</dependency>
重点:控制反转(IOC)、面向切面(AOP)
控制反转(IOC)
代码举例说明控制反转(IOC)
- 创建好几个文件 ,
Hello
是一个简单类,ApplicationContext.xml
是Spring IOC 的一个配置文件,Mytest
是测试类 ,如下:
- Hello内容:
public class Hello {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Hello{" +
"name='" + name + '\'' +
'}';
}
}
- 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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- 在Java中的对象,在spring中统称为bean -->
<!--
java中创建对象(类):
类型 变量名 = new 类型();
Hello hello = new Hello();
对于bean来说:
id 相当于 变量名
class 就是new 的对象(类)
property相当于给对象(类)中的属性设置一个值
-->
<bean id="hello" class="com.zyp.pojo.Hello">
<property name="name" value="hello spring"/>
</bean>
</beans>
- Mytest内容:
public class Mytest {
public static void main(String[] args){
//获取Spring的上下文对象
//ClassPathXmlApplicationContext是通过“配置文件”获取上下文的实现类
ApplicationContext context=new ClassPathXmlApplicationContext("ApplicationContext.xml");
//我们的对象(类)都放在Spring中管理,我们需要使用的时候,直接去取出来
Hello hello =(Hello)context.getBean("hello"); //根据注册的时候的id来取
System.out.println(hello.toString());
}
}
上面的过程就是控制反转(IOC):
控制:原本的是由程序本身来控制对象(类)的创建,现在使用Spring后,由Spring来控制创建。
反转:程序本身不创建对象(类),而变成被动接受。
依赖注入:就是利用set方法、构造器注入等方式来进行注入。
基于以上,我们就可以不再需要通过修改程序,去创建不同的类,以实现不同的操作。我们只需要对配置文件进行配置。IOC即对象皆由Spring来创建、管理、装配。
IOC创建对象方式
现在用一个简单的对象(User)来举例:
public class User {
private String name;
public User(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Hello{" +
"name='" + name + '\'' +
'}';
}
}
当我们没有显式写有参构造的时候,我们默认是存在无参构造的,这时我们在bean里注册的时候要用无参构造创建对象的方式。如果我们的类中有有参构造,且没有再添加无参构造,就需要使用有参构造创建方式。
- 使用无参构造创建对象,setter注入(默认!)
<property name="name" value="这是bean无参构造方式创建对象"/>
- 使用有参构造方法
- 下标索引创建:
<constructor-arg index="0" value="这是有参构造的下标赋值"/>
- 类型创建:
<constructor-arg type="java.lang.String" value="这是有参构造的类型创建法"/>
- 参数名赋值创建:
<constructor-arg name="name" value="这是有参构造的参数名赋值创建法"/>
注意: 第二种基本不使用 ,第三种更常使用
Spring的配置
Bean的配置
<bean id="user" class="com.zyp.pojo.User" name="myuser1 myuser2,myuser3">
</bean>
id:是bean的唯一标识符,也是相当于对象的变量名
class:bean对象所对应的全限定名,包名+类
name:也是取别名,而且可以取多个别名,使用空格 逗号都能分隔
import
import一般用于团队开发使用,用于将外部的xml文件导入进来
<import resource="ApplicationContext.xml"/>
alias
用于给已注册的bean取别名
<alias name="user" alias="myuser"/>
说明:name="user"的user
是已注册的bean的id
依赖注入
Set注入
案例演示:
- 准备一个类,里面包含很多复杂属性。
public class Student {
private String name;
private Address address; //Address是我们自己写的地址类
private String[] books;
private List<String> hobbies;
private Map<String,String> card;
private Set<String> games;
private String wife;
private Properties info;
}
说明:类中有get set toString(),这里只是没有放上来。
- 接着,看看对于上面的Student类,我们在bean注册的时候要怎么使用set进行依赖注入
<!--这个bean会在下面被引用到-->
<bean name="address" class="com.zyp.pojo.Address">
<property name="address" value="zhongguo"/>
</bean>
<bean name="student" class="com.zyp.pojo.Student">
<!-- 1. 普通值的注入,value -->
<property name="name" value="zyp"/>
<!-- 2. bean的注入,ref -->
<property name="address" ref="address"/>
<!-- 3. 数组的注入 -->
<property name="books">
<array>
<value>红楼梦</value>
<value>水浒传</value>
<value>三国演义</value>
<value>西游记</value>
</array>
</property>
<!-- 4. List的注入 -->
<property name="hobbies">
<list>
<value>听歌</value>
<value>写代码</value>
<value>游戏</value>
</list>
</property>
<!-- 5. Map的注入 -->
<property name="card">
<map>
<entry key="身份证号码" value="123456"/>
<entry key="出生日期" value="2003-07-10"/>
</map>
</property>
<!-- 6. Set的注入 -->
<property name="games">
<set>
<value>lol</value>
<value>coc</value>
<value>cf</value>
</set>
</property>
<!-- 7. null的注入 -->
<property name="wife">
<null/>
</property>
<!-- 8. Properties的注入 -->
<property name="info">
<props>
<prop key="url">www.ssss.com</prop>
<prop key="username">beiyuan8</prop>
<prop key="password">123456</prop>
</props>
</property>
</bean>
构造器注入
关于构造器注入,就是IOC创建对象的之有参构造方法创建,这里不多赘述。
P标签注入
可以看成就是set注入的一种封装,类中必须有get方法
p标签的使用,需要在配置文件中引入xmlns:p="http://www.springframework.org/schema/p"
演示:
- 写一个简单类User
public class User {
private String name;
private int age;
private Address address;
public String getName() {
return name;
}
}
说明:类中有get set toString(),这里只是没有放上来。
- xml中使用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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd">
<!--这个bean会在下面被引用到-->
<bean id="address" class="com.zyp.pojo.Address">
<property name="address" value="zhongguo"/>
</bean>
<!--p命名空间注入-->
<bean id="user" class="com.zyp.pojo.User" p:name="zyp" p:age="20" p:address-ref="address"/>
</beans>
- 测试
public class Mytest {
public static void main(String[] args){
ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml");
User user=context.getBean("user", User.class);
System.out.println(user.toString());
}
}
c标签注入
可以看成就是构造注入的一个封装,类中必须有有参构造方法
p标签的使用,需要在配置文件中引入:xmlns:c="http://www.springframework.org/schema/c"
演示:
- 写一个简单类User
public class User {
private String name;
private int age;
private Address address;
public User() {
}
public User(String name, int age, Address address) {
this.name = name;
this.age = age;
this.address = address;
}
}
说明:__类中有get set toString(),这里只是没有放上来。
- xml中使用c命名空间注入
<?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">
<!--这个bean会在下面被引用到-->
<bean id="address" class="com.zyp.pojo.Address">
<property name="address" value="zhongguo"/>
</bean>
<!--c命名空间注入-->
<bean id="user" class="com.zyp.pojo.User" c:name="zyp" c:age="20" c:address-ref="address"/>
</beans>
- 测试
public class Mytest {
public static void main(String[] args){
ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml");
Student student=(Student)context.getBean("student");
User user=context.getBean("user", User.class);
System.out.println(user.toString());
}
}
自动装配
通过例子来演示:
准备三个类,Cat, Dog , People类
public class Cat {
public void shout(){
System.out.println("miaomiaomiao");
}
}
public class Dog {
public void shout(){
System.out.println("wanwanwan");
}
}
public class People {
private Dog dog;
private Cat cat;
private String name;
}
注意:peple类中省略了set方法。
byName
byName会自动在容器中已注册的bean里面查找,和类中设置了的set方法的的属性名对应的的bean的id
<bean id="dog" class="com.zyp.pojo.Dog"/>
<bean id="cat" class="com.zyp.pojo.Cat"/>
<!-- byName会自动在容器中已注册的bean里面查找,和类中设置了的set方法的的属性名对应的的bean的id-->
<bean id="people" class="com.zyp.pojo.People" autowire="byName">
<property name="name" value="hello world"/>
</bean>
上面的xml内容是为我们上面的三个类注册bean,可以看到我们使用了autowire="ByName"后,我们不再需要手动装配cat和dog,只需要bean的id能够对应上属性名就可以。前提是,这个属性拥有set方法。
byType
byType会自动在容器中已注册的bean里面查找,和类中属性的类型相同的bean
<bean id="dog" class="com.zyp.pojo.Dog"/>
<bean id="cat" class="com.zyp.pojo.Cat"/>
<!-- byType会自动在容器中已注册的bean里面查找,和类中属性的类型相同的bean-->
<bean id="people" class="com.zyp.pojo.People" autowire="byType">
<property name="name" value="hello world"/>
</bean>
注解实现自动装配
要使用注解,现有以下几个步骤:
- xml配置文件头部导入约束 (见下面代码块)
- 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.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!-- 开启注解支持 -->
<context:annotation-config/>
</beans>
使用:
- 在ioc容器中,我们只需要注册三个bean
<bean id="dog" class="com.zyp.pojo.Dog"/>
<bean id="cat" class="com.zyp.pojo.Cat"/>
<bean id="people" class="com.zyp.pojo.People">
<property name="name" value="hello world!"/>
</bean>
- 在People类中,对应属性上使用
@Autowired
注解
public class People {
@Autowired
private Dog dog;
@Autowired
private Cat cat;
private String name;
}
注意:此处省略了getter和setter方法
小结:对于@Autowired实现自动装配。当ioc容器中只注册了一个该类型的bean时,根据byType来实现装配。当ioc容器中注册存在多个同一类型的bean时,就根据byName来实现装配。
注解开发
注解说明
@Component
组件,放在类上面,等价于
与之对应了几个衍生注解: 其实都是@Component
,但是按照mvc三层架构,衍生不同的注解;
- 【service】@Service
- 【dao】@Repository
- 【controller】@Controller
@Value()
放在某个属性上面,相当于是属性的值的注入。等价于
-
@Scope("")
放在某个类上面, 声明作用域 -
@Autowired
自动装配,前面介绍过。
xml与注解的最佳实践
xml注册bean, 注解完成属性的注入
使用java的方式配置spring
实例
准备一个pojo的类User
package com.zyp.pojo;
import org.springframework.stereotype.Component;
@Component
public class User {
public String name="喜羊羊";
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
'}';
}
}
用Java实现配置类
- 创建一个类(MyConfiguration),作为配置类
- 使用注解
@Configuration
以及@Bean
,以及@Import()
package com.zyp.configuration;
import com.zyp.pojo.User;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@ComponentScan("com.zyp.pojo") //可以使用ComponentScan进行包扫描
@Import(MyConfiguration2.class)
public class MyConfiguration {
//相当于之前使用xml配置文件注册的一个bean标签
// 方法的名字就是bean的id
// 方法的返回值就是bean标签的class属性
@Bean
public User getUser(){
return new User();
}
}
@Configuration
说明这是一个配置类,相当于我们之前的xml@Bean
相当于之前使用xml配置文件注册的一个bean标签,方法的名字就是bean的id,方法的返回值就是bean标签的class属性。@Import()
相当于导入另外一个配置类,合并在一起使用。
测试与使用
import com.zyp.configuration.MyConfiguration;
import com.zyp.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(MyConfiguration.class);
User user =(User)context.getBean("getUser");
System.out.println(user.getName());
}
}
_说明: _如果使用的是java配置类,则需要使用AnnotationConfigApplicationContext
。并且getBean()方法的参数是bean的id,也就是对应java配置类文件中的方法名。
代理模式
静态代理
角色分析:
- 抽象角色:对应的是接口或者抽象类
- 真实角色:对应了接口的实现类 (业务逻辑)
- 代理角色:对接口实现类进行代理
- 客户
在代码中的体现:
- 抽象角色:对应的是接口或者抽象类
public interface UserService {
public void add();
public void delete();
public void update();
public void query();
}
- 真实角色:对应了接口的实现类 (业务逻辑)
public class UserServiceImpl implements UserService{
@Override
public void add() {
System.out.println("增加一个用户");
}
@Override
public void delete() {
System.out.println("删除一个用户");
}
@Override
public void update() {
System.out.println("修改一个用户");
}
@Override
public void query() {
System.out.println("查询一个用户");
}
}
- 代理角色:对接口实现类进行代理
public class UserServiceProxy implements UserService{
UserServiceImpl userServiceimpl;
public void setUserService(UserServiceImpl userService) {
this.userServiceimpl = userService;
}
@Override
public void add() {
log("add");
userServiceimpl.add();
}
@Override
public void delete() {
log("delete");
userServiceimpl.delete();
}
@Override
public void update() {
log("update");
userServiceimpl.update();
}
@Override
public void query() {
log("query");
userServiceimpl.query();
}
//增加一个日志函数,不改变原有业务的代码,在代理类中进行功能增添
public void log(String msg){
System.out.println("[Debug] "+msg+" 被调用了");
}
}
说明:增加一个日志函数,不改变原有业务的代码,在代理类中进行功能增添
- 客户
public class Client {
public static void main(String [] args){
UserServiceProxy userServiceProxy=new UserServiceProxy(); //代理类
userServiceProxy.setUserService(new UserServiceImpl()); //通过代理类使用业务操作
userServiceProxy.add();
userServiceProxy.delete();
userServiceProxy.update();
userServiceProxy.query();
}
}
动态代理
- 动态代理角色和静态代理的角色一样
- 动态代理分为两大类:基于接口的动态代理、基于类的动态代理
基于接口:jdk动态代理
基于类:cglib
java字节码实现:javasist
看一个使用动态代理的例子
- 抽象角色:接口(租房子这件事)
public interface Rent {
public void rent();
}
- 真实角色(接口实现类):房东
public class Host implements Rent{
@Override
public void rent() {
System.out.println("房东要出租房子!");
}
}
- 写一个类
ProxyInvocationHandler
,由这个类自动生成代理类
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 );
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
look();
Object result=method.invoke(rent, args); //动态代理的本质, 就是使用反射机制
fare();
return result;
}
private void look(){
System.out.println("中介带人看房");
}
private void fare(){
System.out.println("中介收手续费");
}
}
说明:look()函数和 fare()函数都是自己添加的,我们可以在Object invoke( )函数中添加其他代码
- 客户
public class Client {
public static void main(String[] args){
//真实角色(接口实现类)
Host host = new Host();
//这个类可以为我们后面生成代理类
ProxyInvocationHandler pih = new ProxyInvocationHandler();
//设置要代理的接口(传一个真实角色)
pih.setRent(host);
//获得一个动态生成的代理类
Rent proxy = (Rent)pih.getProxy();
proxy.rent();
}
}
动态代理模板
//使用这个类自动生成代理类
public class ProxyInvocationHandler implements InvocationHandler {
private Object target; //被代理的接口
//set方法设置要代理的接口
public void setTarget(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 {
Object result=method.invoke(target, args); //动态代理的本质, 就是使用反射机制
return result;
}
}
spring中的AOP实现
首先需要添加maven依赖:
<!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.6</version>
</dependency>
- 准备一个接口,和对应的接口实现类
public interface UserService {
void add();
void remove();
void update();
void query();
}
public class UserServiceImpl implements UserService{
@Override
public void add() {
System.out.println("增加了一个元素");
}
@Override
public void remove() {
System.out.println("删除了一个元素");
}
@Override
public void update() {
System.out.println("更新了一个元素");
}
@Override
public void query() {
System.out.println("查询一个元素");
}
}
- 写一个自定义aop类
public class div_log {
public void before(){
System.out.println("=========方法执行前==========");
}
public void after(){
System.out.println("=========方法执行后==========");
}
}
- 在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
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<bean id="userService" class="com.zyp.service.UserServiceImpl"/>
<bean id="log" class="com.zyp.log.div_log"/>
<aop:config>
<!-- 自定义切面: ref后面是要引用的类(bean)-->
<aop:aspect ref="log">
<!--定义切入点-->
<!--execution()内部表达的是 返回值任意 service包下的UserServiceImpl类的所有函数,函数参数任意-->
<aop:pointcut id="my_point" expression="execution(* com.zyp.service.UserServiceImpl.*(..))"/>
<!--method是aop类中的某个方法, point-ref是表示method方法对哪个切入点执行-->
<aop:before method="before" pointcut-ref="my_point"/>
<aop:after method="after" pointcut-ref="my_point"/>
</aop:aspect>
</aop:config>
</beans>
- 测试与结果
public class My_test {
public static void main(String[] args ){
ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml");
//注意:动态代理的是接口
UserService userService=(UserService) context.getBean("userService");
userService.add();
userService.query();
}
}
spring中的注解实现aop
首先需要添加maven依赖:
<!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.6</version>
</dependency>
- 准备一个接口,和对应的接口实现类
public interface UserService {
void add();
void remove();
void update();
void query();
}
public class UserServiceImpl implements UserService{
@Override
public void add() {
System.out.println("增加了一个元素");
}
@Override
public void remove() {
System.out.println("删除了一个元素");
}
@Override
public void update() {
System.out.println("更新了一个元素");
}
@Override
public void query() {
System.out.println("查询一个元素");
}
}
- 写一个自定义aop类,然后使用aop注解
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
@Aspect
public class div_log {
@Before("execution(* com.zyp.service.UserServiceImpl.*(..))")
public void before(){
System.out.println("=========(注解方式实现)方法执行前==========");
}
@After("execution(* com.zyp.service.UserServiceImpl.*(..))")
public void after(){
System.out.println("=========(注解方式实现)方法执行后==========");
}
}
- 在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
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<bean id="userService" class="com.zyp.service.UserServiceImpl"/>
<!--将aop类注册为一个bean-->
<bean id="div_log" class="com.zyp.log.div_log"/>
<!--开启注解支持-->
<aop:aspectj-autoproxy/>
</beans>
- 测试与结果
public class My_test {
public static void main(String[] args ){
ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml");
//注意:动态代理的是接口
UserService userService=(UserService) context.getBean("userService");
userService.add();
userService.query();
}
}
spring整合jdbc
- 首先需要准备jar包,maven
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.3.29</version>
</dependency>
- 数据源与sqlSessionFactory
<?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
http://www.springframework.org/schema/aop/spring-aop.xsd">
<!--数据源-->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/study?useSSL=true&useUnicode=true&characterEncoding=GBK"/>
<property name="username" value="root"/>
<!-- 密码改成自己的 -->
<property name="password" value="xxxxxxxxx"/>
</bean>
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<!--后面可以绑定一些mybatis的配置-->
<!--比如configuration、settings等等-->
<property name="configLocation" value="classpath:mybatis-config.xml"/>
<property name="mapperLocations" value="classpath:com/zyp/Mapper/*.xml"/>
</bean>
<bean id="userMapper" class="com.zyp.Mapper.UserMapperImpl2">
<property name="sqlSessionFactory" ref="sqlSessionFactory"/>
</bean>
</beans>
说明:**_<property name="dataSource" ref="dataSource"/>_**
_ 引用了前面的 _**_bean id="dataSource"_**
。
而**_<property name="sqlSessionFactory" ref="sqlSessionFactory"/>_**
_ 又引用了前面的 _**_bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"_**
- 接口配置UserMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--namespace 命名空间 使用其绑定一个Dao(Mapper)的接口-->
<mapper namespace="com.zyp.Mapper.UserMapper">
<!--一条查询语句-->
<!--id对应 namespace绑定的接口中的函数。 resultType对应pojo的实体类-->
<select id="selectUser" resultType="com.zyp.pojo.User">
select * from study.user
</select>
</mapper>
- 接口实现类
public class UserMapperImpl2 extends SqlSessionDaoSupport implements UserMapper{
@Override
public List<User> selectUser() {
return getSqlSession().getMapper(UserMapper.class).selectUser();
}
}
//等价写法
// SqlSession sqlSession=getSqlSession();
// UserMapper userMapper=sqlSession.getMapper(UserMapper.class);
// return userMapper.selectUser();
//
说明:这里UserMapperImpl2
类继承了SqlSessionDaoSupport
,从这个类中,可以直接继承获得getSqlSession()
函数,这个函数就是获取sqlSession。
- 测试与结果
public class My_test {
@Test
public void test(){
ApplicationContext context=new ClassPathXmlApplicationContext("spring-dao.xml");
UserMapper userMapper=context.getBean("userMapper", UserMapper.class);
for(User user: userMapper.selectUser()){
System.out.println(user);
}
}
}
- 目录结构