Spring day02
0 複習
- 工廠設計模式
工廠設計模式代替new方式建立對象,目的是解耦合。
- Spring做為工廠的使用
applicationContext.xml配置bean标簽
如何從工廠中擷取對象
//建立工廠 ApplicationContext ctx = new ClassPathXmlApplicationContext("classpath:applicationContext.xml"); //從工廠中擷取bean ctx.getBean("id值");
- 屬性注入(Spring工廠建立對象的同時,為屬性指派)
- set注入
- 簡單類型
<bean id="id值" class="全類名"> <property name="屬性名" value="簡單屬性值"/> </bean>
- 複雜自定義類型
<bean id="id值" class="全類名"> <property name="屬性名" ref="另外一個bean的id"/> </bean>
- 數組、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>
- Map
<bean id="id值" class="全類名"> <property name="屬性名"> <map> <entry key="鍵的值" value="簡單值"/> <entry key="鍵的值" value—ref="另外一個bean的id"/> </map> </property> </bean>
- Properties
<bean id="id值" class="全類名"> <property name="屬性名"> <props> <prop key="字元串的鍵">字元串的值</prop> <prop key="字元串的鍵">字元串的值</prop> ... </props> </property> </bean>
- 簡單類型
- 構造注入
<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>
- set注入
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>
- 定義一個用于建立複雜對象的類,必須實作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; } }
- 配置上一步定義的FactoryBean
<!-- getBean("conn")擷取不是ConnectionFactoryBean類型的對象,擷取getObject()傳回的複雜對象 --> <bean id="conn" class="com.baizhi.factory.ConnectionFactoryBean"/>
注意:
- 複雜對象的單例控制,由isSingleton()方法傳回值決定
- 通過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)。
-
xsd的基本使用
[外鍊圖檔轉存失敗,源站可能有防盜鍊機制,建議将圖檔儲存下來直接上傳(img-VEEO73ea-1630934265221)(Spring day02.assets/image-20200331154014258.png)]
-
在一個配置檔案中使用多個xsd
Spring不同的子產品定義了不同的xsd檔案,在一個Spring配置檔案中使用多個子產品的功能,也就要在配置檔案中使用多個xsd。
[外鍊圖檔轉存失敗,源站可能有防盜鍊機制,建議将圖檔儲存下來直接上傳(img-JF8z7brZ-1630934265222)(Spring day02.assets/image-20200331154803138.png)]
使用步驟:
- 在跟标簽中添加xmlns:字首=“其它xsd的命名空間”
- 在xsi:schemaLocation=“添加路徑對”
- 使用其它xsd中定義的标簽需要添加
字首:
示例:
[外鍊圖檔轉存失敗,源站可能有防盜鍊機制,建議将圖檔儲存下來直接上傳(img-81stK25t-1630934265224)(Spring day02.assets/image-20200331155251020.png)]
3.3 Spring 配置檔案properties的拆分
程式中關于資料庫的參數配置,一般都抽取到jdbc.properties檔案中。Spring的applicationContext.xml中關于資料庫的配置也一樣要抽取。
- 将資料庫參數抽取到jdbc.properties中
driverClassName=com.mysql.jdbc.Driver url=jdbc:mysql://localhost:3306/baizhi?useUnicode=true&characterEncoding=utf-8 user=root password=root
- 在Spring的配置檔案中讀取jdbc.properties
<!-- 讀取配置檔案 使用context.xsd定義property-placeholder标簽讀取jdbc.properties檔案--> <context:property-placeholder location="classpath:jdbc.properties"/>
- 在需要使用參數的地方,通過${參數名}擷取參數值
<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項目開發步驟:
- 搭建開發環境
- 建立項目
- 導入依賴
資料庫驅動依賴:mysql-connector-java.jar
MyBatis相關的依賴
servlet+jsp+jstl的依賴
junit+hutool+druid
- 配置檔案+工具類
jdbc.properties
log4j.properties
xxxMapper.xml
mybatis-config.xml
- 配置檔案初始化
mybatis-config.xml 初始化配置
- 建表
- 實體
- mapper
- 接口
- 實作:XxxMapper.xml
- service
- 接口
- 實作:
SqlSession sqlSession = MyBatisUtils.openSession();
XxxMapper mapper = sqlSession.getMapper(XxxMapper.class);
- 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項目開發步驟
- 搭建開發環境
- 建立web項目(補全項目結構)
-
導入依賴,pom.xml引入依賴
資料庫依賴:
mysql-connector-java.jar
druid
spring-context
mybatis依賴:mybatis
slf4j-log4j12
spring-jdbc
mybatis-spring
servlet-api
jsp-api
jstl
spring-webmvc
hutool工具hutool-all
- 配置檔案和工具類
jdbc.properties
lo4j.properties
mybatis-config.xml (不再需要)
xxxMapper.xml
web.xml
applicationContext.xml
MyBatisUtils.java (不再需要)
- 配置檔案初始化
web.xml中配置Spring監聽器,建立Spring工廠
- 建表
- 實體
- dao
- 接口
- 實作: mapper.xml中定義sql語句
- service
- 接口
- 實作:暫不提供事務控制(删除掉事務控制的代碼)
- test
-
Controller+jsp
Controller:從ServletContext中擷取工廠,再從工廠中擷取Service對象
- 內建測試
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
```