[Spring Boot实战系列]

来源:互联网 发布:mysql教程视频下载 编辑:程序博客网 时间:2024/05/24 02:01

一、Mybatis是什么:

mybatis是一个优秀的基于java的持久层框架,它内部封装了jdbc,使开发者只需要关注sql语句本身,而不需要花费精力去处理加载驱动、创建连接、创建statement等繁杂的过程。同时,mybatis提供了基于XML或者基于注解的动态SQL的方式,使得我们可以控制和优化SQL。

二、Springboot整合Mybatis两种方式:

A. Spring Boot中引入了自动配置,让开发者利用起来更加的快捷,当我们引入mybatis-spring-boot-starter的时候,springboot会按照默认直接配置好mybatis的相关组件,使得我们可以直接使用mybatis。方法如下所示:

1. 在pom.xml中引入相关依赖:(主要是阿里的druid数据库连接池和mybatis-spring-boot-starter)

<?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>com.springboot.yanming</groupId><artifactId>mybatis</artifactId><version>0.0.1-SNAPSHOT</version><packaging>jar</packaging><name>mybatis</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.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>1.1.1</version></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><dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.0.29</version></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>
2. 在application.yml(或者是.properties格式)中,设置数据库和mybatis参数:

spring:  datasource:    url: jdbc:mysql://localhost:3306/springboot    username: root    password: root    type: com.alibaba.druid.pool.DruidDataSource    driver-class-name: com.mysql.jdbc.Driver    filters: stat    maxActive: 20    initialSize: 1    maxWait: 60000    minIdle: 1    timeBetweenEvictionRunsMillis: 60000    minEvictableIdleTimeMillis: 300000    validationQuery: select 'x'    testWhileIdle: true    testOnBorrow: false    testOnReturn: false    poolPreparedStatements: true    maxOpenPreparedStatements: 20mybatis:  mapper-locations: classpath:mapper/*Mapper.xml  type-aliases-package: com.springboot.yanming.mybatis.model

Mybatis部分,我们声明了Mapper类对应的.xml文件的路径(resources根路径下的mapper文件夹),和mybatis的POJO位置

到此为止,mybatis的配置部分已经结束了,我们只需要编写POJO,Mapper和Dao即可


3.编写User的Mapper类:

package com.springboot.yanming.mybatis.mapper;import com.springboot.yanming.mybatis.model.User;import org.apache.ibatis.annotations.Mapper;import org.apache.ibatis.annotations.Param;import org.apache.ibatis.annotations.Select;/** * @Author: YanMing * @Description: * @Date: Created in 12:20 2017/11/27 */@Mapperpublic interface UserMapper {    //@Select("SELECT username,password,sex FROM user WHERE username = #{username}")    User findUserByName(@Param("username")String username);    void insertUser(User user);}
Mapper类就是我们用来访问数据库的主要工具了。我们可以使用@Select等注解,直接在方法上边写动态SQL,也可以给Mapper编写一个UserMapper.xml,在XML文件中声明statement。(idea 有Mybatis 的插件,可以高亮Mapper中没有添加statement的方法,同时alt+enter生成Mapper.xml。也可以在上边提到的resources/mapper中直接添加以下UserMapper.xml)

4. 编写UserMapper.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.springboot.yanming.mybatis.mapper.UserMapper">    <sql id="ALL_COLUMN">        username,password,sex    </sql>    <insert id="insertUser" parameterType="com.springboot.yanming.mybatis.model.User">        INSERT INTO user(username, password, sex) VALUES (        #{username},        #{password},        #{sex}        )    </insert>    <select id="findUserByName" resultType="com.springboot.yanming.mybatis.model.User">        SELECT        <include refid="ALL_COLUMN"></include>        FROM user WHERE username = #{username};    </select></mapper>

到此, 我们的Mapper就声明为Bean了,可以直接使用@Autowired注入到 Dao中。Dao部分的编写比较简单,直接上代码

5. 编写DAO

package com.springboot.yanming.mybatis.dao;import com.springboot.yanming.mybatis.model.User;import org.springframework.stereotype.Repository;/** * @Author: YanMing * @Description: * @Date: Created in 12:24 2017/11/27 */public interface UserDao {    User findUserByName(String username);    void insertUser(User user);}

package com.springboot.yanming.mybatis.dao.impl;import com.springboot.yanming.mybatis.dao.UserDao;import com.springboot.yanming.mybatis.mapper.UserMapper;import com.springboot.yanming.mybatis.model.User;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Repository;/** * @Author: YanMing * @Description: * @Date: Created in 19:15 2017/11/27 */@Repositorypublic class UserDaoImpl implements UserDao{    @Autowired    UserMapper userMapper;    @Override    public User findUserByName(String username) {        return userMapper.findUserByName(username);    }    @Override    public void insertUser(User user) {        userMapper.insertUser(user);    }}

6. 编写Spirngboot Junit测试用例

package com.springboot.yanming.mybatis.mapper;import com.springboot.yanming.mybatis.MybatisApplication;import com.springboot.yanming.mybatis.dao.UserDao;import com.springboot.yanming.mybatis.model.User;import org.junit.Test;import org.junit.runner.RunWith;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.boot.SpringBootConfiguration;import org.springframework.boot.test.context.SpringBootTest;import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;import static org.junit.Assert.*;/** * @Author: YanMing * @Description: * @Date: Created in 12:28 2017/11/27 */@RunWith(SpringJUnit4ClassRunner.class)//@WebAppConfiguration@SpringBootTest(classes = MybatisApplication.class)@SpringBootConfigurationpublic class UserMapperTest {    @Autowired    UserDao userDao;    @Test    public void insertAUser(){        User user = new User();        user.setSex("man");        user.setUsername("yanming");        user.setPassword("123456");        userDao.insertUser(user);        User res = userDao.findUserByName("xiaoming");        System.out.println(res.getPassword());    }}
注意,由于我findUserByName()返回值是 User,当数据库中存在多个名字相同的用户的时候,调用此方法出错。可以将该方法返回值更改为List<User> ,其余不用更改。

B. 同时,我们也可以自定义MybatisConfig来配置Mybatis,自定义配置Mybatis有两个必需的类:

DataSourceConfig.class:配置数据库(这里使用druid)

MybatisConfig.class:配置Mybatis的sqlSessionFactory等

1. pom.xml中所需依赖(主要是mybatis,mybatis-spring,和spring-boot-starter-jdbc以及Druid)

<?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>com.springboot.yanming</groupId><artifactId>mybatisconfig</artifactId><version>0.0.1-SNAPSHOT</version><packaging>jar</packaging><name>mybatisconfig</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.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><!-- https://mvnrepository.com/artifact/org.mybatis/mybatis --><dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.4.1</version></dependency><!-- https://mvnrepository.com/artifact/org.mybatis/mybatis-spring --><dependency><groupId>org.mybatis</groupId><artifactId>mybatis-spring</artifactId><version>1.3.0</version></dependency><!-- https://mvnrepository.com/artifact/com.alibaba/druid --><dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.0.18</version></dependency><!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-jdbc --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-jdbc</artifactId><version>1.5.8.RELEASE</version></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>
2. 在application.yml中 配置数据库相关信息:

spring:  datasource:    url: jdbc:mysql://localhost:3306/springboot    username: root    password: root    type: com.alibaba.druid.pool.DruidDataSource    driver-class-name: com.mysql.jdbc.Driver    filters: stat    maxActive: 20    initialSize: 1    maxWait: 60000    minIdle: 1    timeBetweenEvictionRunsMillis: 60000    minEvictableIdleTimeMillis: 300000    validationQuery: select 'x'    testWhileIdle: true    testOnBorrow: false    testOnReturn: false    poolPreparedStatements: true    maxOpenPreparedStatements: 20

3. DataSourceConfig.class

package com.springboot.yanming.mybatisconfig.config;import com.alibaba.druid.pool.DruidDataSource;import com.alibaba.druid.support.http.StatViewServlet;import com.alibaba.druid.support.http.WebStatFilter;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.beans.factory.annotation.Value;import org.springframework.boot.web.servlet.FilterRegistrationBean;import org.springframework.boot.web.servlet.ServletRegistrationBean;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import javax.sql.DataSource;import java.sql.SQLException;/** * Created by arnold.zhu on 6/13/2017. */@Configurationpublic class DataSourceConfig {    @Value("${spring.datasource.url}")    private String dbUrl;    @Value("${spring.datasource.username}")    private String username;    @Value("${spring.datasource.password}")    private String password;    @Value("${spring.datasource.driver-class-name}")    private String driverClassName;    @Value("${spring.datasource.initialSize}")    private int initialSize;    @Value("${spring.datasource.minIdle}")    private int minIdle;    @Value("${spring.datasource.maxActive}")    private int maxActive;    @Value("${spring.datasource.maxWait}")    private int maxWait;    @Value("${spring.datasource.timeBetweenEvictionRunsMillis}")    private int timeBetweenEvictionRunsMillis;    @Value("${spring.datasource.minEvictableIdleTimeMillis}")    private int minEvictableIdleTimeMillis;    @Value("${spring.datasource.validationQuery}")    private String validationQuery;    @Value("${spring.datasource.testWhileIdle}")    private boolean testWhileIdle;    @Value("${spring.datasource.testOnBorrow}")    private boolean testOnBorrow;    @Value("${spring.datasource.testOnReturn}")    private boolean testOnReturn;    @Value("${spring.datasource.filters}")    private String filters;    @Bean    public ServletRegistrationBean druidServlet() {        ServletRegistrationBean reg = new ServletRegistrationBean();        reg.setServlet(new StatViewServlet());        reg.addUrlMappings("/druid/*");        reg.addInitParameter("loginUsername", username);        reg.addInitParameter("loginPassword", password);        return reg;    }    @Bean    public FilterRegistrationBean filterRegistrationBean() {        FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();        filterRegistrationBean.setFilter(new WebStatFilter());        filterRegistrationBean.addUrlPatterns("/*");        filterRegistrationBean.addInitParameter("exclusions", "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*");        filterRegistrationBean.addInitParameter("profileEnable", "true");        return filterRegistrationBean;    }    @Bean    public DataSource druidDataSource() {        DruidDataSource datasource = new DruidDataSource();        datasource.setUrl(dbUrl);        datasource.setUsername(username);        datasource.setPassword(password);        datasource.setDriverClassName(driverClassName);        datasource.setInitialSize(initialSize);        datasource.setMinIdle(minIdle);        datasource.setMaxActive(maxActive);        datasource.setMaxWait(maxWait);        datasource.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);        datasource.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);        datasource.setValidationQuery(validationQuery);        datasource.setTestWhileIdle(testWhileIdle);        datasource.setTestOnBorrow(testOnBorrow);        datasource.setTestOnReturn(testOnReturn);        try {            datasource.setFilters(filters);        } catch (SQLException e) {           e.printStackTrace();        }        return datasource;    }}

4. MybatisConfig.class(在类中配置了我们A方法中在application.yml中配置的信息)

package com.springboot.yanming.mybatisconfig.config;import com.alibaba.druid.pool.DruidDataSource;import org.apache.ibatis.session.SqlSessionFactory;import org.mybatis.spring.SqlSessionFactoryBean;import org.mybatis.spring.SqlSessionTemplate;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.core.io.support.PathMatchingResourcePatternResolver;import org.springframework.core.io.support.ResourcePatternResolver;import org.springframework.jdbc.datasource.DataSourceTransactionManager;import org.springframework.transaction.PlatformTransactionManager;import org.springframework.transaction.annotation.EnableTransactionManagement;import org.springframework.transaction.annotation.TransactionManagementConfigurer;import javax.sql.DataSource;/** * @Author: YanMing * @Description: * @Date: Created in 14:29 2017/11/27 */@Configuration@EnableTransactionManagementpublic class MyBatisConfig implements TransactionManagementConfigurer {    @Autowired    DataSource druidDataSource;    @Bean(name = "sqlSessionFactory")    public SqlSessionFactory sqlSessionFactoryBean() {        SqlSessionFactoryBean bean = new SqlSessionFactoryBean();        bean.setDataSource(druidDataSource);        bean.setTypeAliasesPackage("com.springboot.yanming.mybatisconfig.entity");        ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();        try {            bean.setMapperLocations(resolver.getResources("classpath:mapping/*Mapper.xml"));            return bean.getObject();        } catch (Exception e) {            e.printStackTrace();            throw new RuntimeException(e);        }    }    @Bean    public SqlSessionTemplate sqlSessionTemplate(SqlSessionFactory sqlSessionFactory) {        return new SqlSessionTemplate(sqlSessionFactory);    }    @Bean    public PlatformTransactionManager annotationDrivenTransactionManager() {        return new DataSourceTransactionManager(druidDataSource);    }}

后面关于UserMapper,XML文件和DAO部分省略,和A方法中一模一样

运行我们的测试用例:

package com.springboot.yanming.mybatisconfig.dao;import com.springboot.yanming.mybatisconfig.MybatisconfigApplication;import com.springboot.yanming.mybatisconfig.entity.User;import org.junit.Test;import org.junit.runner.RunWith;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.boot.SpringBootConfiguration;import org.springframework.boot.test.context.SpringBootTest;import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;import java.util.List;import static org.junit.Assert.*;/** * @Author: YanMing * @Description: * @Date: Created in 19:06 2017/11/27 */@RunWith(SpringJUnit4ClassRunner.class)//@WebAppConfiguration@SpringBootTest(classes = MybatisconfigApplication.class)@SpringBootConfigurationpublic class UserDaoTest {    @Autowired    UserDao userDao;    @Test    public void testUserDao(){        List<User> users = userDao.findUserByName("yanming");        System.out.println(users.size()+" user named yanming");    }}
结果是并不能运行。因为在我们自定义配置Mybatis的时候还必须给Application指明Mapper所在的路径。解决这个问题可以

1. 直接在Application上加注注解@MapperScan("com.springboot.yanming.mybatisconfig.mapper")

2. 配置MyBatisMapperScannerConfig,配置扫描Mapper所在的路径

package com.springboot.yanming.mybatisconfig.config;import org.mybatis.spring.mapper.MapperScannerConfigurer;import org.springframework.boot.autoconfigure.AutoConfigureAfter;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;@Configuration//@AutoConfigureAfter(MyBatisConfig.class)public class MapperScannerConfig {    @Bean    public MapperScannerConfigurer mapperScannerConfigurer() {        MapperScannerConfigurer mapperScannerConfigurer = new MapperScannerConfigurer();        mapperScannerConfigurer.setSqlSessionFactoryBeanName("sqlSessionFactory");        mapperScannerConfigurer.setBasePackage("com.springboot.yanming.mybatisconfig.mapper");        return mapperScannerConfigurer;    }}

在我进行学习的时候,我发现很多的资料都提到由于mapperScannerConfigurer的执行时间比较早,如果早于MyBatisConfig,那么sqlSessionFactory是无法注入的。但是我通过试验发现并没有报错,所以将@AutoConfigureAfter(MyBatisConfig.class)注释掉。

P.S.文章不妥之处还望指正

文本github源码地址

原创粉丝点击