初學,記錄本身學習整合兩個框架的過程,裏面也有不少踩過的坑,也有沒有解決的問題,先記錄下來。等待解決。java
廢話很少說,直接開始了。先上pom.xml配置文件。mysql
This is my 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"> <modelVersion>4.0.0</modelVersion> <groupId>Sping_Mybatis</groupId> <artifactId>spring_mybatis_test</artifactId> <version>1.0-SNAPSHOT</version> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.10</version> <scope>test</scope> </dependency> <dependency><!-- spring對測試框架的簡單封裝功能 --> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>4.2.0.RELEASE</version> <scope>test</scope> </dependency> <!-- 數據源 --> <dependency> <groupId>commons-dbcp</groupId> <artifactId>commons-dbcp</artifactId> <version>1.4</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.0.8</version> </dependency> <!-- Mybatis3.4.1 --> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.4.1</version> </dependency> <!-- spring整合mybatis --> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>1.3.0</version> </dependency> <!-- Spring-4.2.0 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>4.2.0.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-orm</artifactId> <version>4.2.0.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-expression</artifactId> <version>4.2.0.RELEASE</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.1.8</version> </dependency> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.17</version> </dependency> </dependencies> </project>
貼上一張項目目錄的圖git
再來看mybatisConfig.xml的配置web
數據源在spring的配置文件裏,同時spring文件裏配置了自動掃描Mapper。故在此不用再次編寫<mappers>中的內容spring
<?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"> <configuration> <settings> <setting name="logImpl" value="LOG4J"/> </settings> <typeAliases> <typeAlias type="com.lpp.test.entity.Car" alias="car"/> </typeAliases> <!--<mappers> <mapper url="config/sqlMapper/CarMapper.xml"/> </mappers>--> </configuration>
此時再來看spring_mybatis.xml的配置,在這裏面有個問題暫時還未解決。把jdbc.properties放在resource目錄下以後,在spring配置中引入失敗。在配置數據源時候,變量失效,暫時沒有解決是什麼問題,先放在這裏吧。等待之後回過頭解決。配置的很簡單。解決方法在一篇博客中找到了,具體緣由和解決方案放在最下邊。sql
<?xml version="1.0" encoding="UTF-8" ?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" 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 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <context:component-scan base-package="com.lpp.test"/> <!--<context:property-placeholder location="classpath:jdbc.properties"/> <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="location" value="classpath:jdbc.properties" /> </bean>--> <!--配置數據源--> <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close" p:driverClassName="com.mysql.jdbc.Driver" p:url="jdbc:mysql://localhost:3306/test" p:username="root" p:password="" /><!--${driverClasss}${jdbcUrl}${username}com.mysql.jdbc.Driver--> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean" p:dataSource-ref="dataSource" p:configLocation="classpath:config/mybatisConfig.xml" p:mapperLocations="classpath:config/sqlMapper/*.xml"/> <!--這裏使用spring提供的SQLSessionTemplate--> <bean class="org.mybatis.spring.SqlSessionTemplate"> <constructor-arg ref="sqlSessionFactory"/> </bean> <!-- 掃描直接使用mapper接口類操做dao,並直接歸入IOC容器管理 --> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer" p:sqlSessionFactory-ref="sqlSessionFactory" p:basePackage="com.lpp.test.dao"> </bean> </beans>
接下來是Mapper.xml的配置,三種配置效果差很少是同樣的,寫法上不太相同,跟carMapper接口對比來看就知道是三種方式。express
<?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.lpp.test.dao.carMapper"> <select id="findCarbyId" parameterType="int" resultType="Car"> SELECT id,car_name AS carName,maxSpeed FROM t_car WHERE id = #{id} </select> <select id="findCarbyIdAndName" resultType="Car"> SELECT * FROM t_car WHERE id = #{id} AND car_name = #{car_name}; </select> <select id="findCarbyIdAndSpeed" resultType="Car"> SELECT * FROM t_car WHERE id = #{id} AND maxSpeed = #{maxSpeed}; </select> </mapper>
carMapper接口apache
package com.lpp.test.dao; import com.lpp.test.entity.Car; import org.apache.ibatis.annotations.Param; /** * Created with IntelliJ IDEA. * Description: * User: lpp * Date: 2018-04-17 * Time: 19:44 */ public interface carMapper { public Car findCarbyId(int id); public Car findCarbyIdAndName(@Param("id") int id, @Param("car_name") String car_name); public Car findCarbyIdAndSpeed(Car car); }
貼上log4j.properties的配置session
# Global logging configuration\uff0c\u5efa\u8bae\u5f00\u53d1\u73af\u5883\u4e2d\u8981\u7528debug log4j.rootLogger=DEBUG, stdout # Console output... log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n
entity下的實體 car.javamybatis
package com.lpp.test.entity; /** * Created with IntelliJ IDEA. * Description: * User: lpp * Date: 2018-04-16 * Time: 11:06 */ public class Car { int id; String carName; int maxSpeed; public Car() { } public Car(int id, String carName, int maxSpeed) { this.id = id; this.carName = carName; this.maxSpeed = maxSpeed; } public int getId() { return id; } public String getCarName() { return carName; } public int getMaxSpeed() { return maxSpeed; } public void setId(int id) { this.id = id; } public void setName(String car_name) { this.carName = carName; } public void setMaxSpeed(int maxSpeed) { this.maxSpeed = maxSpeed; } @Override public String toString() { return "Car{" + "id=" + id + ", name='" + carName + '\'' + ", maxSpeed=" + maxSpeed + '}'; } }
最後是測試方法,我建立了一個測試方法和一個主方法測試,代碼分別以下。
test方法
package com.lpp.test.dao; import com.lpp.test.entity.Car; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import static org.junit.Assert.*; /** * Created with IntelliJ IDEA. * Description: * User: lpp * Date: 2018-04-27 * Time: 17:36 */ @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = "classpath:config/spring-mybatis.xml") public class carMapperTest { @Autowired carMapper carMapper; @Test public void findCarbyIdAndName() { Car car = carMapper.findCarbyIdAndName(1,"aodi"); System.out.println(car); } }
主方法
package com.lpp.test.main; import com.lpp.test.dao.carMapper; import com.lpp.test.entity.Car; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; /** * Created with IntelliJ IDEA. * Description: * User: lpp * Date: 2018-04-25 * Time: 17:44 */ public class testMain { public static void main(String[] args) { ApplicationContext ctx = new ClassPathXmlApplicationContext("config/spring-mybatis.xml"); carMapper carMapper = ctx.getBean(com.lpp.test.dao.carMapper.class); Car car = null; car = carMapper.findCarbyId(1); System.out.println(car.toString()); } }
兩種測試方法結果是相同的,調用了不一樣的查詢函數。以上就是我作整合的步驟,初次嘗試,不免有些問題,但願能讓你們收穫一些東西。
附:引入jdbc屬性文件以後報錯,Cannot load JDBC driver class ${jdbc.driverClassName}
引發緣由:在spring裏使用org.mybatis.spring.mapper.MapperScannerConfigurer 進行自動掃描的時候,設置了sqlSessionFactory 的話,可能會致使PropertyPlaceholderConfigurer失效,也就是用${jdbc.username}這樣之類的表達式,將沒法獲取到properties文件裏的內容。
致使這一緣由是由於,MapperScannerConigurer實際是在解析加載bean定義階段的,這個時候要是設置sqlSessionFactory的話,會致使提早初始化一些類,這個時候,PropertyPlaceholderConfigurer還沒來得及替換定義中的變量,致使把表達式看成字符串複製了。
解決思路
1. 若是不設置sqlSessionFactory 屬性的話,就必需要保證sessionFactory在spring中名稱必定要是sqlSessionFactory ,不然就沒法自動注入。
2. 直接定義 MapperFactoryBean
3. 放棄自動代理接口方式。
我理解的解決方案:
單數據源下刪除下列屬性
<property name="sqlSessionTemplate" value="sqlSessionFactory" />或者default-autowire="byName"
多數據源下改用sqlSessionFactoryBeanName。多數據源解決方案暫時不太理解,後續繼續學習
附上gitee地址:https://gitee.com/LL7_s/personal_test_code_sorting/tree/master/spring_mybatis_test