spring学习笔记(狂神说Java笔记)

一、IOC本质


控制反转loC(Inversion of Control),是一种设计思想,DI(依赖注入)是实现IoC的一-种方法,也有人认为DI只是IoC的另一种说法。没有IoC的程序中,我们使用面向对象编程,对象的创建与对象间的依赖关系完全硬编码在程序中,对象的创建由程序自己控制,控制反转后将对象的创建转移给第三方,个人认为所谓控制反转就是:获得依赖对象的方式反转了。


在这里插入图片描述


loC是Spring框架的核心内容,使用多种方式完美的实现了IoC,可以使用XML配置,也可以使用注解,新版本的Spring也可以零配置实现loC。Spring容器在初始化时先读取配置文件,根据配置文件或元数据创建与组织对象存入容器中,程序使用时再从Ioc容器中取出需要的对象。

控制反转是一种通过描述(XML或注解)并通过第三方去生产或获取特定对象的方式。在Spring中实现控制反转的是IoC容器,其实现方法是依赖注入(Dependency Injection,DI)。

<?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">
</beans>

控制:谁来控制对象的创建,传统应用程序的对象是由程序本身控制创建的,使用Spring后,对象是由Spring来创建的.
反转:程序本身不创建对象,而变成被动的接收对象.
依赖注入:就是利用set方法来进行注入的.
IOC是一种编程思想,由主动的编程变成被动的接收.
可以通过newClassPathXmlApplicationContext去浏览一下底层源码 .

OK ,到了现在,我们彻底不用再程序中去改动了,要实现不同的操作,只需要在xml配置文件中进行修改,所谓的loC,一句话搞定:对象由Spring来创建,管理,装配!


1、ioc创建对象的方式

​ 1.使用无参构造创建对象,默认!
​ 2.假设我们要使用有参构造创建对象。
​ 1.下标赋值

<bean id="user" class="com.wch.pojo.User">
  <constructor-arg index="0" value="wch"></constructor-arg>
</bean>

​ 2.类型

<bean id="user" class="com.wch.pojo.User">
  <constructor-arg type="java.lang.String" value="wch"></constructor-arg>
</bean>

​ 3.直接通过参数名

<bean id="user" class="com.wch.pojo.User">
  <constructor-arg name="name" value="wch"></constructor-arg>
</bean>

2、spring的配置

2.1 别名

<!--别名,如果添加了别名,我们也可以使用别名获取到这个对象-->
<alias name="user" alias="userNew"></alias>

2.2 Bean的配置

<!--
    id : bean的唯一 标识符,也就是相当于我们学的对象名
    class : bean对象所对应的全限定名:包名+类型
    name :也是别名,而且name可以同时取多个别名
-->
<bean id="userT" class="com.wch.pojo.UserT" name="user2,u2">
  <property name="name" value="123"></property>
</bean>

2.3 import

这个import, - 般用于团队开发使用,他可以将多个配置文件,导入合并为一个
假设,现在项目中有多个人开发,这三个人负责不同的类开发,不同的类需要注册在不同的bean中,我们可以利
用import将所有人的beans.xml合并为一个总的!

  • 张三
  • 李四
  • 王五
  • applicationContext.xml
<import resource="beans.xml"/>
<import resource="beans1.xml"/>
<import resource="beans1.xml"/>
<import resource="beans2.xml"/>

用的时候直接import

3. 依赖注入

3.1 构造器注入

​ 前边说过了

3.2 Set方法注入

  • 依赖注入:set注入
    1. 依赖:bean对象的创建依赖于容器
    2. 注入:bean对象中的所有属性,由容器注入

例子:(依照spring的官网提供的类型)

1、创建地址address的set、get、toString方法

private String address;

public String getAddress() {
  return address;
}

public void setAddress(String address) {
  this.address = address;
}
@Override
public String toString() {
  return "Address{" +
    "address='" + address + '\'' +
    '}';
}

2、创建学生student的属性方法等

private String name;
private Address address;
private String[] books;
private List<String> hobbies;
private Map<String, String> card;
private Set<String> games;
private String wife;
private Properties info;

3、Bean的注入

<!--第一种普通注入,用value值-->
<bean id="student" class="com.wch.pojo.Student">
  <property name="name" value="王成浩"/>
</bean>

4、注册测试类MyTest

ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
Student student = (Student) context.getBean("student");
System.out.println(student.getName());
//没有注入的属性的值是NULL
System.out.println(student.toString());

最后的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/beans
                           https://www.springframework.org/schema/beans/spring-beans.xsd">
  <!--第二种注入,ref-->
  <bean id="address" class="com.wch.pojo.Address">
    <property name="address" value="河北沧州"/>
  </bean>
  <!--第一种普通注入,用value值-->
  <bean id="student" class="com.wch.pojo.Student">
    <property name="name" value="王成浩"/>
    <property name="address" ref="address"/>
    <!--数组注入-->
    <property name="books">
      <array>
        <value>红楼梦</value>
        <value>水浒传</value>
        <value>西游记</value>
      </array>
    </property>
    <!--list注入-->
    <property name="hobbies">
      <list>
        <value>听歌</value>
        <value>美女</value>
        <value>游戏</value>
      </list>
    </property>
    <!--map注入-->
    <property name="card">
      <map>
        <entry key="身份证" value="132200122325134410"></entry>
        <entry key="银行卡" value="789456132110015677"></entry>
      </map>
    </property>
    <!--set-->
    <property name="games">
      <set>
        <value>LOL</value>
        <value>COC</value>
        <value>BOB</value>
      </set>
    </property>
    <!--null值注入-->
    <property name="wife">
      <null></null>
    </property>

    <property name="info">
      <props>
        <prop key="学号">17851100</prop>
        <prop key="性别"></prop>
        <prop key="身高">180</prop>
      </props>
    </property>
  </bean>
</beans>

3.3 扩展方式注入–(不重要)

我们可以使用p命令空间和c命令空间进行注入

官方文档:
在这里插入图片描述

创建的Uer类:

public class User {
  private String name;
  private Integer age;

  public User() {
  }

  public User(String name, Integer age) {
    this.name = name;
    this.age = age;
  }

  public String getName() {
    return name;
  }

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

  public Integer getAge() {
    return age;
  }

  public void setAge(Integer age) {
    this.age = age;
  }

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

beans.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"
       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">
  <!--user中不能没有无参的构造器-->
  <!--p命名空间注入,可以直接注入属性的值:property(注意上边还得有p的相关的xml约束)-->
  <bean id="user" clas="com.wch.pojo.User" p:name="wch" p:age="18"/>
  <!--user中得有有参的构造器才能用c标签-->
  <!--c命名空间注入,通过构造器注入: construct-args-->
  <bean id="user1" class="com.wch.pojo.User" c:name="wch1" c:age="17"/>
</beans>

测试方法:

@Test
public void Test1() {
  ApplicationContext context = new ClassPathXmlApplicationContext("beans1.xml");
  User user = (User) context.getBean("user1");
  System.out.println(user.toString());
}

注意点: p命名和c命名空间不能直接使用,需要导入xml约束!

xmlns:p="http://www.springframework.org/schema/p"
xmlns:c="http://www.springframework.org/schema/c"

ntext = new ClassPathXmlApplicationContext(“beans1.xml”);
User user = (User) context.getBean(“user1”);
System.out.println(user.toString());
}


==注意点: p命名和c命名空间不能直接使用,需要导入xml约束!==

```xml
xmlns:p="http://www.springframework.org/schema/p"
xmlns:c="http://www.springframework.org/schema/c"

4.bean的作用域

1、单例模式(spring的默认模式)

<bean id="student" class="com.wch.pojo.Student" scope="singleton">

2、原型模式:每次从容器中get的时候,都会产生一个新的对象

<bean id="student" class="com.wch.pojo.Student" scope="prototype">

3、其余的request、session. application. 这些个只能在web开发中使用到!

5.Bean的自动装配

  • 自动装配是spring满足bean依赖的一种方式
  • spring会在上下文中自动寻找,并自动给bean装配属性

在sprig中有三种装配方式

  1. 在xml中显示的配置
  2. 在java中显示的配置
  3. 隐式的自动装配bean【重要】

5.1测试

环境搭建:一个人有两种宠物–猫、狗

5.2ByName和ByType

<bean id="cat" class="com.wch.pojo.Cat"/>
<bean id="dog" class="com.wch.pojo.Dog"/>
<!--
    byName:会自动在容器上下文中查找,和自己对象set方法后面的值对应的beanid!
    byType:会自动在容器上下文中查找,和自己 对象属性类型相同的bean!
    -->
<bean id="person" class="com.wch.pojo.Person" autowire="byType">
  <property name="name" value="wch"/>
</bean>

小结:

  • byname的时候,需要保证所有bean的id唯一,并且这个bean需要和自动注入的属性的set方法的值一致!
  • bytype的时候,需要保证所有bean的class唯- -, 并且这个bean需要和自动注入的属性的类型一致!

5.3使用注解实现自动装配

jdk1 .5支持的注解,Spring2.5就支持注解了!
The introduction of annotation-based configuration raised the question of whether this approach is “better” than XML.
要使用注解须知: .
1.导入约束 context:约束
2.配置注解的支持 注意:context:annotation-config

<?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 id="cat" class="com.wch.pojo.Cat"/>
  <bean id="dog" class="com.wch.pojo.Dog"/>
  <bean id="person" class="com.wch.pojo.Person" autowire="byType"/>

</beans>

@Autowired
直接在属性上使用即可!也可以在set方式上使用!
使用Autowired我们可以不用编写Set方法了,前提是你这个自动装配的属性在I0C (Spring) 容器中存在,且符
合名字byname!
科普:

@Nullable字段标记 了这个注解,说明这个字段可以为null;

如果@Autowired自动装配的环境比较复杂,自动装配无法通过一个注解[ @Autowired]完成的时候、我们可以
使用@Qualifier(value=“xx”)去配置@Autowired的使用,指定-个唯一的bean对象注入!

小结:
@Resource(jdk11好像就已经移除了)和@ Autowired的区别:
●都是用来自动装配的,都可以放在属性字段上
●@ Autowired通过byType的方式实现,而且必须要求这个对象存在! [常用]
●@ Resource默认通过byname的方式实现,如果找不到名字,则通过byType实现!如果两个都找不到的情况下,就报错! [常用]
●执行顺序不同: @ Autowired通过byType的方式实现。@ Resource默认通过byname的方式实现。

6、使用注解开发

在Spring4之后,要使用注解开发,必须要保证aop的包导入了

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nZzDujgH-1604325648152)(image-20201101102109101.png)]

1、用bean注入

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
                           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:component-scan base-package="com.wch.pojo"/>
  <context:annotation-config/>
</beans>
//等价于<bean id="user"class="com.wch.pojo.User"/>
//@Component组件

@Component
public class User {
  public String name = "王成浩";
  @Value("河北沧州")
  public String address;
  public int age;

  @Value("18")
  public void setAge(int age) {
    this.age = age;
  }
}
public class MyTest {
  public static void main(String[] args) {
    ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
    User user = (User) context.getBean("user");
    System.out.println(user.name);
    System.out.println(user.address);
    System.out.println(user.age);
  }
}

3.衍生的注解

@Component有几个衍生注解,我们在web开发中,会按照mvc三层架构分层!
。dao [ @Repository]
。service [@Service]
。controller [ @Controller ]
这四个注解功能都是一样的,都是代表将某个类注册到Spring中, 装配Bean

4.自动装配置

- @Autowired :自动装配通过类型。名字
如果Autowi red不能唯一自动装配 上属性,则需要通过@Qualifier(value="xxx")
- @Nullable
字段标记了这个注解,说明这个字段可以为null;
- @Resource:自动装配通过名字。类型。

5.作用域

@Component
@Scope("prototype")
public class UserDao {    
}

6.小结

​ xmI与注解:
​ 。xml 更加万能,适用于任何场合! 维护简单方便
​ 。注解不是自己类使用不了,维护相对复杂!
​ xml与注解最佳实践:
​ 。xml用来管理bean;
​ 。注解只负责完成属性的注入;
​ 。我们在使用的过程中,只需要注意一个问题:必须让注解生效,就需要开启注解的支持

<!--指定扫描的包,这个包下的注解就会生效-->
<context:component-scan base-package="com.wch"/>
<context:annotation-config/>

7、代理模式

为什么要学习代理模式?因为这就是SpringAOP的底层! [SpringAOP 和SpringMVC]
代理模式的分类: .
● 静态代理
● 动态代理

7.1 静态代理

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ytk23z7D-1604325648155)(image-20201101140704982.png)]

角色分析:
● 抽象角色:一般会使用接口或者抽象类来解决
● 真实角色:被代理的角色
● 代理角色:代理真实角色,代理真实角色后,我们一般会做一些附属操作
● 客户:访问代理对象的人!

代码步骤:
1.接口

//接口
public interface Rent {
  void host();
}

​ 2.真实角色

//被代理类,房东的角色
public class House implements Rent {
  public void host() {
    System.out.println("房东要出租房子!");
  }
}

​ 3.代理角色

//代理类,中介的角色
public class Proxy implements Rent {

  private House house;

  public Proxy() {
  }

  public Proxy(House house) {
    this.house = house;
  }

  @Override
  public void host() {
    seeHouse();
    house.host();
    ht();
  }

  public void seeHouse() {
    System.out.println("中介带着去看房子");
  }

  public void ht() {
    System.out.println("中介带着你和房东签合同");
  }
}

​ 4.客户端访问代理角色

//你要租房子
public class person {
  public static void main(String[] args) {
    House house = new House();
    Proxy proxy = new Proxy(house);
    proxy.host();
  }
}

代理模式的好处: .
● 可以使真实角色的操作更加纯粹!不用去关注一 些公共的业务
● 公共也就就交给代理角色!实现了业务的分工!
● 公共业务发生扩展的时候,方便集中管理!

缺点:
● 一个真实角色就会产生- -个代理角色;代码量会翻倍开发效率会变低

具体代码实现;

public interface UserService {
  void add();
  void delete();
  void query();
  void modify();
}
public class UserServiceImpl implements UserService {
  @Override
  public void add() {
    System.out.println("实现了增加操作!");
  }
  @Override
  public void delete() {
    System.out.println("实现了删除操作!");
  }
  @Override
  public void query() {
    System.out.println("实现了查询操作!");
  }
  @Override
  public void modify() {
    System.out.println("实现了修改操作!");
  }
}
public class UserServiceProxy implements UserService {

  private UserServiceImpl userService;

  public void setUserService(UserServiceImpl userService) {
    this.userService = userService;
  }
  @Override
  public void add() {
    userService.add();
    massage("add");
  }
  @Override
  public void delete() {
    userService.delete();
    massage("delete");
  }
  @Override
  public void query() {
    userService.query();
    massage("query");
  }
  @Override
  public void modify() {
    userService.modify();
    massage("modify");
  }
  private void massage(String mge) {
    System.out.println("【日志】:使用了" + mge + "方法");
  }
}
public class Client {
  public static void main(String[] args) {
    UserServiceImpl userService = new UserServiceImpl();
    UserServiceProxy userServiceProxy = new UserServiceProxy();
    //这里用的是set方法将userService传进去
    userServiceProxy.setUserService(userService);
    userServiceProxy.add();
    userServiceProxy.delete();
    userServiceProxy.query();
    userServiceProxy.modify();
  }
}

7.2 动态代理

​ ●动态代理和静态代理角色一样
​ ●动态代理的代理类是动态生成的,不是我们直接写好的!
​ ●动态代理分为两大类:基于接口的动态代理,基于类的动态代理
​ 。基于接口-- JDK动态代理[我们在这里使用]
​ 。基于类: cglib
​ 。java字节码实现: javasist

需要了解两个类: Proxy: 代理,InvocationHandler: 调用处理程序

动态代理的好处: .
● 可以使真实角色的操作更加纯粹!不用去关注一些公共的业务
● 公共也就就交给代理角色!实现了业务的分工
● 公共业务发生扩展的时候,方便集中管理!
● 一个动态代理类代理的是一个接口,一般就是对应的一类业务

二、 AOP

1.什么是AOP

AOP (Aspect Oriented Programming)意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。AOP是0OP的延续,是软件开发中的一个热点,也是Spring框架中的- -个重要内容,是函数式编程的一种衍生范型。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。

1.2 Aop在Spring中的作用

提供声明式事务;允许用户自定义切面
● 横切关注点:跨越应用程序多个模块的方法或功能。即是,与我们业务逻辑无关的,但是我们需要关注的部分,就是横切关注点。如 日志,安全,缓存,事务等等…
● 切面(ASPECT) :横切关注点被模块化的特殊对象。即,它是一个类。
● 通知(Advice) :切面必须要完成的工作。即,它是类中的一个方法。
● 目标(Target) :被通知对象。
● 代理(Proxy) :向目标对象应用通知之后创建的对象。
● 切入点(PointCut) :切面通知执行的“地点”的定义。
● 连接点(JointPoint) :与切入点匹配的执行点。

1.3使用Spring实现Aop

[重点]使用AOP织入,需要导入一个依赖包!

<!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver -->
<dependency>
  <groupId>org.aspectj</groupId>
  <artifactId>aspectjweaver</artifactId>
  <version>1.9.6</version>
</dependency>

1、UserService

public interface UserService {
  public void add();

  public void delete();

  public void update();

  public void select();
}

2、UserServiceImpl

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 select() {
    System.out.println("查询了一个用户!");
  }
}

3、AfterLog

public class AfterLog implements AfterReturningAdvice {
  //returnValue:返回值
  @Override
  public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
    System.out.println("执行了," + method.getName() + "方法,返回结果为:" + returnValue);
  }
}

4、BeforeLog

public class BeforeLog implements MethodBeforeAdvice {
  //method:要执 行的目标对象的方法
  //args:参数
  //target:目标对象
  @Override
  public void before(Method method, Object[] args, Object target) throws Throwable {
    System.out.println(target.getClass().getName() + "的" + method.getName() + "被执行了!");
  }
}

5、xml

5.1方式一:只用spring的API接口,主要springAPI的接口实现

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
                           https://www.springframework.org/schema/beans/spring-beans.xsd
                           http://www.springframework.org/schema/aop
                           https://www.springframework.org/schema/aop/spring-aop.xsd">
  <!--注册bean-->
  <bean id="userService" class="com.wch.service.UserServiceImpl"/>
  <bean id="afterLog" class="com.wch.log.AfterLog"/>
  <bean id="beforeLog" class="com.wch.log.BeforeLog"/>
  <!--方式一:使用原生Spring API接口-->
  <!--配置aop:需要导入aop的约束-->
  <aop:config>
    <!--切入点: expression:表达式,execution(要执行的位置! *****)-->
    <aop:pointcut id="pointcut" expression="execution(* com.wch.service.UserServiceImpl.*(..))"/>
    <!--执行环绕增加! -->
    <aop:advisor advice-ref="beforeLog" pointcut-ref="pointcut"/>
    <aop:advisor advice-ref="afterLog" pointcut-ref="pointcut"/>
  </aop:config>
</beans>

5.2方式二:自定义来实现AOP,主要是切面定义

<!--方式二;自定义类-->
<bean id="diy" class="com.wch.diy.DiyPointCut"/>
<aop:config>
  <!--自定义切面,ref要引用的类-->
  <aop:aspect ref="diy">
    <!--切入点-->
    <aop:pointcut id="point" expression="execution(* com.wch.service.UserServiceImpl.*(..))"/>
    <!--通知-->
    <aop:before method="before" pointcut-ref="point"/>
    <aop:after method="after" pointcut-ref="point"/>
  </aop:aspect>
</aop:config>
public class DiyPointCut {
  public void before() {
    System.out.println("===执行方法之前===");
  }
  public void after() {
    System.out.println("===执行方法之后===");
  }
}

5.3方式三:使用注解实现

<!--方式三-->
<bean id="annotationPointCut" class="com.wch.diy.AnnotationPointCut"/>
<!--开启注解支持! JDK(默认proxy-target-class="false" cglib (proxy-target-class="true")-->
<aop:aspectj-autoproxy/>
@Aspect
public class AnnotationPointCut {

  @Before("execution(* com.wch.service.UserServiceImpl.*(..))")
  public void before() {
    System.out.println("====方法执行前====");
  }

  @After("execution(* com.wch.service.UserServiceImpl.*(..))")
  public void after() {
    System.out.println("====方法执行后====");
  }

  @Around("execution(* com.wch.service.UserServiceImpl.*(..))")
  public void around(ProceedingJoinPoint jp) throws Throwable {
    System.out.println("环绕前");
    Signature signature = jp.getSignature();
    System.out.println("signature:" + signature);
    Object proceed = jp.proceed();
    System.out.println("环绕后");
  }
}

6、Test

public class MyTest {
  public static void main(String[] args) {
    ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
    UserService userService = (UserService) context.getBean("userService");
    System.out.println("************************");
    userService.add();
    System.out.println("************************");
    userService.delete();
    System.out.println("************************");
    userService.update();
    System.out.println("************************");
    userService.select();
    System.out.println("************************");
  }
}

三、整合Mybatis

1.测试mybatis

步骤:
1.导入相关jar包
。junit
。mybatis
。mysq|数据库
。spring相关的
。aop织入
。mybatis-spring [new]
2.编写配置文件
3.测试

创建的sql表:

/*
 Navicat Premium Data Transfer

 Source Server         : localhost_3306
 Source Server Type    : MySQL
 Source Server Version : 80019
 Source Host           : localhost:3306
 Source Schema         : mybaties

 Target Server Type    : MySQL
 Target Server Version : 80019
 File Encoding         : 65001

 Date: 02/11/2020 11:20:53
*/

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for user
-- ----------------------------
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user`  (
  `id` int(0) NOT NULL,
  `name` varchar(30) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
  `pwd` varchar(30) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_unicode_ci ROW_FORMAT = Dynamic;

SET FOREIGN_KEY_CHECKS = 1;

相关的pom.xml依赖:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <parent>
    <artifactId>spring-study</artifactId>
    <groupId>org.wch</groupId>
    <version>1.0-SNAPSHOT</version>
  </parent>
  <modelVersion>4.0.0</modelVersion>
  <artifactId>spring-10-mybatis</artifactId>
  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.12</version>
    </dependency>
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>8.0.19</version>
    </dependency>
    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis</artifactId>
      <version>3.5.3</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>5.2.10.RELEASE</version>
    </dependency>
    <!--Spring操作数据库的话,还需要一个spring-jdbc-->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-jdbc</artifactId>
      <version>5.2.10.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.aspectj</groupId>
      <artifactId>aspectjweaver</artifactId>
      <version>1.9.6</version>
    </dependency>
    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis-spring</artifactId>
      <version>2.0.5</version>
    </dependency>
    <dependency>
      <groupId>org.projectlombok</groupId>
      <artifactId>lombok</artifactId>
      <version>1.18.10</version>
    </dependency>
  </dependencies>
  <build>
    <resources>
      <resource>
        <directory>src/main/java</directory>
        <includes>
          <include>**/*.properties</include>
          <include>**/*.xml</include>
        </includes>
        <filtering>true</filtering>
      </resource>
    </resources>
  </build>
</project>

创建步骤:
1、创建一个实体类

//这是一个实体类
@Data
public class User {
  private int id;
  private String name;
  private String pwd;
}

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">

<!-- 通过这个配置文件完成mybatis与数据库的连接 -->
<configuration>

  <typeAliases>
    <package name="com.wch.pojo"/>
  </typeAliases>
  <environments default="development">
    <environment id="development">
      <!--配置事务管理,采用JDBC的事务管理  -->
      <transactionManager type="JDBC"></transactionManager>
      <!-- POOLED:mybatis自带的数据源,JNDI:基于tomcat的数据源 -->
      <dataSource type="POOLED">
        <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost:3306/mybaties"/>
        <property name="username" value="root"/>
        <property name="password" value="000000"/>
      </dataSource>
    </environment>
  </environments>
  <mappers>
    <mapper class="com.wch.mapper.UserMapper"/>
  </mappers>
</configuration>

3、编写接口(UserMapper)以及接口对应的xml(UserMapper.xml)

public interface UserMapper {
  public List<User> selectUser();
}
<?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.wch.mapper.UserMapper">
  <select id="selectUser" resultType="user">
    select * from mybaties.user;
  </select>
</mapper>

4、在mybatis-config.xml中注册这个接口

<mappers>
  <mapper class="com.wch.mapper.UserMapper"/>
</mappers>

5、测试

public class MyTest {
  @Test
  public void Test() throws IOException {
    String resources = "mybatis-config.xml";
    InputStream inputStream = Resources.getResourceAsStream(resources);
    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
    SqlSession sqlSession = sqlSessionFactory.openSession(true);
    UserMapper mapper = sqlSession.getMapper(UserMapper.class);
    List<User> strings = mapper.selectUser();
    for (User s : strings) {
      System.out.println(s);
    }
  }
}

2.整合mybatis

<?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">
  <!--DataSource:使用Spring的数据源替换Mybatis的配置c3p0 dbcp druid
    我们这里使用Spring提供的JDBC:org.springframework.jdbc.datasource-->
  <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/mybaties"/>
    <property name="username" value="root"/>
    <property name="password" value="000000"/>
  </bean>
  <!--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/wch/mapper/*.xml"/>
  </bean>
  <!--SqlSessionTemplate:就是我们使用的sqlSession-->
  <bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
    <!--只能使用构造器注入sqlSessionFactory, 因为它没有set方法-->
    <constructor-arg index="0" ref="sqlSessionFactory"/>
  </bean>

  <bean id="userMapper" class="com.wch.mapper.UserMapperImpl">
    <property name="sqlSession" ref="sqlSession"/>
  </bean>
</beans>

<?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">
<!-- 通过这个配置文件完成mybatis与数据库的连接 -->
<configuration>
  <typeAliases>
    <package name="com.wch.pojo"/>
  </typeAliases>
</configuration>
<?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">
  <import resource="spring-dao.xml"/>
  <bean id="userMapper" class="com.wch.mapper.UserMapperImpl">
    <property name="sqlSession" ref="sqlSession"/>
  </bean>
</beans>
public class UserMapperImpl implements UserMapper {
  //我们的所有操作,都使用sqlSession来执行,在原来,现在都使用sqlSessionTemplate;
  private SqlSessionTemplate sqlSession;
  public void setSqlSession(SqlSessionTemplate sqlSession) {
    this.sqlSession = sqlSession;
  }
  @Override
  public List<User> selectUser() {
    UserMapper mapper = sqlSession.getMapper(UserMapper.class);
    return mapper.selectUser();
  }
}
@Test
public void Test1() {
  ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
  UserMapper userMapper = context.getBean("userMapper", UserMapper.class);

  for (User user : userMapper.selectUser()) {
    System.out.println(user);
  }
}

2.1整合mybaits

public class UserMapperImpl2 extends SqlSessionDaoSupport implements UserMapper {
  @Override
  public List<User> selectUser() {
    return getSqlSession().getMapper(UserMapper.class).selectUser();
  }
}
<bean id="userMapper2" class="com.wch.mapper.UserMapperImpl2">
  <property name="sqlSessionFactory" ref="sqlSessionFactory"/>
</bean>
@Test
public void Test1() {
  ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
  UserMapper userMapper = context.getBean("userMapper2", UserMapper.class);
  for (User user : userMapper.selectUser()) {
    System.out.println(user);
  }
}

四、声明式事务

1、回顾事务

  • 把一组业务当成一个业务来做;要么都成功,要么都失败!

  • 事务在项目开发中,十分的重要,涉及到数据的一致性问题,不能马虎!

  • 确保完整性和一致性;

    事务ACID原则: .
    ● 原子性
    ● 一致性
    ● 隔离性

    ​ 多个业务可能操作同一个资源,防止数据损坏

    ​ ● 持久性

    ​ 事务一旦提交,无论系统发生什么问题,结果都不会再被影响,被持久化的写到存储器中!

1、User

@Data
//这里的构造器一般用注解,我这注解有问题,用不了
public class User {
    private int id;
    private String name;
    private String pwd;

    public User() {
    }

    public User(int id, String name, String pwd) {
        this.id = id;
        this.name = name;
        this.pwd = pwd;
    }
}

2、UserMapper

public interface UserMapper {
  public List<User> selectUser();
  //增加一个用户
  public int addUser(User user);
  //删除一个用户
  public int deleteUser(int id);
}

3、UserMapperImpl

public class UserMapperImpl extends SqlSessionDaoSupport implements UserMapper {
  @Override
  public List<User> selectUser() {
    User user = new User(1, "wch", "000000");
    UserMapper mapper = getSqlSession().getMapper(UserMapper.class);
    //        mapper.addUser(user);
    mapper.deleteUser(2);
    return mapper.selectUser();
  }

  @Override
  public int addUser(User user) {
    return getSqlSession().getMapper(UserMapper.class).addUser(user);
  }

  @Override
  public int deleteUser(int id) {
    return getSqlSession().getMapper(UserMapper.class).deleteUser(id);
  }
}public class UserMapperImpl extends SqlSessionDaoSupport implements UserMapper {
  @Override
  public List<User> selectUser() {
    User user = new User(1, "wch", "000000");
    UserMapper mapper = getSqlSession().getMapper(UserMapper.class);
    //        mapper.addUser(user);
    mapper.deleteUser(2);
    return mapper.selectUser();
  }

  @Override
  public int addUser(User user) {
    return getSqlSession().getMapper(UserMapper.class).addUser(user);
  }

  @Override
  public int deleteUser(int id) {
    return getSqlSession().getMapper(UserMapper.class).deleteUser(id);
  }
}

4、mapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.wch.mapper.UserMapper">
  <select id="selectUser" resultType="user">
    select * from mybaties.user;
  </select>
  <insert id="addUser" parameterType="user">
    insert into mybaties.user (id,name,pwd ) values (#{id},#{name},#{pwd});
  </insert>
  <delete id="deleteUser" parameterType="int">
    delete from mybaties.user where id=#{id}
  </delete>
</mapper>

5、各个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">

  <import resource="spring-dao.xml"/>
  <bean id="userMapper" class="com.wch.mapper.UserMapperImpl">
    <property name="sqlSessionFactory" ref="sqlSessionFactory"/>
  </bean>
</beans>
<?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">

<!-- 通过这个配置文件完成mybatis与数据库的连接 -->
<configuration>
  <typeAliases>
    <package name="com.wch.pojo"/>
  </typeAliases>
</configuration>
<?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
                           https://www.springframework.org/schema/beans/spring-beans.xsd
                           http://www.springframework.org/schema/tx
                           http://www.springframework.org/schema/tx/spring-cache.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd">
  <!--DataSource:使用Spring的数据源替换Mybatis的配置c3p0 dbcp druid
    我们这里使用Spring提供的JDBC:org.springframework.jdbc.datasource-->
  <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/mybaties"/>
    <property name="username" value="root"/>
    <property name="password" value="000000"/>
  </bean>
  <!--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/wch/mapper/*.xml"/>
  </bean>
  <!--SqlSessionTemplate:就是我们使用的sqlSession-->
  <bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
    <!--只能使用构造器注入sqlSessionFactory, 因为它没有set方法-->
    <constructor-arg index="0" ref="sqlSessionFactory"/>
  </bean>
  <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" read-only="true"/>
      <tx:method name="*" propagation="REQUIRED"/>
    </tx:attributes>
  </tx:advice>
  <aop:config>
    <aop:pointcut id="txPoint" expression="execution(* com.wch.mapper.*.*(..))"/>
    <aop:advisor advice-ref="txAdvice" pointcut-ref="txPoint"/>
  </aop:config>
</beans>

6、测试类

public class MyTest {
  public static void main(String[] args) {
    ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
    UserMapper userMapper = context.getBean("userMapper", UserMapper.class);
    List<User> userList = userMapper.selectUser();
    for (User user : userList) {
      System.out.println(user);
    }
  }
}

7、pom.xml

<artifactId>spring-11-transaction</artifactId>
<dependencies>
  <dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.12</version>
  </dependency>
  <dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.19</version>
  </dependency>
  <dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis</artifactId>
    <version>3.5.3</version>
  </dependency>
  <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>5.2.10.RELEASE</version>
  </dependency>
  <!--Spring操作数据库的话,还需要一个spring-jdbc-->
  <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-jdbc</artifactId>
    <version>5.2.10.RELEASE</version>
  </dependency>
  <dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjweaver</artifactId>
    <version>1.9.6</version>
  </dependency>
  <dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis-spring</artifactId>
    <version>2.0.5</version>
  </dependency>
  <dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.18.10</version>
  </dependency>
</dependencies>
<build>
  <resources>
    <resource>
      <directory>src/main/java</directory>
      <includes>
        <include>**/*.properties</include>
        <include>**/*.xml</include>
      </includes>
      <filtering>true</filtering>
    </resource>
  </resources>
</build>
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Azure++

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值