[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即可
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源码地址
- [Spring Boot实战系列]
- [Spring Boot实战系列]
- [Spring Boot实战系列]
- [Spring Boot实战系列]
- Spring Boot实战系列教程
- spring boot学习系列:spring boot的单元测试实战
- Spring boot实战一书问题解惑系列
- spring boot实战一
- Spring Boot实战
- spring boot实战笔记
- Spring Boot 实战(一)
- Spring Boot实战笔记
- Spring Boot实战
- Spring Boot实战pdf
- Spring Boot实战 目录
- 《Spring Boot 实战》-- 读书笔记
- spring-boot实战:shiro
- Spring Boot功能实战
- 【现代前端】HTML基础 DOCTYPE AMP HTML
- 图片上传
- HTTP Status 500
- Spring的Ioc和Di
- Javascript入门一
- [Spring Boot实战系列]
- 最优化问题综述
- 第八章.对象的容纳 -----Thinking in java 更新中……
- 图解设计模式
- sdnu 1521(快速排序)
- 高阶导数的运算法则 与 莱布尼茨公式
- 拥塞控制分析之Compound
- 二、c++猜数字游戏
- 疯狂Activiti6.0连载(19)Activiti整合Spring