springboot整合Mybatis(一)——入门

时间:2023-03-09 13:31:56
springboot整合Mybatis(一)——入门

一、概述

  1.先导

    mybatis入门随笔:http://www.cnblogs.com/jiangbei/p/6884641.html

  2.引入依赖

       <dependency>
   <groupId>org.mybatis.spring.boot</groupId>
   <artifactId>mybatis-spring-boot-starter</artifactId>
   <version>1.3.0</version>
</dependency>

    //其他必须的依赖还包括mysql连接,web依赖(web项目),此处贴出完整依赖(有部分依赖例如jpa此处可不选)

<?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.example</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging> <name>springboot_demo</name>
<description>Demo project for Spring Boot</description> <parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.4.7.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.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<!--spring-boot-starter-data-jpa包含spring-data-jpa、spring-orm 和 Hibernate 来支持 JPA-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<!-- mysql连接-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!-- mybatis-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.0</version>
</dependency>
<!-- 阿里druid连接池 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.6</version>
</dependency>
<!-- AOP支持-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<!-- spring-boot-devtools热部署支持-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
</dependencies> <build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<dependencies>
<!-- spring热部署 -->
<!-- <dependency>
<groupId>org.springframework</groupId>
<artifactId>springloaded</artifactId>
<version>1.2.6.RELEASE</version>
</dependency>-->
</dependencies>
</plugin>
</plugins>
</build> </project>

pom.xml 

  额外功能(后文陆续补充)

    •   PageHelper 分页插件
    •   mybatis generator 自动生成代码插件

   3.数据源配置

    依旧是前文的druid数据源

spring:
datasource:
type: com.alibaba.druid.pool.DruidDataSource
driverClassName: com.mysql.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/sakila
username: root
password: root
# druid配置项,默认spring-boot不支持,故需要config类来解析
initialSize: 5
minIdle: 5
maxActive: 20
maxWait: 60000
timeBetweenEvictionRunsMillis: 60000
minEvictableIdleTimeMillis: 300000
validationQuery: SELECT 1 FROM DUAL
testWhileIdle: true
testOnBorrow: false
testOnReturn: false
poolPreparedStatements: true
maxPoolPreparedStatementPerConnectionSize: 20
filters: stat,wall,log4j
connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000

application.yml

  4.起步

    以下介绍两种整合方式:

      传统的mapper.xml映射文件

      springboot提倡的无配置注解形式

二、无配置注解形式

  1.配置mybatis:

mybatis:
type-aliases-package: com.example.demo.bean

// 包别名简写

  2.Bean

    沿用之前的bean:girl

package com.example.demo.bean;

import javax.validation.constraints.Min;
import javax.validation.constraints.Size; /**
* girl的bean
*
* @author zcc ON 2018/2/9
**/ public class Girl {
private Integer id;
@Size(min = 3, max = 8, message = "名称长度不合法!")
private String name;
@Min(value = 18, message = "未成年禁止入内!")
private Integer age; public Girl() {
} public Girl(String name, Integer age) {
this.name = name;
this.age = age;
} public Integer getId() {
return id;
} public void setId(Integer id) {
this.id = id;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public Integer getAge() {
return age;
} public void setAge(Integer age) {
this.age = age;
} @Override
public String toString() {
return "Girl{" +
"id=" + id +
", name='" + name + '\'' +
", age=" + age +
'}';
}
}

Girl.java

  3.Mapper 

package com.example.demo.mapper;

import com.example.demo.bean.Girl;
import org.apache.ibatis.annotations.*; import java.util.List; /**
* GirlMapper
*
* @author zcc
**/
// @Mapper 这里可以使用@Mapper注解,但是每个mapper都加注解比较麻烦,所以也可以统一配置@MapperScan在扫描路径在application类中
@Mapper
public interface GirlMapper { @Select("SELECT * FROM girl WHERE id = #{id}")
Girl findGirlById(Integer id); @Select("SELECT * FROM girl")
List<Girl> findAll(); @Insert("INSERT INTO girl VALUES(NULL,#{age},#{name})")
int addGirl(Girl girl); @Update("UPDATE girl SET age = #{girl.age},name = #{girl.name} WHERE id = #{id}")
int updateGirl(@Param("id") Integer id, @Param("girl") Girl girl); @Delete("DELETE FROM girl WHERE id = #{id}")
int deleteGirl(Integer id);
}

    以上注解的使用基本与之前xml中的用法一致,完整注解,参考官网:http://www.mybatis.org/mybatis-3/zh/java-api.html

  当然,需要注意的是,mybatis官网给出了使用注解的注意点:

不幸的是,Java 注解限制了它们的表现和灵活。尽管很多时间都花调查,设计和 实验上,最强大的 MyBatis 映射不能用注解来构建,那并不可笑。

  4.测试

    启动类:

package com.example.demo;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication
// @MapperScan("cn.demo.mapper") 若Mapper上不加注解,则在这里统一扫描
public class SpringbootDemoApplication { public static void main(String[] args) {
SpringApplication.run(SpringbootDemoApplication.class, args);
}
}

   controller:

 @GetMapping(value = "/girl/{id}")
public Girl findGirlById(@PathVariable("id") Integer id) {
return girlService.findGirlById(id);
}
@PutMapping(value = "/girl/{id}")
public Integer updateGirlById(@PathVariable("id") Integer id, Girl girl) {
return girlService.updateGirl(id, girl);
}
package com.example.demo.controller;

import com.example.demo.bean.Girl;
import com.example.demo.bean.Result;
import com.example.demo.dao.GirlRepository;
import com.example.demo.service.GirlService;
import com.example.demo.utils.ResultUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.annotation.*; import javax.validation.Valid;
import java.util.List; /**
* controller
*
* @author zcc ON 2018/2/9
**/
@RestController
public class GirlController {
/**
* 简单的逻辑,这里就暂时省略service了
*/
private static final Logger log = LoggerFactory.getLogger(GirlController.class);
@Autowired
private GirlRepository girlRepository;
@Autowired
private GirlService girlService;
@GetMapping(value = "/girls")
public List<Girl> getList() {
// 直接调用findAll()即可,已经封装了!
return girlRepository.findAll();
} /**
* 可以使用此方式进行参数绑定
*/
/*@PostMapping(value = "/girls")
public String addGirl(@RequestParam("age") Integer age, String name) {
return null;
}*/ /**
* 更推荐bean进行绑定(这里规则和springMVC是一样的)
* @param girl 实体
* @return
*/
@PostMapping(value = "/girls")
public Result<Object> addGirl(@Valid Girl girl, BindingResult bindingResult) {
// 表单验证逻辑
if (bindingResult.hasErrors()) {
List<FieldError> fieldErrors = bindingResult.getFieldErrors();
StringBuffer sb = new StringBuffer();
for (FieldError fieldError : fieldErrors) {
sb.append(fieldError.getDefaultMessage());
}
return ResultUtils.error(sb.toString());
}
return ResultUtils.success(girlRepository.save(girl));
}
@GetMapping(value = "/girls/{id}")
public Girl getGirlById(@PathVariable("id") Integer id) {
// 推荐使用更加通用的findOne()!
return girlRepository.findOne(id);
}
@PutMapping(value = "/girls/{id}")
public Girl updateGirlById(@PathVariable("id") Integer id, String name) {
Girl girl = new Girl();
girl.setId(id);
girl.setName(name);
return girlRepository.save(girl);
}
@DeleteMapping(value = "/girls/{id}")
public String deleteGirlById(@PathVariable("id") Integer id) {
girlRepository.delete(id);
return "删除ID为:" + id + " 的女生成功!";
}
@GetMapping(value = "/girls/age/{age}")
public List<Girl> getListByAge(@PathVariable("age") Integer age) {
return girlRepository.findByAge(age);
}
@PostMapping(value = "/girls/two")
public void insertTwo() {
girlService.insertTwo();
}
@GetMapping(value = "/girls/getAge/{id}")
public void getAge(@PathVariable("id") Integer id) {
// 判断应该交给service
girlService.getAge(id);
}
@GetMapping(value = "/ageAndId/{name}/{id}")
public List<Girl> testKeyWords(@PathVariable("name") String name, @PathVariable("id") Integer id) {
return girlService.findByNameStartingWithAndIdLessThan(name, id);
} @GetMapping(value = "/girl/{id}")
public Girl findGirlById(@PathVariable("id") Integer id) {
return girlService.findGirlById(id);
}
@PutMapping(value = "/girl/{id}")
public Integer updateGirlById(@PathVariable("id") Integer id, Girl girl) {
return girlService.updateGirl(id, girl);
}
}

controller

  service:

  public Girl findGirlById(Integer id) {
return girlMapper.findGirlById(id);
} public int updateGirl(Integer id, Girl girl) {
return girlMapper.updateGirl(id, girl);
}
package com.example.demo.service;

import com.example.demo.dao.GirlRepository;
import com.example.demo.bean.Girl;
import com.example.demo.enums.ResultEnum;
import com.example.demo.exception.MyException;
import com.example.demo.mapper.GirlMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import java.util.List; /**
* service
*
* @author zcc ON 2018/2/9
**/
@Service
public class GirlService {
@Autowired
private GirlRepository girlRepository;
@Autowired
private GirlMapper girlMapper;
@Transactional
public void insertTwo() {
Girl girl1 = new Girl("Nana", 18);
Girl girl2 = new Girl("Lala", 19);
girlRepository.save(girl1);
girlRepository.save(girl2);
} public void getAge(Integer id) {
Integer age = girlRepository.findOne(id).getAge();
if (age < 12) {
// 小学生
throw new MyException(ResultEnum.PRIMARY);
} else {
// 上初中了
throw new MyException(ResultEnum.MIDDLE);
}
} /**
* 通过id查询
* @param id 实体类id
* @return
*/
public Girl findOne(Integer id) {
return girlRepository.findOne(id);
}
public List<Girl> findByNameStartingWithAndIdLessThan(String name, Integer id) {
return girlRepository.findByNameStartingWithAndIdLessThan(name, id);
} public Girl findGirlById(Integer id) {
return girlMapper.findGirlById(id);
} public int updateGirl(Integer id, Girl girl) {
return girlMapper.updateGirl(id, girl);
}
}

service

   注入mapper报错的处理(不影响实际使用,强迫症可选)

springboot整合Mybatis(一)——入门

  实际测试可以使用经典的postman,也推荐IDEA自带的tool——REST Client

三、经典注解版

  基本代码类似,只是少数代码更改

  项目结构:

    springboot整合Mybatis(一)——入门

  yml配置mybatis:

mybatis:
type-aliases-package: com.example.demo.bean
mapper-locations: classpath:mybatis/mapper/*.xml
config-location: classpath:mybatis/mybatis-config.xml

  // 别名也可以在mybatis-config.xml中进行配置!,默认别名参考文档:点击查看

  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>
<typeAliases>
</typeAliases>
</configuration>

  mapper:

package com.example.demo.mapper;

import com.example.demo.bean.Girl;
import org.apache.ibatis.annotations.Param; import java.util.List; /**
* GirlMapper
*
* @author zcc
**/
// 这里不在这里加@Repository注解,统一在启动类通过MapperScan扫描
public interface GirlMapper { Girl findGirlById(Integer id); List<Girl> findAll(); int addGirl(Girl girl); int updateGirl(@Param("id") Integer id, @Param("girl") Girl girl); int deleteGirl(Integer id);
}

  mapper.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接口代理实现编写规则:
1.映射文件中namespace要等于接口的全路径
2.映射文件中sql语句的id要等于接口的方法名
3.映射文件中传入参数类型要等于接口方法的入参
4.映射文件返回值类型要等于接方法的返回值类型
-->
<mapper namespace="com.example.demo.mapper.GirlMapper">
<resultMap id="BaseResultMap" type="girl">
<id column="id" property="id" jdbcType="INTEGER"/>
<result column="age" property="age" jdbcType="INTEGER"/>
<result column="name" property="name" jdbcType="VARCHAR"/>
</resultMap> <sql id="Base_Column_List">
id,age,name
</sql> <select id="findGirlById" parameterType="integer" resultMap="BaseResultMap">
SELECT
<include refid="Base_Column_List"/>
FROM girl
WHERE id = #{id}
</select> <select id="findAll" resultMap="BaseResultMap">
SELECT
<include refid="Base_Column_List"/>
FROM girl
</select> <select id="addGirl" parameterType="girl">
INSERT INTO
girl(age,name)
VALUES(#{age},#{name})
</select> <update id="updateGirl" parameterType="girl">
UPDATE
girl
SET
age = #{age},name = #{name}
WHERE
id = #{id}
</update> <delete id="deleteGirl" parameterType="integer">
DELETE
FROM
girl
WHERE
id = #{id}
</delete>
</mapper>

  mapper中的各种警告处理(不影响使用,强迫症可以进行设置):

  springboot整合Mybatis(一)——入门