易筋SpringBoot 2.1 | 第八篇:Mybatis访问MySQL

写作时间:2019-01-05
Spring Boot: 2.1 ,JDK: 1.8, IDE: IntelliJ IDEA, MySQL 8.0.13

什么是 MyBatis ?

MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 POJOs(Plain Old Java Objects,普通的 Java对象)映射成数据库中的记录。

MySQL准备

笔者的MySQL版本为8.0.13,搭建环境可参考文章JdbcTemplate访问MySQL

创建数据库表

# drop table  if exists city ;

CREATE TABLE city (
    id INT PRIMARY KEY auto_increment, 
    name varchar(20),
    state varchar(20),
    country varchar(20)
);

INSERT INTO city (name, state, country) VALUES ('San Francisco', 'CA', 'US');

工程建立

工程建立的时候,需要勾选SQL的MySQL和MyBatis两项:
在这里插入图片描述
参照教程【SpringBoot 2.1 | 第一篇:构建第一个SpringBoot工程】新建一个Spring Boot项目,名字叫demomysql, 在目录src/main/java/resources 下找到配置文件application.properties,重命名为application.yml

配置文件

pom.xml 依赖配置修改,mysql-connector-java改为如下 :

<dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>8.0.13</version>
      <scope>runtime</scope>
 </dependency>

数据库连接信息配置src/main/resources/application.yml

spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/db_example
    username: springuser
    password: ThePassword

配置项解析请参考文章JdbcTemplate访问MySQL

实体类

新建实体类com.zgpeace.demomybatis.bean.City

package com.zgpeace.demomybatis.bean;

import java.io.Serializable;

public class City implements Serializable {

    private static final long serialVersionUID = 1L;

    private Long id;
    private String name;
    private String state;
    private String country;

    @Override
    public String toString() {
        return String.format(
                "City[id=%d, name='%s', state='%s', country='%s']",
                id, name, state, country
        );
    }

    // getter... setter...
}

DAO层接口

新建类 com.zgpeace.demomybatis.dao.CityMapper

package com.zgpeace.demomybatis.dao;

import com.zgpeace.demomybatis.bean.City;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;

@Mapper
public interface CityMapper {

    @Select("SELECT id, name, state, country FROM city WHERE state = #{state}")
    City findByState(String state);
}

Application快速校验可用性

完善启动类com.zgpeace.demomybatis.DemomybatisApplication

package com.zgpeace.demomybatis;

import com.zgpeace.demomybatis.dao.CityMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;

@SpringBootApplication
public class DemomybatisApplication {

    @Autowired
    private CityMapper cityMapper;

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

    @Bean
    CommandLineRunner sampleCommandLineRunner() {
        return (args) -> {
            System.out.println(cityMapper.findByState("CA"));
        };
    }

}

控制台打印:

City[id=1, name='San Francisco', state='CA', country='US']

验证MyBatis用法正确,下面分层处理CRUD操作。

DAO层CRUD

完善类com.zgpeace.demomybatis.dao.CityMapper

package com.zgpeace.demomybatis.dao;

import com.zgpeace.demomybatis.bean.City;
import org.apache.ibatis.annotations.*;
import java.util.List;

@Mapper
public interface CityMapper {

    @Select("SELECT id, name, state, country FROM city WHERE state = #{state}")
    City findByState(String state);

    @Select("SELECT id, name, state, country FROM city WHERE id = #{id}")
    @Results({
            @Result(property = "id",  column = "id"),
            @Result(property = "name", column = "name"),
            @Result(property = "state",  column = "state"),
            @Result(property = "country", column = "country"),
    })
    City findById(@Param("id") int id);

    @Select("SELECT id, name, state, country FROM city")
    List<City> findCityList();

    @Insert("insert into city(name, state, country) values(#{name}, #{state}, #{country})")
    int add(@Param("name") String name, @Param("state") String state, @Param("country") String country);

    @Update("update city set name = #{name}, state = #{state}, country = #{country} where id = #{id}")
    int update(@Param("name") String name, @Param("state") String state, @Param("country") String country, @Param("id") int id);

    @Delete("delete from city where id = #{id}")
    int delete(int id);

}

代码解析:

@Select 是查询类的注解,所有的查询均使用这个
@Result 修饰返回的结果集,关联实体类属性和数据库字段一一对应,如果实体类属性和数据库属性名保持一致,就不需要这个属性来修饰。
@Insert 插入数据库使用,直接传入实体类会自动解析属性到对应的值
@Update 负责修改,也可以直接传入对象
@delete 负责删除

注意,使用#符号和$符号的不同:

// This example creates a prepared statement, something like select * from city where name = ?;
@Select("Select * from city where name = #{name}")
City selectCityByName(@Param("name") String name);

// This example creates n inlined statement, something like select * from city where name = 'someName';
@Select("Select * from city where name = '${name}'")
Teacher selectCityByName(@Param("name") String name);

了解更多属性参考这里

Service 层

新增类com.zgpeace.demomybatis.service.CityService

package com.zgpeace.demomybatis.service;

import com.zgpeace.demomybatis.bean.City;
import com.zgpeace.demomybatis.dao.CityMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class CityService {

    @Autowired
    private CityMapper cityMapper;

    public City findById(int id) {
        return cityMapper.findById(id);
    }

    public List<City> findCityList() {
        return cityMapper.findCityList();
    }

    public int add(String name, String state, String country) {
        return cityMapper.add(name, state, country);
    }

    public int update(String name, String state, String country, int id) {
        return cityMapper.update(name, state, country, id);
    }

    public int delete(int id) {
        return cityMapper.delete(id);
    }
}

Controller 层

新增类com.zgpeace.demomybatis.web.CityController

package com.zgpeace.demomybatis.web;

import com.zgpeace.demomybatis.bean.City;
import com.zgpeace.demomybatis.service.CityService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
@RequestMapping("/city")
public class CityController {

    @Autowired
    private CityService cityService;

    @GetMapping("/list")
    public List<City> getCitys() {
        return cityService.findCityList();
    }

    @GetMapping("/{id}")
    public City getCityById(@PathVariable("id") int id) {
        return cityService.findById(id);
    }

    @PutMapping("/{id}")
    public String updateCity(@PathVariable("id") int id,
                             @RequestParam(value = "name", required = true) String name,
                             @RequestParam(value = "state", required = true) String state,
                             @RequestParam(value = "country", required = true) String country) {
        int count = cityService.update(name, state, country, id);
        if (count == 1) {
            return "update success";
        } else  {
            return "update fail";
        }
    }

    @PostMapping("")
    public String addCity(@RequestParam(value = "name", required = true) String name,
                          @RequestParam(value = "state", required = true) String state,
                          @RequestParam(value = "country", required = true) String country) {
        int count = cityService.add(name, state, country);
        if (count == 1) {
            return "add success";
        } else {
            return "add fail";
        }
    }

    @DeleteMapping("/{id}")
    public String delete(@PathVariable(value = "id") int id) {
        int count = cityService.delete(id);
        if (count == 1) {
            return "delete success";
        } else {
            return "delete fail";
        }
    }

    @Transactional
    @GetMapping("/addTwoCity")
    public String addTwoCity() throws RuntimeException {
        cityService.add("HangZhou", "ZheJiang", "China");
        int temp = 1/0;
        cityService.add("WenZhou", "ZheJiang", "China");

        return "both two success";
    }
}

代码解析:
@Transactional 表示开启事务,addTwoCity()方法增加两条记录为原子性操作,因为在中间有异常,所以第一条也不会入库成功。可以尝试注释掉@Transactional,就会有第一条入库成功。

上面代码用Postman全部测试通过,Postman用法可点击链接

总结

恭喜你!学会了运用Mybatis操作数据库, 开启事务@Transactional 原子性操作。

代码下载:
https://github.com/zgpeace/Spring-Boot2.1/tree/master/demomybatis

参考:
https://github.com/mybatis/spring-boot-starter/wiki/Quick-Start
https://www.cnblogs.com/ityouknow/p/6037431.html
https://blog.csdn.net/forezp/article/details/70768477
http://www.mybatis.org/mybatis-3/zh/index.html
http://www.mybatis.org/mybatis-3/zh/java-api.html

猜你喜欢

转载自blog.csdn.net/zgpeace/article/details/85841730