Springboot整合Mybatis项目搭建

实战第一,先创建一个springboot整合mybatis的简单例子:
第一步:

  

 

 

 

创建完成后的maven配置依赖:

<?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>
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.1.1.RELEASE</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>
	<groupId>com.example</groupId>
	<artifactId>demo</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>jar</packaging>
	<name>springmybatis</name>
	<description>Demo project for Spring Boot</description>

	<properties>
		<java.version>1.8</java.version>
	</properties>

	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-jdbc</artifactId>
		</dependency>
		<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.3.2</version>
		</dependency>

		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<version>5.1.35</version>
			<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>

自动生产的配置文件是application.properties,这里我们使用更广泛使用的yml配置文件:

application.yml文件:

server:
  port: 8080
spring:
  datasource:
    url: jdbc:mysql://127.0.0.1:3306/demo?useUnicode=true&characterEncoding=utf8&autoReconnect=true&useSSL=false&serverTimezone=Asia/Shanghai
    username: root
    password: root
    driver-class-name: com.mysql.jdbc.Driver
mybatis:
  mapper-locations: classpath:mapping/*.xml  #注意:一定要对应mapper映射xml文件的所在路径

 

 我们首先在resource目录下面创建一个mapping目录,这个目录要和application.yml配置文件中的路径一致,再在路径下面配置

Demomapper.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.spring.mybatis.mapper.DemoMapper">

    <sql id="select">
        id,content,create_datetime,is_delete
    </sql>

    <select id="queryUserById" parameterType="long" resultType="com.spring.mybatis.model.Demo">
        SELECT
          id,content,create_datetime as createTime,is_delete as isDelete
        FROM demo
        <where>
            <if test="id != null">
                id = #{id}
            </if>
        </where>
    </select>
</mapper>

目录如下:

 在创建DemoMapper接口:

package com.spring.mybatis.mapper;

import com.spring.mybatis.model.Demo;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;

@Repository
public interface DemoMapper {

    Demo queryUserById(@Param("id") long id);
}

目录如下:

 接下来就是实体Demo:

package com.spring.mybatis.model;


import java.util.Date;

//get/set方法必须要有,否则mybatis查询返回会报找不到对象的错误

public class Demo {

    private long id;

    private String context;

    private Date createTime;

    private int isDelete;

    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    public String getContext() {
        return context;
    }

    public void setContext(String context) {
        this.context = context;
    }

    public Date getCreateTime() {
        return createTime;
    }

    public void setCreateTime(Date createTime) {
        this.createTime = createTime;
    }

    public int getIsDelete() {
        return isDelete;
    }

    public void setIsDelete(int isDelete) {
        this.isDelete = isDelete;
    }
}

service:

package com.spring.mybatis.service;

import com.spring.mybatis.model.Demo;

public interface DemoService {

    Demo queryUserById(long id);
}

service实现:

package com.spring.mybatis.service;

import com.spring.mybatis.mapper.DemoMapper;
import com.spring.mybatis.model.Demo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class DemoServiceImp implements DemoService {

    @Autowired
    private DemoMapper demoMapper;

    @Override
    public Demo queryUserById(long id) {
        return demoMapper.queryUserById(id);
    }
}

controller:

package com.spring.mybatis.controller;

import com.spring.mybatis.model.Demo;
import com.spring.mybatis.service.DemoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class DemoController {

    @Autowired
    private DemoService demoService;

    @GetMapping(value = "/demo/queryUserById/{id}")
    private Demo queryUserById(@PathVariable(value = "id") long id){
        return demoService.queryUserById(id);
    }
}

 

启动类:

package com.spring.mybatis;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
@MapperScan("com.spring.mybatis.mapper")//这个是要扫描的mapper接口的包路径,很重要
public class SpringmybatisApplication {

	public static void main(String[] args) {
		SpringApplication.run(SpringmybatisApplication.class, args);
	}
}

测试:

 

spring 2.1.1中默认使用的是Hikari连接池,这从日志文件中可以看出来:

 我们也可以从maven的依赖树中看出来:

mvn dependency:tree命令查看maven依赖树:

 

1、 我们也可以通过在application.yml配置文件中配置默认Hikari连接池的相关属性:

server:
  port: 8080
spring:
  datasource:
    url: jdbc:mysql://127.0.0.1:3306/demo?useUnicode=true&characterEncoding=utf8&autoReconnect=true&useSSL=false&serverTimezone=Asia/Shanghai
    username: root
    password: root
    driver-class-name: com.mysql.jdbc.Driver
    type: com.zaxxer.hikari.HikariDataSource #声明使用Hikari连接池
    hikari:
      minimum-idle: 5 #池中维护的最小空闲连接数
      maximum-pool-size: 15 #池中最大连接数
      auto-commit: true #自动提交从池中返回的连接
      idle-timeout:  50000 #连接允许在池中闲置的最长时间
      pool-name: DatebookHikariCP #线程池的名字
      max-lifetime: 1800000 #池中连接最长生命周期
      connection-timeout:  30000 #等待来自池的连接的最大毫秒数
mybatis:
  mapper-locations: classpath:mapping/*.xml  #注意:一定要对应mapper映射xml文件的所在路径

 2、我们也可以在自己通过代码注入Datasource覆盖默认的Hikari连接,为什么可以覆盖呢,我们可DataSourceConfiguration这个一看就知道是数据源的配置类)

/*
 * Copyright 2012-2018 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.springframework.boot.autoconfigure.jdbc;

import javax.sql.DataSource;

import com.zaxxer.hikari.HikariDataSource;

import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DatabaseDriver;
import org.springframework.context.annotation.Bean;
import org.springframework.util.StringUtils;

/**
 * Actual DataSource configurations imported by {@link DataSourceAutoConfiguration}.
 *
 * @author Dave Syer
 * @author Phillip Webb
 * @author Stephane Nicoll
 */
abstract class DataSourceConfiguration {

	@SuppressWarnings("unchecked")
	protected static <T> T createDataSource(DataSourceProperties properties,
			Class<? extends DataSource> type) {
		return (T) properties.initializeDataSourceBuilder().type(type).build();
	}

	/**
	 * Tomcat Pool DataSource configuration.
	 */
	@ConditionalOnClass(org.apache.tomcat.jdbc.pool.DataSource.class)
	@ConditionalOnMissingBean(DataSource.class)
	@ConditionalOnProperty(name = "spring.datasource.type", havingValue = "org.apache.tomcat.jdbc.pool.DataSource", matchIfMissing = true)
	static class Tomcat {

		@Bean
		@ConfigurationProperties(prefix = "spring.datasource.tomcat")
		public org.apache.tomcat.jdbc.pool.DataSource dataSource(
				DataSourceProperties properties) {
			org.apache.tomcat.jdbc.pool.DataSource dataSource = createDataSource(
					properties, org.apache.tomcat.jdbc.pool.DataSource.class);
			DatabaseDriver databaseDriver = DatabaseDriver
					.fromJdbcUrl(properties.determineUrl());
			String validationQuery = databaseDriver.getValidationQuery();
			if (validationQuery != null) {
				dataSource.setTestOnBorrow(true);
				dataSource.setValidationQuery(validationQuery);
			}
			return dataSource;
		}

	}

	/**
	 * Hikari DataSource configuration.
	 */
        //如果项目有HikariDataSource这个class类
	@ConditionalOnClass(HikariDataSource.class)
        //如果容器中缺少DataSource这个bean
	@ConditionalOnMissingBean(DataSource.class)
        //配置文件中是否name=spring.datasource.type这个属性,有就拿出来和havingValue的值
        //比对,如果相同则Condition生效,否则不生效,matchIfMissing表示缺少name属性是否
        //加载,true表示加载,false表示报错
	@ConditionalOnProperty(name = "spring.datasource.type", havingValue = "com.zaxxer.hikari.HikariDataSource", matchIfMissing = true)
	static class Hikari {

		@Bean
		@ConfigurationProperties(prefix = "spring.datasource.hikari")
		public HikariDataSource dataSource(DataSourceProperties properties) {
			HikariDataSource dataSource = createDataSource(properties,
					HikariDataSource.class);
			if (StringUtils.hasText(properties.getName())) {
				dataSource.setPoolName(properties.getName());
			}
			return dataSource;
		}

	}

	/**
	 * DBCP DataSource configuration.
	 */
	@ConditionalOnClass(org.apache.commons.dbcp2.BasicDataSource.class)
	@ConditionalOnMissingBean(DataSource.class)
	@ConditionalOnProperty(name = "spring.datasource.type", havingValue = "org.apache.commons.dbcp2.BasicDataSource", matchIfMissing = true)
	static class Dbcp2 {

		@Bean
		@ConfigurationProperties(prefix = "spring.datasource.dbcp2")
		public org.apache.commons.dbcp2.BasicDataSource dataSource(
				DataSourceProperties properties) {
			return createDataSource(properties,
					org.apache.commons.dbcp2.BasicDataSource.class);
		}

	}

	/**
	 * Generic DataSource configuration.
	 */
	@ConditionalOnMissingBean(DataSource.class)
	@ConditionalOnProperty(name = "spring.datasource.type")
	static class Generic {

		@Bean
		public DataSource dataSource(DataSourceProperties properties) {
			return properties.initializeDataSourceBuilder().build();
		}

	}

}

 从Hikari数据源的配置注解就可以看出如果项目有HikariDataSource这个class类同时容器中缺少自定义的Datasource这个Bean,那么就会生成一个HikariDataSource,从配置中可以看出,除了HikariDataSource我们还可以配置Dbcp2和tomcat数据源,换数据源也是非常简单的,我们只需导入要调换的数据源的jar包,配置文件做相应的配置就可以了;

注: //配置文件中是否name=spring.datasource.type这个属性,有就拿出来和havingValue的值
        //比对,如果相同则Condition生效,否则不生效,matchIfMissing表示缺少name属性是否
        //加载,true表示加载,false表示报错
       @ConditionalOnProperty(name = "spring.datasource.type", havingValue = "com.zaxxer.hikari.HikariDataSource",         matchIfMissing = true)

我们来尝试一下换tomcat数据源:

第一步:修改application.yml配置文件:

 第二步:引入tomacat的maven依赖:

   <!-- 配置tomcat数据源-->
		<dependency>
			<groupId>org.apache.tomcat</groupId>
			<artifactId>tomcat-jdbc</artifactId>
		</dependency>

现在我们来看效果,通过debug我们可以很清楚的看见现在创建的就是tomcat数据源:

 除了使用通过配置文件配置默认的数据源,我们也可以通过代码自己注入自定义的数据源bean覆盖默认的数据源配置;

下面我们自定义一个HikariDataSource数据源代替默认的HikariDataSource数据源,代码如下:

package com.spring.mybatis.config;

import com.zaxxer.hikari.HikariDataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;

import javax.sql.DataSource;

@Configuration
public class DataSourceConfig {

    private final Environment environment;

    @Autowired
    public  DataSourceConfig(Environment environment){
        this.environment = environment;
    }

    @Bean
    public DataSource dataSource(){
        HikariDataSource dataSource = new HikariDataSource();
        dataSource.setDriverClassName(environment.getProperty("spring.datasource.driver-class-name"));
        dataSource.setJdbcUrl(environment.getProperty("spring.datasource.url"));
        dataSource.setUsername(environment.getProperty("spring.datasource.username"));
        dataSource.setPassword(environment.getProperty("spring.datasource.password"));
        dataSource.setPoolName(environment.getProperty("spring.datasource.hikari.pool-name"));
        dataSource.setAutoCommit(Boolean.getBoolean(environment.getProperty("spring.datasource.hikari.auto-commit")));
        dataSource.setMaximumPoolSize(Integer.valueOf(environment.getProperty("spring.datasource.hikari.maximum-pool-size")));
        System.out.println(dataSource);
        return dataSource;
    }
}

 

3、通过代码的方式注入mybatis的配置bean的,如SqlsessionFactory、SqlSessionTemplate、PlatformTransactionManager等:

package com.spring.mybatis.config;

import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import javax.sql.DataSource;
import java.io.IOException;
import java.util.Properties;

@Configuration
@EnableTransactionManagement //开启注解事物管理
@MapperScan(basePackages = "com.spring.mybatis.mapper" ,sqlSessionFactoryRef = "sqlSessionFactory")
public class MybatisConfig {

    @Autowired
    @Qualifier("dataSource")
    private DataSource dataSource;


    //配置sqlSessionFactory
    //自动装配时当出现多个Bean候选者时,被注解为@Primary的Bean将作为首选者,否则将抛出异常
    @Bean(name = "sqlSessionFactory")
    @Primary
    public SqlSessionFactory getSqlSessionFactory() throws IOException {
        SqlSessionFactory sessionFactory = null;
        SqlSessionFactoryBean sessionFactoryBean = new SqlSessionFactoryBean();
        Resource[] resources = new Resource[1];
       /*
        Resource方式只能一个一个列出mapper文件
       Resource resource = new ClassPathResource("mapping/DemoMapper.xml");
        resources[0] = resource;*/
       //PathMatchingResourcePatternResolver方式可以使用正则匹配
        PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
        sessionFactoryBean.setMapperLocations(resolver.getResources("classpath:mapping/*.xml"));
        //给entity取别名,这样在mapper文件中就可以使用缩写,默认别名是类名,不区分大小写
        sessionFactoryBean.setTypeAliasesPackage("com.spring.mybatis.model");
        sessionFactoryBean.setDataSource(this.dataSource);
        Properties mybatisProperties = new Properties();
        mybatisProperties.setProperty("dialect", "mysql");
        sessionFactoryBean.setConfigurationProperties(mybatisProperties);
        try {
            sessionFactory = sessionFactoryBean.getObject();
            sessionFactory.getConfiguration().setCacheEnabled(true);
            sessionFactory.getConfiguration().setMapUnderscoreToCamelCase(true);
            return  sessionFactory;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return sessionFactory;
    }


    //配置sqlSessionTemplate
    @Bean(name = "sqlSessionTemplate")
    @Primary
    public SqlSessionTemplate getSqlSessionTemplate(SqlSessionFactory sqlSessionFactory){
        return new SqlSessionTemplate(sqlSessionFactory);
    }

    //注入事物管理器实例关于事务管理器,不管是JPA还是JDBC等都实现自接口 PlatformTransactionManager 、
    // 如果你添加的是 spring-boot-starter-jdbc 依赖,框架会默认注入 DataSourceTransactionManager 实例。
    // 如果你添加的是 spring-boot-starter-data-jpa 依赖,框架会默认注入 JpaTransactionManager 实例。
    @Bean
    public PlatformTransactionManager transactionManager(){
        return new DataSourceTransactionManager(this.dataSource);
    }
}

注意:

1、sessionFactoryBean.setMapperLocations(resolver.getResources("classpath:mapping/*.xml"));

扫描mapper文件的路径,支持正则匹配;

2、sessionFactoryBean.setTypeAliasesPackage("com.spring.mybatis.model");

给entity取别名,这样在mapper文件中就可以使用缩写,默认别名是类名,不区分大小写

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值