SpringBoot集成MyBatis
spring boot 版本为 1.5.8.RELEASE
1 准备工作(创建数据表)
CREATE TABLE `admin` (
`admin_id` varchar(32) NOT NULL,
`account` varchar(45) NOT NULL,
`password` varchar(255) NOT NULL,
`salt` varchar(10) NOT NULL,
`name` varchar(45) NOT NULL DEFAULT '',
`status` int(11) NOT NULL DEFAULT '1',
`last_login_time` datetime DEFAULT NULL,
`last_login_ip` varchar(45) DEFAULT NULL,
PRIMARY KEY (`admin_id`),
UNIQUE KEY `account` (`account`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
2 创建spring boot工程
2.1 手动创建
创建maven工程,将下列pom文件拷贝至工程中
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>priv.jarome.springboot</groupId>
<artifactId>test-ssm</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>test-ssm</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.8.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.1</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
2.2 spring 官网创建
打开浏览器输入http://start.spring.io/ ,选择Maven Project,boot 版本为1.5.8,输入Group、Artifact,在右侧Dependencies中选择Web,MyBatis。如下图所示:
3 工程文件
3.1 application.yml
mybatis:
mapper-locations: classpath:mapper/*.xml
type-aliases-package: priv.jarome.springboot.testssm.model
config-location: classpath:config/mybatis-config.xml
spring:
datasource:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/pymy?useUnicode=true&characterEncoding=utf-8
username: root
password: 123456
type: org.apache.tomcat.jdbc.pool.DataSource
3.2 Model(Admin.java)
package priv.jarome.springboot.testssm.model;
import java.util.Date;
/**
* @author jarome
* @date 2017/11/21
*/
public class Admin {
private String adminId;
private String account;
private String password;
private String salt;
private String name;
private Integer status;
private Date lastLoginTime;
private String lastLoginIp;
public String getAdminId() {
return adminId;
}
public void setAdminId(String adminId) {
this.adminId = adminId;
}
public String getAccount() {
return account;
}
public void setAccount(String account) {
this.account = account;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getSalt() {
return salt;
}
public void setSalt(String salt) {
this.salt = salt;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getStatus() {
return status;
}
public void setStatus(Integer status) {
this.status = status;
}
public Date getLastLoginTime() {
return lastLoginTime;
}
public void setLastLoginTime(Date lastLoginTime) {
this.lastLoginTime = lastLoginTime;
}
public String getLastLoginIp() {
return lastLoginIp;
}
public void setLastLoginIp(String lastLoginIp) {
this.lastLoginIp = lastLoginIp;
}
}
3.3 Mapper(AdminMapper.xml、AdminMapper.java)
AdminMapper.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="priv.jarome.springboot.testssm.dao.AdminMapper">
<resultMap id="BaseResultMap" type="priv.jarome.springboot.testssm.model.Admin">
<id column="admin_id" jdbcType="VARCHAR" property="adminId" />
<result column="account" jdbcType="VARCHAR" property="account" />
<result column="password" jdbcType="VARCHAR" property="password" />
<result column="salt" jdbcType="VARCHAR" property="salt" />
<result column="name" jdbcType="VARCHAR" property="name" />
<result column="status" jdbcType="INTEGER" property="status" />
<result column="last_login_time" jdbcType="TIMESTAMP" property="lastLoginTime" />
<result column="last_login_ip" jdbcType="VARCHAR" property="lastLoginIp" />
</resultMap>
<sql id="Base_Column_List">
admin_id, account, password, salt, name, status, last_login_time, last_login_ip
</sql>
<select id="selectByPrimaryKey" parameterType="java.lang.String" resultMap="BaseResultMap">
select
<include refid="Base_Column_List" />
from admin
where admin_id = #{adminId,jdbcType=VARCHAR}
</select>
</mapper>
AdminMapper.java
package priv.jarome.springboot.testssm.dao;
import priv.jarome.springboot.testssm.model.Admin;
/**
* @author jarome
* @date 2017/11/21
*/
public interface AdminMapper {
Admin selectByPrimaryKey(String adminId);
}
mybatis-config.xml
<?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="callSettersOnNulls" value="true"/>
<setting name="cacheEnabled" value="true"/>
<setting name="lazyLoadingEnabled" value="true"/>
<setting name="aggressiveLazyLoading" value="true"/>
<setting name="multipleResultSetsEnabled" value="true"/>
<setting name="useColumnLabel" value="true"/>
<setting name="useGeneratedKeys" value="false"/>
<setting name="autoMappingBehavior" value="PARTIAL"/>
<setting name="defaultExecutorType" value="SIMPLE"/>
<setting name="mapUnderscoreToCamelCase" value="true"/>
<setting name="localCacheScope" value="SESSION"/>
<setting name="jdbcTypeForNull" value="NULL"/>
</settings>
<typeAliases>
<typeAlias alias="Integer" type="java.lang.Integer" />
<typeAlias alias="Long" type="java.lang.Long" />
<typeAlias alias="HashMap" type="java.util.HashMap" />
<typeAlias alias="LinkedHashMap" type="java.util.LinkedHashMap" />
<typeAlias alias="ArrayList" type="java.util.ArrayList" />
<typeAlias alias="LinkedList" type="java.util.LinkedList" />
</typeAliases>
</configuration>
3.4 Serice
AdminService.java
package priv.jarome.springboot.testssm.service;
import priv.jarome.springboot.testssm.model.Admin;
/**
* @author jarome
* @date 2017/11/21
*/
public interface AdminService {
Admin getByAdminId(String adminId);
}
AdminServiceImpl.java
package priv.jarome.springboot.testssm.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import priv.jarome.springboot.testssm.dao.AdminMapper;
import priv.jarome.springboot.testssm.model.Admin;
/**
* @author jarome
* @date 2017/11/21
*/
@Service("adminService")
public class AdminServiceImpl implements AdminService {
@Autowired
private AdminMapper adminMapper;
@Override
public Admin getByAdminId(String adminId) {
return adminMapper.selectByPrimaryKey(adminId);
}
}
3.5 Controller
PageController.java
package priv.jarome.springboot.testssm.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import priv.jarome.springboot.testssm.model.Admin;
import priv.jarome.springboot.testssm.service.AdminService;
/**
* @author jarome
* @date 2017/11/21
*/
@Controller
public class PageController {
@Autowired
@Qualifier(value = "adminService")
private AdminService adminService;
@RequestMapping(value = "/testdb")
@ResponseBody
public Admin testdb(){
return adminService.getByAdminId("d3ef9f34b08811e79324124e51ae7336");
}
}
3.6 Application
Application.java
package priv.jarome.springboot.testssm.app;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.tomcat.jdbc.pool.DataSource;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.annotation.MapperScan;
import org.mybatis.spring.boot.autoconfigure.MybatisProperties;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;
@SpringBootApplication
@EnableAutoConfiguration(exclude = {DataSourceAutoConfiguration.class})
@ComponentScan(basePackages = {"priv.jarome.springboot.testssm.controller", "priv.jarome.springboot.testssm.service"})
@MapperScan("priv.jarome.springboot.testssm.dao")
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
4 异常分析
运行Application,发现控制台报如下错误:
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'adminMapper' defined in file [/Users/jarome/develop/vcs/mygit/mystudy/springboot-testssm/target/classes/priv/jarome/springboot/testssm/dao/AdminMapper.class]: Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Property 'sqlSessionFactory' or 'sqlSessionTemplate' are required
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1628) ~[spring-beans-4.3.12.RELEASE.jar:4.3.12.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:555) ~[spring-beans-4.3.12.RELEASE.jar:4.3.12.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483) ~[spring-beans-4.3.12.RELEASE.jar:4.3.12.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306) ~[spring-beans-4.3.12.RELEASE.jar:4.3.12.RELEASE]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) ~[spring-beans-4.3.12.RELEASE.jar:4.3.12.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302) ~[spring-beans-4.3.12.RELEASE.jar:4.3.12.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202) ~[spring-beans-4.3.12.RELEASE.jar:4.3.12.RELEASE]
at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:208) ~[spring-beans-4.3.12.RELEASE.jar:4.3.12.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1138) ~[spring-beans-4.3.12.RELEASE.jar:4.3.12.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1066) ~[spring-beans-4.3.12.RELEASE.jar:4.3.12.RELEASE]
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:585) ~[spring-beans-4.3.12.RELEASE.jar:4.3.12.RELEASE]
... 32 common frames omitted
Caused by: java.lang.IllegalArgumentException: Property 'sqlSessionFactory' or 'sqlSessionTemplate' are required
at org.springframework.util.Assert.notNull(Assert.java:134) ~[spring-core-4.3.12.RELEASE.jar:4.3.12.RELEASE]
at org.mybatis.spring.support.SqlSessionDaoSupport.checkDaoConfig(SqlSessionDaoSupport.java:74) ~[mybatis-spring-1.3.1.jar:1.3.1]
at org.mybatis.spring.mapper.MapperFactoryBean.checkDaoConfig(MapperFactoryBean.java:73) ~[mybatis-spring-1.3.1.jar:1.3.1]
at org.springframework.dao.support.DaoSupport.afterPropertiesSet(DaoSupport.java:44) ~[spring-tx-4.3.12.RELEASE.jar:4.3.12.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1687) ~[spring-beans-4.3.12.RELEASE.jar:4.3.12.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1624) ~[spring-beans-4.3.12.RELEASE.jar:4.3.12.RELEASE]
... 42 common frames omitted
异常分析 经查阅,发现是由于Mybais-Spring包版本过高(1.2以上)引起的,因为1.2以及以上的版本中,对SqlSessionDaoSupport类中的’sqlSessionFactory’或’sqlSessionTemplate’注入方式进行了调整。
解决办法 在Appliation中增加对DataSource的处理,经修改后的Application.java内容如下:
package priv.jarome.springboot.testssm.app;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.tomcat.jdbc.pool.DataSource;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.annotation.MapperScan;
import org.mybatis.spring.boot.autoconfigure.MybatisProperties;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;
@SpringBootApplication
@EnableAutoConfiguration(exclude = {DataSourceAutoConfiguration.class})
@ComponentScan(basePackages = {"priv.jarome.springboot.testssm.controller", "priv.jarome.springboot.testssm.service"})
@MapperScan("priv.jarome.springboot.testssm.dao")
public class Application {
private final static String DATASOURCE_PREIFX = "spring.datasource";
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
@Bean
@ConfigurationProperties(prefix = DATASOURCE_PREIFX)
public DataSource dataSource() {
return new org.apache.tomcat.jdbc.pool.DataSource();
}
@Bean
public SqlSessionFactory sqlSessionFactoryBean() throws Exception {
SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
sqlSessionFactoryBean.setDataSource(dataSource());
PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
sqlSessionFactoryBean.setMapperLocations(resolver.getResources("classpath:/mapper/*.xml"));
return sqlSessionFactoryBean.getObject();
}
@Bean
public PlatformTransactionManager transactionManager() {
return new DataSourceTransactionManager(dataSource());
}
}