天天看点

Spring day02Spring day02

Spring day02

0 复习

  1. 工厂设计模式
    工厂设计模式代替new方式创建对象,目的是解耦合。
  2. Spring做为工厂的使用

    applicationContext.xml配置bean标签

    如何从工厂中获取对象

    //创建工厂
    ApplicationContext ctx = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
    //从工厂中获取bean
    ctx.getBean("id值");
               
  3. 属性注入(Spring工厂创建对象的同时,为属性赋值)
    1. set注入
      1. 简单类型
        <bean id="id值" class="全类名">
        	<property name="属性名" value="简单属性值"/>
        </bean>
                   
      2. 复杂自定义类型
        <bean id="id值" class="全类名">
        	<property name="属性名" ref="另外一个bean的id"/>
        </bean>
                   
      3. 数组、List、Set
        <bean id="id值" class="全类名">
        	<property name="属性名">
            	<array>
                	<value>简单值</value>
                    <ref bean="另外一个bean的id"/>
                    ...
                </array>
            </property>
        </bean>
        
        <bean id="id值" class="全类名">
        	<property name="属性名">
            	<list>
                	<value>简单值</value>
                    <ref bean="另外一个bean的id"/>
                    ...
                </list>
            </property>
        </bean>
        
        <bean id="id值" class="全类名">
        	<property name="属性名">
            	<set>
                	<value>简单值</value>
                    <ref bean="另外一个bean的id"/>
                    ...
                </set>
            </property>
        </bean>
                   
      4. Map
        <bean id="id值" class="全类名">
        	<property name="属性名">
            	<map>
                	<entry key="键的值" value="简单值"/>
                    <entry key="键的值" value—ref="另外一个bean的id"/>
                </map>
            </property>
        </bean>
                   
      5. Properties
        <bean id="id值" class="全类名">
        	<property name="属性名">
            	<props>
                	<prop key="字符串的键">字符串的值</prop>
                    <prop key="字符串的键">字符串的值</prop>
                    ...
                </props>
            </property>
        </bean>
                   
    2. 构造注入
      <bean id="id值" class="全类名">
      	<constructor-arg value="简单值"/>
          <constructor-arg ref="另外一个bean的id"/>
      </bean>
      
      <bean id="id值" class="全类名">
      	<constructor-arg value="简单值" type="值的类型" index="0"/>
          <constructor-arg ref="另外一个bean的id" type="值的类型" index="1"/>
      </bean>
                 

1 注入补充【了解】

1.1 注入null值

需要显式的为一个属性赋null值时,需要使用null子标签。

<bean id="addr" class="com.baizhi.entity.Address">
    <constructor-arg value="硅谷"/>
    <constructor-arg><null></null></constructor-arg>
</bean>
           

1.2 内部bean

当一个bean只为另外一个bean使用时,可以写成内部bean的形式。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HH0XqYag-1630934265215)(Spring day02.assets/image-20200331110913137.png)]

2 FactoryBean技术(创建复杂对象)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RKGKHTwN-1630934265217)(Spring day02.assets/image-20210614212427106.png)]

当Spring工厂需要创建一些无法通过new直接创建的对象,就需要使用FactoryBean技术创建复杂对象。

通过完成Spring创建JDBC中Connection的需求,演示FactoryBean的使用步骤:

准备工作:pom.xml导入mysql-connector-java依赖

<dependency>
     <groupId>mysql</groupId>
     <artifactId>mysql-connector-java</artifactId>
     <version>8.0.23</version>
</dependency>
           
  1. 定义一个用于创建复杂对象的类,必须实现FactoryBean接口
    public class ConnectionFactoryBean implements FactoryBean<Connection> {
        @Override
        // 用于返回 创建的复杂对象
        public Connection getObject() throws Exception {
            Class.forName("com.mysql.jdbc.Driver");
            String url = "jdbc:mysql://localhost:3306/baizhi?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai";
            String username = "root";
            String password = "root";
    
            return DriverManager.getConnection(url,username,password);
        }
    
        @Override
        //返回 复杂对象的类型(类对象)
        public Class<?> getObjectType() {
            return Connection.class;
        }
    
        @Override
        //决定复杂对象是不是单例
        public boolean isSingleton() {
            return false;
        }
    }
               
  2. 配置上一步定义的FactoryBean
    <!--
            getBean("conn")获取不是ConnectionFactoryBean类型的对象,获取getObject()返回的复杂对象
         -->
    <bean id="conn" class="com.baizhi.factory.ConnectionFactoryBean"/>
               

注意:

  1. 复杂对象的单例控制,由isSingleton()方法返回值决定
  2. 通过getBean("&id属性"),可以获取自定义的FactoryBean对象

3 Spring的IOC和DI

IOC(Inversion of Control)控制反转、反转控制。

DI(Dependency Injection)依赖注入

控制:对于类中属性的赋值的控制权。

传统的正向控制:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-t7zk8FZ7-1630934265218)(Spring day02.assets/image-20210615224410283.png)]

正向控制存在的问题:类和类之间强耦合。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-B7iFdJek-1630934265219)(Spring day02.assets/image-20210615225645602.png)]

IOC和DI对同一件事,不同角度的描述。IOC更加偏重思想,DI更加偏重于实现手段。

IOC:属性的赋值权力从代码反转到Spring框架中。

DI:Spring通过依赖注入完成属性赋值。

3 Spring配置文件的拆分

3.1 applicationContext.xml的拆分

一个复杂的企业应用会拆分成多个模块,不同模块中有各自的spring配置,最终还需要聚合在一起。

classpath:JVM寻找类的起始路径,可以认为java、resources都是classpath。

3.2 Spring配置文件的xsd

XML的格式约束文件有2种:DTD(Document Type Definition)和XSD(XML Schema Definition)。XSD和DTD一样用来约束配置文件,DTD编写简单,XSD功能强大。

一般地,简单的配置文件用dtd约束(如Struts2的配置文件,MyBatis的配置文件),复杂的配置文件使用xsd约束(如Spring)。

  1. xsd的基本使用

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VEEO73ea-1630934265221)(Spring day02.assets/image-20200331154014258.png)]

  2. 在一个配置文件中使用多个xsd

    Spring不同的模块定义了不同的xsd文件,在一个Spring配置文件中使用多个模块的功能,也就要在配置文件中使用多个xsd。

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JF8z7brZ-1630934265222)(Spring day02.assets/image-20200331154803138.png)]

    使用步骤:

    1. 在跟标签中添加xmlns:前缀=“其它xsd的命名空间”
    2. 在xsi:schemaLocation=“添加路径对”
    3. 使用其它xsd中定义的标签需要添加

      前缀:

    示例:

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-81stK25t-1630934265224)(Spring day02.assets/image-20200331155251020.png)]

3.3 Spring 配置文件properties的拆分

程序中关于数据库的参数配置,一般都抽取到jdbc.properties文件中。Spring的applicationContext.xml中关于数据库的配置也一样要抽取。

  1. 将数据库参数抽取到jdbc.properties中
    driverClassName=com.mysql.jdbc.Driver
    url=jdbc:mysql://localhost:3306/baizhi?useUnicode=true&characterEncoding=utf-8
    user=root
    password=root
               
  2. 在Spring的配置文件中读取jdbc.properties
    <!-- 读取配置文件 使用context.xsd定义property-placeholder标签读取jdbc.properties文件-->
    <context:property-placeholder location="classpath:jdbc.properties"/>
               
  3. 在需要使用参数的地方,通过${参数名}获取参数值
    <bean id="conn" class="com.baizhi.factory.ConnectionFactoryBean" >
        <property name="url" value="${url}"/>
        <property name="driverClassName" value="${driverClassName}"/>
        <property name="username" value="${user}"/>
        <property name="password" value="${password}"/>
    </bean>
               

注意:${username}会优先读取操作系统的用户名,jdbc.properties中必须改名

4 Spring整合MyBatis

4.1 整合效果分析

首先,回顾下MyBatis项目开发步骤:

  1. 搭建开发环境
    1. 新建项目
    2. 导入依赖

      数据库驱动依赖:mysql-connector-java.jar

      MyBatis相关的依赖

      servlet+jsp+jstl的依赖

      junit+hutool+druid

    3. 配置文件+工具类
      jdbc.properties

    log4j.properties

    xxxMapper.xml

    mybatis-config.xml

    1. 配置文件初始化
    mybatis-config.xml 初始化配置
  2. 建表
  3. 实体
  4. mapper
    1. 接口
    2. 实现:XxxMapper.xml
  5. service
    1. 接口
    2. 实现:

      SqlSession sqlSession = MyBatisUtils.openSession();

      XxxMapper mapper = sqlSession.getMapper(XxxMapper.class);

  6. test

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XsE4hrJJ-1630934265224)(Spring day02.assets/image-20210614214830286.png)]

Spring整合MyBatis的效果就是使用Spring的工厂功能创建MyBatis项目中需要的关键对象:Dao对象和Service对象。

4.2 整合思路分析

整合的关键在于如何在applicationContext.xml中配置,由Spring工厂创建Dao对象。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-o9FG04n2-1630934265225)(Spring day02.assets/image-20210614222528122.png)]

思路:原dao的编码创建过程中需要创建哪些对象,在Spring中也需要创建哪些对象,只不过编码方式转为Spring的配置。原来编码创建的对象,在Spring中以bean标签的形式体现。

4.3 整合实战

准备工作,添加 mybatis-spring依赖

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid</artifactId>
    <version>1.1.22</version>
</dependency>

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>5.2.8.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-jdbc</artifactId>
    <version>5.2.8.RELEASE</version>
</dependency>
<!-- 整合spring mybatis的依赖-->
<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis-spring</artifactId>
    <version>2.0.4</version>
</dependency>
           

初版配置:

<!-- 读取jdbc.properties-->
<context:property-placeholder location="classpath:jdbc.properties"/>
<!-- 0 定义一个连接池 -->
<bean id="druidDataSource" class="com.alibaba.druid.pool.DruidDataSource">
    <property name="driverClassName" value="${jdbc.driverClassName}"/>
    <property name="url" value="${jdbc.url}"/>
    <property name="username" value="${jdbc.username}"/>
    <property name="password" value="${jdbc.password}"/>
</bean>

<!-- 定义SqlSessionFactory-->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">

    <property name="dataSource" ref="druidDataSource"/>
    <!--
            配置实体类的包名,自动为实体配置短类名的别名
         -->
    <property name="typeAliasesPackage" value="com.baizhi.entity"/>
    <property name="mapperLocations">
        <!-- 配置mapper.xml的路径-->
        <list>
            <!--<value>classpath:com/baizhi/mapper/UserMapper.xml</value>
                <value>classpath:com/baizhi/mapper/StudentMapper.xml</value>
                <value>classpath:com/baizhi/mapper/BookMapper.xml</value>-->
            <value>classpath:com/baizhi/mapper/*Mapper.xml</value>
        </list>
    </property>
</bean>

<!-- 定义SqlSession -->
<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
    <constructor-arg ref="sqlSessionFactory"/>
</bean>

<!-- 创建 UserMapper实现类对象-->
<bean id="userMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">
    <property name="sqlSessionTemplate" ref="sqlSession"/>
    <property name="mapperInterface" value="com.baizhi.mapper.UserMapper"/>
</bean>

<!--<bean id="bookMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">
        <property name="sqlSessionTemplate" ref="sqlSession"/>
        <property name="mapperInterface" value="com.baizhi.mapper.BookMapper"/>
    </bean>-->

<bean id="userService" class="com.baizhi.service.impl.UserServiceImpl">
    <property name="userMapper" ref="userMapper"/>
</bean>
           

最终配置:

<!-- 读取jdbc.properties-->
    <context:property-placeholder location="classpath:jdbc.properties"/>
    <!-- 0 定义一个连接池 -->
    <bean id="druidDataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="driverClassName" value="${jdbc.driverClassName}"/>
        <property name="url" value="${jdbc.url}"/>
        <property name="username" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
    </bean>

    <!-- 定义SqlSessionFactory-->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">

        <property name="dataSource" ref="druidDataSource"/>
        <!--
            配置实体类的包名,自动为实体配置短类名的别名
         -->
        <property name="typeAliasesPackage" value="com.baizhi.entity"/>
        <property name="mapperLocations">
            <!-- 配置mapper.xml的路径-->
            <list>                
                <value>classpath:com/baizhi/mapper/*Mapper.xml</value>
            </list>
        </property>
    </bean>
    <!--
        自动创建Mapper实现类对象
        自动扫描basePackage包下的Mapper接口,自动创建Mapper接口的实现类对象

    -->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <!--
            mapper实现类对象的id规则:接口名首字母小写
            UserMapper  ==> userMapper
            BookMapper ==> bookMapper
        -->
        <property name="basePackage" value="com.baizhi.mapper"/>
    </bean>

    <bean id="userService" class="com.baizhi.service.impl.UserServiceImpl">
        <property name="userMapper" ref="userMapper"/>
    </bean>
           

注意:Service中的编码式事务控制,对由Spring创建的Dao无效。所以,我们删除service中事务控制代码,暂时以无事务的状态运转。

5 Spring整合Servlet

5.1 整合效果分析

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-on1jMJxs-1630934265226)(Spring day02.assets/image-20210615132416834.png)]

预期效果:Servlet中获取Service对象的方式从new改为从工厂中获取。

5.2 整合方案

Spring整合Servlet的关键在于从Spring工厂中获取Service对象,这就必须先解决2个问题:

  • 如何创建Spring工厂
  • 何时创建Spring工厂

方案1: 直接在Servlet的服务方法中,创建工厂。

public class XxxController extends HttpServlet{
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 收参 
        ...
        //调用业务层方法
        ApplicationContext ctx = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
        XxxService xxxService = (XxxService) ctx.getBean("xxxService");
       	//跳转
        ...
    }
}
           

存在的问题:每请求一次服务方法,就重新创建1次工厂(工厂是重量级对象,占用内容空间较大),性能较差

方案2:将工厂做成属性

public class XxxController extends HttpServlet{
    private ApplicationContext ctx = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 收参 
        ...
        //调用业务层方法
        XxxService xxxService = (XxxService) ctx.getBean("xxxService");
       	//跳转
        ...
    }
}
           

存在的问题:每一个Servlet独有一个工厂属性,有多少Servlet就会有多少Spring工厂,性能仍待提升

方案3:工厂应该全局共享,整个web应用中只创建一个工厂

public class BaiZhiWebApplicationContextUtils{
    private static ApplicationContext ctx = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
    public static ApplicationContext getWebApplicationContext(){
        return ctx;
    }
}

public class XxxController extends HttpServlet{
   
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 收参 
        ...
        //调用业务层方法
        ApplicationContext ctx = BaiZhiWebApplicationContextUtils.getWebApplicationContext();
        XxxService xxxService = (XxxService) ctx.getBean("xxxService");
       	//跳转
        ...
    }
}
           

存在的问题:第1次访问Servlet在调用WebApplicationContextUtils时需要创建工厂,工厂的创建比较耗时。第1次请求的响应会比较耗时,用户体验差。

方案4:可以在Web应用一启动时就提前创建Spring工厂,在ServletContextListener中监听到Web应用的启动

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-I0481h1d-1630934265227)(Spring day02.assets/image-20210615220557477.png)]

public class ContextLoaderListener implements ServletContextListener {
  
    @Override
    public void contextInitialized(ServletContextEvent sce) {
        ApplicationContext ctx = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
        ServletContext servletContxt = sec.getServletContext();
        servletContext.setAttribute("ctx",ctx);
    }
    
}
           
public class BaiZhiWebApplicationContextUtils{

    public static ApplicationContext getWebApplicationContext(ServletContext sc){
        return (ApplicationContext).getAttribute("ctx");
    }
}


public class XxxController extends HttpServlet{
   
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 收参 
        ...
        //调用业务层方法
        ApplicationContext ctx = BaiZhiWebApplicationContextUtils.getWebApplicationContext(req.getServletContext());
        XxxService xxxService = (XxxService) ctx.getBean("xxxService");
       	//跳转
        ...
    }
}

           

方案5(重点):和上一个方案的思路一致,只不过使用Spring-Web模块内置的监听器和工具类。

准备工作,pom.xml添加 spring-web依赖

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-web</artifactId>
    <version>5.2.8.RELEASE</version>
</dependency>
           

web.xml

<!-- 设置applicationConext.xml的路径-->
<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:applicationContext.xml</param-value>
</context-param>
<!-- 配置监听器:在web应用启动时,自动的创建工厂并保存到ServletContext中-->
<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
           
public class XxxController extends HttpServlet{
   
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 收参 
        ...
        //调用业务层方法
        ApplicationContext ctx = WebApplicationContextUtils.getWebApplicationContext(req.getServletContext());
        XxxService xxxService = (XxxService) ctx.getBean("xxxService");
       	//跳转
        ...
    }
}
           

方案1~方案4为思路过渡方案,最终在理解各种方案的优缺点后,掌握最终的标准方案即可。

6 总结:SM项目开发步骤

  1. 搭建开发环境
    1. 新建web项目(补全项目结构)
    2. 导入依赖,pom.xml引入依赖

      数据库依赖:

      mysql-connector-java.jar

      druid

      spring依赖:
      spring-context
      mybatis依赖:

      mybatis

      slf4j-log4j12

      mybatis和spring整合

      spring-jdbc

      mybatis-spring

      servlet+jsp+jstl依赖

      servlet-api

      jsp-api

      jstl

      springmvc依赖
      spring-webmvc
      hutool工具
      hutool-all
    3. 配置文件和工具类

      jdbc.properties

      lo4j.properties

      mybatis-config.xml (不再需要)

      xxxMapper.xml

      web.xml

      applicationContext.xml

      MyBatisUtils.java (不再需要)

    4. 配置文件初始化
      web.xml中配置Spring监听器,创建Spring工厂
  2. 建表
  3. 实体
  4. dao
    1. 接口
    2. 实现: mapper.xml中定义sql语句
  5. service
    1. 接口
    2. 实现:暂不提供事务控制(删除掉事务控制的代码)
  6. test
  7. Controller+jsp

    ​ Controller:从ServletContext中获取工厂,再从工厂中获取Service对象

  8. 集成测试

pom.xml

<!-- jdbc依赖-->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.23</version>
</dependency>

<!-- 阿里巴巴连接池依赖 -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid</artifactId>
    <version>1.0.24</version>
</dependency>

<!--引入Spring依赖-->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>5.2.8.RELEASE</version>
</dependency>

<dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjweaver</artifactId>
    <version>1.9.5</version>
</dependency>

<!-- mybatis依赖-->
<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis</artifactId>
    <version>3.5.4</version>
</dependency>
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-log4j12</artifactId>
    <version>1.7.30</version>
</dependency>

<!-- spring 整合 mybatis 依赖-->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-jdbc</artifactId>
    <version>5.2.8.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis-spring</artifactId>
    <version>2.0.4</version>
</dependency>

<!-- servlet jsp jstl 依赖-->
<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>4.0.1</version>
    <scope>provided</scope>
</dependency>

<dependency>
    <groupId>javax.servlet.jsp</groupId>
    <artifactId>javax.servlet.jsp-api</artifactId>
    <version>2.3.3</version>
    <scope>provided</scope>
</dependency>
<dependency>
    <groupId>jstl</groupId>
    <artifactId>jstl</artifactId>
    <version>1.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/taglibs/standard -->
<dependency>
    <groupId>taglibs</groupId>
    <artifactId>standard</artifactId>
    <version>1.1.2</version>
</dependency>


<!-- SpringMVC依赖 -->
 <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>5.2.8.RELEASE</version>
    </dependency>

<!--
       hutool工具类
    -->
<!-- https://mvnrepository.com/artifact/cn.hutool/hutool-all -->
<dependency>
    <groupId>cn.hutool</groupId>
    <artifactId>hutool-all</artifactId>
    <version>5.2.3</version>
</dependency>

<!-- junit测试依赖-->
<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <scope>test</scope>
    <version>4.12</version>
</dependency>
           

web.xml

<!-- 配置spring配置文件的路径-->
<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:applicationContext.xml</param-value>
</context-param>
<!-- 监听器:监听web应用启动,根据上面配置的spring配置文件路径创建Spring工厂-->
<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
           

applicationContext.xml

<context:property-placeholder location="classpath:jdbc.properties"/>
<!-- 创建连接池 DataSource -->
<bean id="druidDataSource" class="com.alibaba.druid.pool.DruidDataSource">
    <!-- 必须的配置 -->
    <property name="url" value="${url}"/>
    <property name="driverClassName" value="${driverClassName}"/>
    <property name="username" value="${user}"/>
    <property name="password" value="${password}"/>
    <!-- 额外的配置-->
</bean>

<!-- 定义SqlSessionFactory-->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">

    <property name="dataSource" ref="druidDataSource"/>
    <!--
            配置实体类的包名,自动为实体配置短类名的别名
         -->
    <property name="typeAliasesPackage" value="com.baizhi.entity"/>
    <property name="mapperLocations">
        <!-- 配置mapper.xml的路径-->
        <list>                
            <value>classpath:com/baizhi/mapper/*Mapper.xml</value>
        </list>
    </property>
</bean>
<!--
        自动创建Mapper实现类对象
        自动扫描basePackage包下的Mapper接口,自动创建Mapper接口的实现类对象

    -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
    <!--
            mapper实现类对象的id规则:接口名首字母小写
            UserMapper  ==> userMapper
            BookMapper ==> bookMapper
        -->
    <property name="basePackage" value="com.baizhi.mapper"/>
</bean>

<!-- 定义service对象-->
<bean id="userService" class="com.baizhi.service.impl.UserServiceImpl">
    <property name="userMapper" ref="userMapper"/>
</bean>
           

urce" ref=“druidDataSource”/>

classpath:com/baizhi/mapper/*Mapper.xml

```