第四十五天:Spring01 配置bean标签+依赖注入+spring整合Mybaits

1. 概念相关

框架的学习思路

  1. 了解框架的作用
  2. 会用框架
    • 有哪些配置(重点、难点)
    • 少量API
    • 懂:学习其中原理
  • 咬牙坚持配的多了;自然就会了,记不住(live template)(笔记)

学习安排

SSM

  • S - Spring - 每一层
  • S - SpringMVC - WEB
  • M - Mybatis - DAO

Spring

  • IoC AOP 两大核心思想
  • 2天 IoC
  • 2天AOP
  • 源码分析

SpringMVC

  • 3天
  • 融合了所有web核心的技术点

Spring概念

1603440523744

  • Spring之父 Rod Johnson
    • EJB Enterprise Java Bean,sun公司提出来的大型web项目的架构
    • Expert One-on-One J2EE Design and Development 2002年 手把手教你怎么使用EJB开发大型web项目
    • Expert one-on-one J2EE Development without EJB 2004 手把手教你怎么不使用EJB开发大型web项目 (Spring的原型)
    • 官网:https://spring.io/projects
    • 课堂版本5.x

Spring架构

1603441503859

Spring优势

  • 方便解耦,简化开发

  • 方便集成各种优秀框架(不排斥、慢慢整合)

  • AOP(面向切面编程)编程的支持

  • 声明式事务的支持

  • Java源码是经典学习范例

  • 方便程序的测试(Spring整合junit)

Spring两大核心思想

  • IoC:Inverse of Control 控制反转
  • AOP:Aspect Oriented Programming 面向切面编程

IoC

  • 内聚耦合

    内聚:

    耦合:

  • Spring演化过程

    基于接口编程:service和dao之间高度耦合

    基于工厂:解除service和dao之间的耦合,但是带来的工厂和dao的耦合

    工厂+配置文件:解除了耦合,留下配置文件和dao/工厂耦合,这种耦合是我们期望的一种耦合方式

  • IoC 控制反转

    把对象的创建权从程序员自己new反转到了Spring容器创建并提供

2. Spring入门案例

2.1 配置依赖坐标
<dependencies>
    <!--
        配置Spring的依赖坐标
        会根据依赖传传递自动导入其依赖的其他坐标
     -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>5.1.9.RELEASE</version>
    </dependency>
</dependencies>
2.2 编写service/dao实现类和接口,service实现类中main方法测试
2.3 新建Spring的配置文件并配置

resources 右键 选择 new--》xml configration file --》Spring config(前提是Spring的依赖已经成功导入)

配置文件名称任意,习惯写法applicationcontext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!-- 把Bean装配进Spring容器
        id 唯一标识,任意起名,但是尽量使用提示的名字
        class  全限定类名(用于反射创建对象)
     -->
    <bean class="com.itheima.dao.impl.UserDaoImpl" id="userDao"/>
</beans>
2.4 创建Spring容器对象并获取bean对象
public class UserServiceImpl {

    public static void main(String[] args) {

        // 创建容器对象,并加载配置文件
        ApplicationContext app = new ClassPathXmlApplicationContext("classpath:beans.xml");

        // 从容器对象中获取bean对象
        UserDao userDao = (UserDao) app.getBean("userDao");

        // 使用获取的bean对象
        List<User> allUser = userDao.getAllUser();
    }
}

3. Spring配置-Bean标签

3.1 id&class属性

id:唯一标识,同一个Spring容器中不允许重复

class:全限定类名,用于反射创建对象

XML配置

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!-- 把Bean装配进Spring容器
        id 唯一标识,任意起名,但是尽量使用提示的名字
        class  全限定类名(用于反射创建对象)
     -->
    <bean class="com.itheima.dao.impl.UserDaoImpl" id="userDao"/>
</beans>

测试代码

public class UserServiceImpl {

    public static void main(String[] args) {

        // 创建容器对象,并加载配置文件
        ApplicationContext app = new ClassPathXmlApplicationContext("classpath:beans.xml");

        // 从容器对象中获取bean对象
        UserDao userDao = (UserDao) app.getBean("userDao");

        // 使用获取的bean对象
        List<User> allUser = userDao.getAllUser();
    }
}
3.2 name属性(了解)

XML配置

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!-- 
		把Bean装配进Spring容器
        bean可以定义多个名称,使用name属性完成,中间使用,分割

     -->
    <bean id="userService" name="userService1,userService2" class="com.itheima.service.impl.UserServiceImpl"/>
</beans>

测试代码

public class UserServiceImpl {

    public static void main(String[] args) {

        // 创建容器对象,并加载配置文件
        ApplicationContext app = new ClassPathXmlApplicationContext("classpath:beans.xml");

        // 从容器对象中获取bean对象
        UserDao userDao = (UserDao) app.getBean("userDao");

        // 使用获取的bean对象
        List<User> allUser = userDao.getAllUser();
    }
}
3.3 scope(重要但不需要配置)

控制Spring容器中的bean时单例还是多例的,默认单例,也是推荐的配置。

XML配置beans-scope.xml

<bean class="com.itheima.domain.User" id="user2" scope="singleton"/>
<bean class="com.itheima.domain.User" id="user1" scope="prototype"/>

类的单例和Spring中Bean的单例的区别

项目类的单例Spring中Bean的单例
概念同一个软件项目中,某个类的实例有且只能有一个整个Spring容器中,某个Bean的实例有且只能有一个
范围整个项目项目中的Spring容器
注意点一个类最多只能有一个实例一个Bean标签最多只能有一个实例。
但是多个Bean标签可以配置相同的class属性值,所以Spring中单例Bean对应的一个类可以有多个实例
<bean id="userService3" scope="singleton" class="com.itheima.service.impl.UserServiceImpl"/>
<bean id="userService33" scope="singleton" class="com.itheima.service.impl.UserServiceImpl"/>

测试代码

// 需求1:测试单例和多例的Bean分别在什么时候创建,请在beans_scope.xml配置并完成测试
// Spring会在创建Spring容器的时候创建所有单例的Bean
@Test
public void test01() {
    app = new ClassPathXmlApplicationContext("beans-scope.xml");
    User user1 = (User) app.getBean("user1");
    User user3 = (User) app.getBean("user1");
    User user2 = (User) app.getBean("user2");
	System.out.println(user1 == user3);
    System.out.println(user1 == user2);

    Object book = app.getBean("book");
    Object book2 = app.getBean("book");
    System.out.println("book = " + book);
    System.out.println("book2 = " + book2);


}

结论:

Spring容器在创建的时候,只会初始化并装配所有单例Bean。

3.4 lazy-init

思想重要,配置不重要

结论:Spring容器在创建的时候,只会初始化并装配所有非懒加载的单例Bean。

XML配置beans-lazy.xml

<bean class="com.itheima.domain.User" id="user" scope="singleton" lazy-init="true"/>

测试代码

// 需求2:单例Bean能不能在我们获取使用的时候再创建?如果可以请在beans_lazy.xml文件中配置并完成测试
// Spring会在初始化Spring容器的时候创建所有非懒加载的单例Bean
@Test
public void test02() {
    app = new ClassPathXmlApplicationContext("beans-lazy.xml");

    User user = (User) app.getBean("user");
    User user1 = (User) app.getBean("user");
}
3.5 depends-on(了解)

XML配置beans-order.xml

<!-- 把 user  book car 装配进Spring容器
    1. 默认情况下,Bean标签的配置顺序就是实例化顺序
    2. 通过配置depends-on属性,调整顺序;会先实例化属性中的bean,再实例化当前bean

    注意:
        这里仅仅是调整了bean的实例化顺序,无他。
 -->

<bean class="com.itheima.domain.Car" id="car" depends-on="user,book"/>

<bean class="com.itheima.domain.Book" id="book"/>

<bean class="com.itheima.domain.User" id="user"/>

测试代码

// 需求3:请按照User、Book、Car的顺序实例化三个Bean,请在beans-order.xml中配置并完成测试
@Test
public void test03() {
    app = new ClassPathXmlApplicationContext("beans-order.xml");
}

其他代码

public class User {

    public User(){
        System.out.println("User创建成功……");
    }
}
public class Book {
    public Book() {
        System.out.println("Book创建成功……");
    }
}
public class Car {
    public Car() {
        System.out.println("汽车创建成功……");
    }
}
3.6 init-method&destroy-mehtod(理解)

配置bean对象初始化的方法和销毁的方法

注意:

  1. 提前准备好两个方法,方法名任意 xxx yyy

    <bean id="userDao" class="com.itheima.dao.UserDao" init-method="xxx" destroy-method="yyy">
    
  2. 属性值不用带小括号

  3. 多例bean的生命周期不归Spring容器管理

3.7 对象的创建方式

Java中

public void test01(){

    // 1. 直接new 创建对象
    User user = new User();
    System.out.println("user = " + user);

    // 2. 通过工厂实例获取一个car对象
    CarFactory carFactory = new CarFactory();
    Car car = carFactory.getCar();
    System.out.println("car = " + car);

    Car car1 = carFactory.getCar();
    System.out.println("car1 = " + car1);


    // 3. 通过工厂静态方法获取一个car对象
    Car car2 = StaticCarFactory.getCar();
    System.out.println("car2 = " + car2);

    Car car3 = CarFactoryStatic.getCar();
    System.out.println("car3 = " + car3);
}

Spring中

无参构造

User user = new User();

对应Spring中配置

<bean id="user" class="com.itheima.daomian.User">

工厂实例

CarFactory carFactory = new CarFactory();
Car car = carFactory.getCar();

对应Spring中配置

<!-- 把CarFactory装配进Spring容器,创建CarFactory对象 --> 
<bean id="carFactory" class = "com.itheima.facotry.CarFactory"/>
<!-- 通过CarFactory对象,获取car对象 --> 
<bean id="car" factory-bean="carFactory" factory-method="getCar">

工厂静态

Car car = StaticCarFactory.getCar();

对应Spring中配置

<!-- 通过CarFactory的静态发昂发,获取car对象 --> 
<bean id="car" class = "com.itheima.facotry.StaticCarFactory" factory-method="getCar">
3.8 factory-bean& factory-method

用于指定工厂bean(容器中已经存在的一个bean)或者工厂中的创建对象的方法

3.9 工厂方式创建对象使用场景:

当某些对象的创建过程非常复杂(耗时、内存、性能)的时候,优先使用工厂的方式。

3.10 IoC思想总结

IOC

控制反转

控制:对象的创建权

反转:反转的就是对象的创建权

对象的创建权从程序员自己new的方式,反转成了spring读取配置文件并创建的方式。

我们如果需要使用,直接找Spring容器获取即可。

4. 依赖注入

4.1 概念

依赖:在A类中用到了B类,就说A依赖B;

依赖注入:Spring会把B类对象自动注入到A类中B类型的属性上,这就是依赖注入。Dependency Injection,DI。

// 伪代码演示
class A{
	// 自动为B类型的b变量初始化的过程,称为依赖注入
	B b = null;
}

依赖注入可以理解成IoC的一种应用场景,反转的是对象间依赖关系维护权

4.2 IoC和DI的关系(面试题)

IoC是一种思想(规范),可以把对象的创建权、对象间依赖关系的维护权等从程序员手中,反转到了Spring容器中;

DI依赖注入,只是IoC在某个方面的一个具体实现,在 依赖关系维护 方面的一个实现。

4.3 注入方式

本质上就是为某个类的成员变量赋值的方式:setter/有参构造

/*
	1. 直接为成员变量赋值,(成员变量一般都是private,不能被直接访问)----不推荐
    2. 提供有参构造方法,通过构造方法在创建对象的同时为成员变量赋值
    3. 提供setter,通过setter为成员变量赋值
*/

4.4 Setter方式注入

  1. 保证两个bean都已经装配到Spring容器

    <bean id="userDao" class="com.itheima.dao.impl.UserDao"/>
    <bean id="userService" class="com.itheima.dao.impl.UserServiceImpl"/>
    
  2. 在UserServiceImpl类中添加UserDao的属性并提供setter

    class UserServiceImpl{
        private UserDao xxx;
        
        // 属性指的是通过getter/setter方法名截取得到的,与成员变量名无关
        // 这个案例中,成员变量名就叫做userDao,和xxx、yyy无关
        public void setUserDao(UserDao yyyy){
            this.xxx = yyyy;
        }
        // 非Spring容器中存在的bean---普通类型
        private Integer num;
        public void setNum(int num1){
            this.num = num1;
        }
    }
    
    
  3. 通过<property>子标签完成注入

    <bean id="userDao" class="com.itheima.dao.impl.UserDao"/>
    <bean id="userService" class="com.itheima.dao.impl.UserServiceImpl">
        <!--  
    			name属性名,通过getter/getter截得
     		  	ref 当前Spring容器中已经存在的bean的id值
    	-->
    	<property name="userDao" ref=“userDao”/>
        <!-- 
    		注入普通类型(基本类型<包括其包装类> + String)  不是ref,而是使用value;
    		都要有有settter
    	-->
        <property name="num" value=“666”/>
    </bean>
    
    

4.5 p标签注入(本质是property)(了解)

需要导入p命名空间,写完p: + Alter&Enter

<bean class="com.itheima.service.impl.UserServiceImpl" id="userService"
      p:userDao-ref="userDao" p:num="666">
</bean>

对应Java代码

public class UserServiceImpl implements UserService {
    UserDao xxx;

    public void setUserDao(UserDao yyyy) {
        this.xxx = yyyy;
    }
    private Integer num;
    public void setNum(Integer num) {
        this.num = num;
    }
}

4.6 构造方法注入(了解)

public class UserServiceImpl implements UserService {

    private UserDao userDao;
    private int num;
    private String version;

    public UserServiceImpl(UserDao userDao, int num, String version){
        this.userDao = userDao;
        this.num = num;
        this.version = version;
    }
}

如果要使用构造器注入,建议使用name+ref/value,index/type不要用

<bean id="userService" class="com.itheima.service.impl.UserServiceImpl">
    <!--;使用构造方法进行注入,需要保障注入的属性与bean中定义的属性一致
    一致指顺序一致或类型一致或使用index解决该问题 -->
    <!--  推荐使用name + ref/value方式,见名知意好维护  -->
    <constructor-arg name="userDao" ref="userDao"/>
    <constructor-arg name="num" value="666666"/>
    <constructor-arg name="version" value="itcast"/>
</bean>
<!-- 下面的配置会默认找无参构造创建对象,如果没有无参构造,会报错 -->
<bean id="userService" class="com.itheima.service.impl.UserServiceImpl">

4.7 C标签注入(本质是构造器注入)(了解)

需要导入c命名空间,写完c: + Alter&Enter

<bean class="com.itheima.service.impl.UserServiceImpl" id="userService" c:num="777"
      c:xxx-ref="userDao"/>

4.8 集合注入(了解)

<bean class="com.itheima.domain.Book" id="book1">
    <property name="bookName" value="Java编程思想"/>
</bean>


<bean class="com.itheima.domain.Book" id="book2">
    <property name="bookName" value="新Java编程思想"/>
</bean>

<bean id="birth" class="java.util.Date"/>

<bean id="bmw" class="com.itheima.domain.Car">
    <property name="band" value="BMW"/>
</bean>


<!--
    单例集合  list  set  array
        配置通用  ,建议使用list
    双列集合  map properties
        配置通用 ,建议使用Map
-->

<bean class="com.itheima.domain.User" id="user" >
    <property name="username" value="张三"/>
    <property name="age" value="28"/>
    <!--<property name="birthday" ref="birth"/>-->
    <property name="birthday"  >
        <bean class="java.util.Date" />
    </property>
    <property name="car" ref="bmw"/>

    <!-- 书单 -->
    <property name="bookList">
        <list>
            <ref bean="book1"></ref>
            <bean class="com.itheima.domain.Book" >
                <property name="bookName" value="Java从入门到精通"/>
            </bean>
            <bean class="com.itheima.domain.Book"
                  p:bookName="Effective Java"/>
            <bean class="com.itheima.domain.Book" p:bookName="深入理解Java虚拟机"/>
            <bean class="com.itheima.domain.Book" p:bookName="颈椎病诊疗与自我康复"/>
        </list>
    </property>
    <!-- 昵称 -->
    <property name="nikeNameSet">
        <list>
            <value>程序员</value>
            <value>Programmer</value>
            <value>软件工程师</value>
            <value>码农</value>
            <value>IT民工</value>
            <value>修电脑的</value>
        </list>
    </property>

    <!-- 书单2-->
    <property name="shelfMap">
        <props>
            <prop key="111">2222</prop>
        </props>
    </property>

    <!--书单3-->
    <property name="bookProp">
        <map>
            <entry key="技术" value="程序员的自我修养"/>
            <entry key="生活" value="认识身体"/>
            <entry key="思维" value="刻意练习"/>
            <entry key="理财" value="从零开始学炒股"/>
            <entry key="思维" value="刻意练习"/>
            <entry key="娱乐" value="别做正常的傻瓜"/>
        </map>
    </property>
</bean>


4.9 SpEL

Spring Expression Language

简单,但是功能强大

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

    <bean class="com.itheima.domain.Car" id="car" p:color="">
        <property name="band" value="BMW"></property>
    </bean>
    <bean class="com.itheima.domain.User" id="user1" p:age="18"></bean>


    <!--
    [SpEL] Spring Expression Language
        Spring中的支持运行时查询和操作对象图的强大的表达式语言,语法类似于el。

            与EL类似,但是用法不同
            EL   是从域中取值  ${}
            SpEL 是从Spring容器中取值   #{}

        SpEl可以用在
            1. 配置文件中
            2. @Value("#{}")
            //3. 用在代码中(需要解析器)

        在SpEL可以操作内容
            字面值常量、
            引用其他bean、
            引用其他bean的某个属性值、
            调用非静态方法#{对象.非静态方法(参数列表)}
            调用静态方法#{T(全类名).静态方法(参数列表)}
            使用运算符
    -->
<!--
    <bean class="java.util.Date" id="date"/>
-->

    <bean class="com.itheima.domain.User" id="user">
        <property name="age" value="#{18-1}"/>
        <property name="car" value="#{car}"/>
        <property name="birthday" value="#{new java.util.Date()}"/>
        <property name="userId" value="#{T(java.util.UUID).randomUUID().toString()}"/>
    </bean>
</beans>

5. 引入properties文件

5.1 创建properties文件 jdbc.properties

# 不要使用username,否则会错误的获取到当前系统的用户名。建议使用jdbc.username
jdbc.username=root
pwd=123321

5.2 beans.xml文件引入 jdbc.properties文件

<!-- 在类路径下加载指定名称的properties配置文件 -->
<context:property-placeholder location="classpath:data.properties"/>
<!-- 在类路径下加载所有的properties配置文件 -->
<context:property-placeholder location="classpath:*.properties"/>
<!-- 在类路径+jar包中(整个项目下)加载所有的properties配置文件
    统配会造成效率降低,速度变慢
 -->
<context:property-placeholder location="classpath*:*.properties"/>

<!--
    ${} 所有的框架都支持这个种写法,从当前容器对象中根据key获取值
    #{}  SpELl********

    Spring容器会把当前系统的内置变量整合进自己的容器 username=当前系统的用户名
    ${username} 会获取当前系统的用户名
 -->
<bean class="com.itheima.dao.impl.UserDaoImpl" id="userDao">
    <property name="userName" value="${jdbc.username}"/>
    <property name="password" value="${pwd}"/>
</bean>

5.3 代码测试

ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");
UserDao userDao = (UserDao) ctx.getBean("userDao");
userDao.save();

6. 引入xml格式的Spring配置文件

配置文件拆分

  • 按照模块拆分 : user / book / xxx
  • 按照层级拆分:web / service /dao

xx**plicationContext.xml

    <!--
        所有的配置都写在一个配置文件中,会造成该文件很臃肿,不易管理。
        所以可以把配置文件拆分,然后再主的配置文件中引入其他分的Spring配置文件
        分层配置
            dao
            service
            web

        分模块配置
            user
            book
            order

        在主的配置文件中通过import标签的resource属性,引入其他的分配置文件

        或者在创建Spring容器对象的时候,一次性指定多个配置文件(此时没有主配置文件的概念)

    -->
<!--    <import resource="classpath:applicationContext-user.xml"/>
    <import resource="classpath:applicationContext-book.xml"/>
    <import resource="classpath:applicationContext-book2.xml"/>-->

    <bean class="com.itheima.dao.impl.UserDaoImpl" id="userDao">
        <property name="userName" value="${jdbc.username}"/>
        <property name="password" value="${pwd}"/>
    </bean>

applicationContext-user.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="userDao" class="com.itheima.dao.impl.UserDaoImpl">
        <property name="userName" value="${jdbc.username}"/>
        <property name="password" value="${pwd}"/>
    </bean>

    <bean id="userService" class="com.itheima.service.impl.UserServiceImpl">
        <property name="userDao" ref="userDao"/>
    </bean>
</beans>

测试类

public class UserApp {
    public static void main(String[] args) {
        //ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
        ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext-user.xml","applicationContext.xml");
        UserService userService = (UserService) ctx.getBean("userService");
        userService.save();
    }
}

注意:

  • 一个Spring核心配置文件中不能出现两个相同id的bean
  • 多个Spring核心配置文件,如果出现了相同id的bean,后面的会覆盖前面的

7. ApplicationContext体系

/*
├─ BeanFactory
	├─xxxx .....	
        ├─ ApplicationContext
        │   ├── yyy.....
        │   │   ├── ClassPathXmlApplicationContext   类路径
        │   │   ├── FileSystemXmlApplicationContext  文件系统
        └─ zzzz....
            ├── AnnotationConfigApplicationContext  注解
*/

BeanFactory & ApplicationContext区别

  • 懒加载

8. Spring整合Mybatis

8.1 导入依赖坐标

pom.xml

<!-- 配置私服 -->

<!-- 配置各个依赖 -->
<dependencies>
    <!-- spring -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>5.1.9.RELEASE</version>
    </dependency>
    <!-- spring-jdbc -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-jdbc</artifactId>
        <version>5.1.9.RELEASE</version>
    </dependency>

    <!-- mybatis整合Spring的依赖 -->
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis-spring</artifactId>
        <version>1.3.0</version>
    </dependency>

    <!-- mybatis -->
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis</artifactId>
        <version>3.5.3</version>
    </dependency>

    <!-- mysql 数据库驱动 -->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.47</version>
    </dependency>

    <!-- druid数据源 -->
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>druid</artifactId>
        <version>1.1.16</version>
    </dependency>

    <!-- lombok -->
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.18.16</version>
        <scope>provided</scope>
    </dependency>

    <!-- junit -->
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
        <scope>test</scope>
    </dependency>

</dependencies>

8.2 Spring配置文件

  1. 导入外部的properties文件
  2. 装配DruidDataSource
  3. 装配AccountDao(不需要我们自己搞)、AccountService接口的实现类
  4. 整合Mybatis核心配置文件

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

    <!--加载perperties配置文件的信息-->
    <context:property-placeholder location="classpath:jdbc.properties"/>
    
    <!--装配DruidDataSource进Spring容器-->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="driverClassName" value="${jdbc.driver}"/>
        <property name="url" value="${jdbc.url}"/>
        <property name="username" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
    </bean>

    
        
    <!--
		accountDao不需要我们自己创建并装配进Spring容器

		使用Mybatis,他会根据接口和映射配置文件,动态生成接口的代理对象并装配进Spring容器;
		这个代理对象就是我们要使用的accountDao对象
	-->
    
    <!--
		配置service作为spring的bean,注入dao
		ref 引用的是mybatis动态生成的accountDao代理对象,该对象的id默认为接口名
	-->
    <bean id="accountService" class="com.itheima.service.impl.AccountServiceImpl">
        <property name="accountDao" ref="accountDao"/>
    </bean>

    <!--
		SqlSessionFactoryBean:创建SqlSession的工厂的Bean
			spring整合mybatis后,可以使用该bean创建SqlSession,并最终获取到代理对象accountDao
		
		该bean对象 依赖数据源 所以注入druidDataSource
		之前在mybatis核心配置文件中的大部分内容,都是通过set方法注入的方式配置在该Bean中
		id可以省略不写,Spring会根据bean的类型自动查找到该Bean
	-->
    <bean class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource"/>
        <property name="typeAliasesPackage" value="com.itheima.domain"/>
    </bean>

    <!--
		MapperScannerConfigurer:映射的扫描配置,从哪个位置加载映射配置文件,并且装配到Spring容器中
		id可以省略不写,Spring会根据bean的类型自动查找到该Bean。
	-->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="com.itheima.dao"/>
    </bean>
</beans>

8.3 数据库连接参数配置

jdbc.properties

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/spring_db
jdbc.username=root
jdbc.password=itheima

8.4 POJO

Account.java

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Account /* implements Serializable */ {

    private Integer id;
    private String name;
    private Double money;
}

8.5 dao层接口和配置文件

AccountDao.java

public interface AccountDao {
    void save(Account account);
    void delete(Integer id);
    void update(Account account);
    List<Account> findAll();
    Account findById(Integer id);
}

AccountDao.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.itheima.dao.AccountDao">

    <!--配置根据id查询-->
    <select id="findById" resultType="account" parameterType="int">
        select * from account where id = #{id}
    </select>

    <!--配置查询所有-->
    <select id="findAll" resultType="account">
        select * from account
    </select>

    <!--配置保存-->
    <insert id="save" parameterType="account">
        insert into account(name,money)values(#{name},#{money})
    </insert>

    <!--配置删除-->
    <delete id="delete" parameterType="int">
        delete from account where id = #{id}
    </delete>

    <!--配置更新-->
    <update id="update" parameterType="account">
        update account set name=#{name},money=#{money} where id=#{id}
    </update>
</mapper>

8.6 service层接口&实现类

AccountService.java

public interface AccountService {
    void save(Account account);
    void delete(Integer id);
    void update(Account account);
    List<Account> findAll();
    Account findById(Integer id);
}

AccountServiceImpl.java

public class AccountServiceImpl implements AccountService {

    private AccountDao accountDao;

    // 提供setter,方便注入
    public void setAccountDao(AccountDao accountDao) {
        this.accountDao = accountDao;
    }

    public void save(Account account) {
        accountDao.save(account);
    }

    public void update(Account account){
        accountDao.update(account);
    }

    public void delete(Integer id) {
        accountDao.delete(id);
    }

    public Account findById(Integer id) {
        return accountDao.findById(id);
    }

    public List<Account> findAll() {
        return accountDao.findAll();
    }
}

8.7 测试类

App.java

public class App {
    public static void main(String[] args) {
        ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
        AccountService accountService = (AccountService) ctx.getBean("accountService");
        Account ac = accountService.findById(2);
        System.out.println(ac);

//        Account account = new Account();
//        account.setName("Tom");
//        account.setMoney(123456.78);
//
//        accountService.save(account);

   

9. getBean相关API

  • Object getBean(“beanName”)

    根据beanName(beanId)从spring容器中获取对象;只有存在对应的beanId,就可以获取成功;但是返回值为Object类型,需要强制类型转换

  • T getBean(Class<T> requiredType )

    根据class对象类型,从Spring容器中获取对象,不需要强制转换;但是,如果存在多个相同类型的对象,会报错:

    NoUniqueBeanDefinitionException: No qualifying bean of type 'com.itheima.service.AccountService' available: expected single matching bean but found 2: accountService1,accountService2
    
  • T getBean(String beanName, Class<T> requiredType )

    根据class对象类型 + beanId,从Spring容器中获取对象,不需要强制转换;但是,如果存在多个相同类型的对象,按照类型匹配之后,在根据beanId进行匹配,找到即返回。

10. 相关概念梳理

10.1 类&Bean(spring中的bean)

Java中最小的单位:类

Spring中最小的单位:Bean

10.2 JavaBean & POJO

都是用于封装并且传递数据的,VO、TO、DO……

JavaBean

  1. sun公司提出规范,为了规范数据传输的载体
  2. 类必须有一个无参构造
  3. 成员变量必须有getter/setter
  4. 可以序列化的,必须实现seriazable
  5. 有关图形化(GUI)内容,必须符合swing相关规范

POJO(普通的java类,Plain Ordinary Java Object)

  1. 阿里巴巴编码规约中表示,有成员变量及相关getter/setter/toString方法的类称之为POJO

args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext(“applicationContext.xml”);
AccountService accountService = (AccountService) ctx.getBean(“accountService”);
Account ac = accountService.findById(2);
System.out.println(ac);

// Account account = new Account();
// account.setName(“Tom”);
// account.setMoney(123456.78);
//
// accountService.save(account);






## 9. getBean相关API

- Object getBean("beanName")

  根据beanName(beanId)从spring容器中获取对象;只有存在对应的beanId,就可以获取成功;但是返回值为Object类型,需要强制类型转换

- T getBean(Class\<T\> requiredType )

  根据class对象类型,从Spring容器中获取对象,不需要强制转换;但是,如果存在多个相同类型的对象,会报错:

  ```shell
  NoUniqueBeanDefinitionException: No qualifying bean of type 'com.itheima.service.AccountService' available: expected single matching bean but found 2: accountService1,accountService2
  • T getBean(String beanName, Class<T> requiredType )

    根据class对象类型 + beanId,从Spring容器中获取对象,不需要强制转换;但是,如果存在多个相同类型的对象,按照类型匹配之后,在根据beanId进行匹配,找到即返回。

10. 相关概念梳理

10.1 类&Bean(spring中的bean)

Java中最小的单位:类

Spring中最小的单位:Bean

10.2 JavaBean & POJO

都是用于封装并且传递数据的,VO、TO、DO……

JavaBean

  1. sun公司提出规范,为了规范数据传输的载体
  2. 类必须有一个无参构造
  3. 成员变量必须有getter/setter
  4. 可以序列化的,必须实现seriazable
  5. 有关图形化(GUI)内容,必须符合swing相关规范

POJO(普通的java类,Plain Ordinary Java Object)

  1. 阿里巴巴编码规约中表示,有成员变量及相关getter/setter/toString方法的类称之为POJO
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值