什么是Mybatis
MyBatis 是一款优秀的持久层框架,它支持自定义 SQL、存储过程以及高级映射。可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。
? 在mybatis这类框架没有出现之前,大多通过 jdbc连接数据库的方式,在java代码中拼接sql语句然后执行,具体如下:
1.加载JDBC驱动程序:
Class.forName("com.mysql.jdbc.Driver") ;
2.创建数据库的连接:
Connection con = DriverManager.getConnection(url , username , password ) ;
3.执行预编译语句:
Statement stmt = con.createStatement() ;
ResultSet rs = stmt.executeQuery("SELECT * FROM ...") ;
4.遍历结果集进行数据解析:
while(rs.next()){
String name = rs.getString("name") ;
String pass = rs.getString(1) ;
}
mybatis框架对以上过程进行封装和优化,包括:可以配置数据源建立连接池;将java和 sql语句分离,sql语句可以写在xml配置文件中,接口定义在java中;自定义结果集和实体对象的转换。极大提高了开发人员的编码效率,提高了代码的可读性,节约数据库的性能。
本教程使用如下版本
spring boot 2.7.0
mybatis 2.1.3
druid 1.2.1
mysql 5.6
整合
创建项目
新建一个spring boot 项目。可以通过我之前的教程创建一个空项目。
Spring Boot 新手入门
编辑pom文件
在idea中新建一个maven项目后,首先需要在pom文件中引入如下依赖。
主要包含:mybatis依赖,druid依赖,mysql依赖
<properties>
<java.version>1.8</java.version>
</properties>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.0</version>
<relativePath/>
</parent>
<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-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.3</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.2.1</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<mainClass>com.study.MainStarter</mainClass>
<jvmArguments>-Dfile.encoding=UTF-8</jvmArguments>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
不要忘记重新加载一下依赖,防止找不到jar包!依次点击maven,项目名称=》右键=》Reimport
目录结构
建立好如下图的包目录结构,具体如下:
建表语句
在mysql5.6 数据库中执行我们设计好的建表语句。
CREATE DATABASE /*!32312 IF NOT EXISTS*/studydb /*!40100 DEFAULT CHARACTER SET utf8 */;
USE studydb;
DROP TABLE IF EXISTS ser_company;
CREATE TABLE ser_company (
company_id int(11) NOT NULL AUTO_INCREMENT COMMENT '公司id',
company_name varchar(64) DEFAULT NULL COMMENT '公司名称',
company_code varchar(4) DEFAULT NULL COMMENT '公司编号',
company_msg text COMMENT '公司简介',
company_crdt timestamp NULL DEFAULT NULL COMMENT '创建时间',
PRIMARY KEY (company_id)
) ENGINE=InnoDB AUTO_INCREMENT=18 DEFAULT CHARSET=utf8;
配置数据源及mybatis
在 application.properties 配置文件中增加如下配置:
spring.datasource.driverClassName=com.mysql.cj.jdbc.Driver
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/studydb?serverTimezone=UTC&useUnicode=true&characterEncoding=UTF-8
spring.datasource.username=root
spring.datasource.password=root
spring.thymeleaf.cache=false
mybatis.mapper-locations=classpath:mapper/*.xml
mybatis.type-aliases-package=com.study.model
logging.level.com.study.* = debug
注意到上述配置文件中的数据库地址,账号,密码,mapper映射路径,实体别名路径,以及日志需要修改至自己有的数据库中。配置mapper映射路径会在spring boot 容器时自动扫描该路径下的文件。配置实体别名包路径可以在编写xml中的类名时不需要写实体类的包名。这里使用的是阿里巴巴druid数据库连接组件。
实体类
在com.study.model包下编写一个实体类,对应ser_company表中的实体。我们以公司对象为例,包含公司名称,公司代码,公司信息,入库时间等字段。代码如下:
package com.study.model;
import org.apache.ibatis.type.Alias;
@Alias("SerCompanyVO")
public class SerCompanyVO {
private int companyId;
private String companyName;
private String companyCode;
private String companyMsg;
private String companyCrdt;
public int getCompanyId() {
return companyId;
}
public void setCompanyId(int companyId) {
this.companyId = companyId;
}
public String getCompanyName() {
return companyName;
}
public void setCompanyName(String companyName) {
this.companyName = companyName;
}
public String getCompanyCode() {
return companyCode;
}
public void setCompanyCode(String companyCode) {
this.companyCode = companyCode;
}
public String getCompanyMsg() {
return companyMsg;
}
public void setCompanyMsg(String companyMsg) {
this.companyMsg = companyMsg;
}
public String getCompanyCrdt() {
return companyCrdt;
}
public void setCompanyCrdt(String companyCrdt) {
this.companyCrdt = companyCrdt;
}
}
dao
在com.study.dao包下编辑SerCompanyMapper类,映射xml中的相关接口。这里可以选择一个接口例如selectSerCompanyList进行练习。本教程中包含多个接口。除了增加修改删除查询以外。本教程包含批量插入,动态语句插入并返回主键,动态语句修改等示例接口。代码如下:
package com.study.dao;
import com.study.model.SerCompanyVO;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
@Mapper
public interface SerCompanyMapper {
List<SerCompanyVO> selectSerCompanyList();
SerCompanyVO selectSerCompanyById(Integer companyId);
int insertSerCompanyVO(SerCompanyVO serCompanyVO);
int insertSerCompanyDynamic(SerCompanyVO serCompanyVO);
int insertCompanyBatch(List<SerCompanyVO> list);
int updateCompany(SerCompanyVO serCompanyVO);
int updateCompanyDynamic(SerCompanyVO serCompanyVO);
int deleteCompanyById(Integer companyId);
}
xml
在mapper目录下,新建SerCompanyMapper.xml并编写如下代码:
namespace 为 dao层接口类的路径。
resultMap对查询的结果集进行封装为SerCompanyVO对象。
foreach标签可以对list参数进行遍历。
useGeneratedKeys、keyProperty在插入后可以返回主键。
<?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.study.dao.SerCompanyMapper">
<resultMap id="resultMap" type="SerCompanyVO">
<id column="company_id" property="companyId" jdbcType="INTEGER" />
<result column="company_name" property="companyName" jdbcType="VARCHAR" />
<result column="company_code" property="companyCode" jdbcType="VARCHAR" />
<result column="company_msg" property="companyMsg" jdbcType="VARCHAR" />
<result column="company_crdt" property="companyCrdt" jdbcType="VARCHAR" />
</resultMap>
<insert id="insertSerCompanyVO" useGeneratedKeys="true" keyProperty="companyId">
insert into ser_company(
company_name,
company_code,
company_msg,
company_crdt
) values (
#{companyName, jdbcType=VARCHAR},
#{companyCode, jdbcType=VARCHAR},
#{companyMsg, jdbcType=VARCHAR},
#{companyCrdt, jdbcType=TIMESTAMP}
)
</insert>
<insert id="insertSerCompanyDynamic" useGeneratedKeys="true" keyProperty="companyId">
insert into ser_company(
<if test="null != companyName and ''!= companyName">
company_name,
</if>
<if test="null != companyCode and ''!= companyCode">
company_code,
</if>
<if test="null != companyMsg and ''!= companyMsg">
company_msg,
</if>
<if test="null != companyCrdt and ''!= companyCrdt">
company_crdt
</if>
) values (
<if test="null != companyName and ''!= companyName">
#{companyName, jdbcType=VARCHAR},
</if>
<if test="null != companyCode and ''!= companyCode">
#{companyCode, jdbcType=VARCHAR},
</if>
<if test="null != companyMsg and ''!= companyMsg">
#{companyMsg, jdbcType=VARCHAR},
</if>
<if test="null != companyCrdt and ''!= companyCrdt">
#{companyCrdt, jdbcType=TIMESTAMP}
</if>
)
</insert>
<insert id="insertCompanyBatch">
insert into ser_company(
company_name,
company_code,
company_msg,
company_crdt
) values
<foreach collection="list" item="item" separator=",">
(
#{item.companyName, jdbcType=VARCHAR},
#{item.companyCode, jdbcType=VARCHAR},
#{item.companyMsg, jdbcType=VARCHAR},
#{item.companyCrdt, jdbcType=TIMESTAMP}
)
</foreach>
</insert>
<update id="updateCompanyDynamic" >
update ser_company set
<if test="null != companyName and ''!= companyName">
company_name = #{companyName, jdbcType=VARCHAR},
</if>
<if test="null != companyCode and ''!= companyCode">
company_code = #{companyCode, jdbcType=VARCHAR},
</if>
<if test="null != companyMsg and ''!= companyMsg">
company_msg = #{companyMsg, jdbcType=VARCHAR},
</if>
<if test="null != companyCrdt and ''!= companyCrdt">
company_crdt = #{companyCrdt, jdbcType=TIMESTAMP}
</if>
where company_id = #{companyId, jdbcType=INTEGER}
</update>
<update id="updateCompany">
update ser_company set
company_name = #{companyName, jdbcType=VARCHAR},
company_code = #{companyCode, jdbcType=VARCHAR},
company_msg = #{companyMsg, jdbcType=VARCHAR},
company_crdt = #{companyCrdt, jdbcType=TIMESTAMP}
where company_id = #{companyId, jdbcType=INTEGER}
</update>
<delete id="deleteCompanyById">
delete from ser_company where company_id = #{companyId, jdbcType=INTEGER}
</delete>
<select id="selectSerCompanyList" resultMap="resultMap">
select company_name, company_code, company_msg, company_crdt from ser_company
</select>
<select id="selectSerCompanyById" resultMap="resultMap" parameterType="java.lang.Integer">
select company_id,company_name, company_code, company_msg, company_crdt from ser_company where company_id=#{companyId, jdbcType=INTEGER}
</select>
</mapper>
service及实现类
在com.study.service包下 新建 SerCompanyService接口,代码如下:
package com.study.service;
import com.study.model.SerCompanyVO;
import java.util.List;
public interface SerCompanyService {
List<SerCompanyVO> querySerCompanyList();
int addCompany(SerCompanyVO serCompanyVO);
int addCompanyDynamic(SerCompanyVO serCompanyVO);
int addCompanyBatch(List<SerCompanyVO> list);
SerCompanyVO querySerCompanyById(Integer companyId);
int updateCompany(SerCompanyVO serCompanyVO);
int updateCompanyDynamic(SerCompanyVO serCompanyVO);
int deleteCompanyById(Integer companyId);
}
在com.study.service.impl包下新建SerCompanyServiceImpl实现类,代码如下:
这里使用了我们刚刚写好的SerCompanyMapper。通过该类进行mybatis xml中语句的调用。
package com.study.service.impl;
import com.study.dao.SerCompanyMapper;
import com.study.model.SerCompanyVO;
import com.study.service.SerCompanyService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class SerCompanyServiceImpl implements SerCompanyService {
private Logger log = LoggerFactory.getLogger(this.getClass().getName());
@Autowired
private SerCompanyMapper serCompanyMapper;
@Override
public List<SerCompanyVO> querySerCompanyList() {
return serCompanyMapper.selectSerCompanyList();
}
@Override
public int addCompany(SerCompanyVO serCompanyVO) {
return serCompanyMapper.insertSerCompanyVO(serCompanyVO);
}
@Override
public int addCompanyDynamic(SerCompanyVO serCompanyVO) {
return serCompanyMapper.insertSerCompanyDynamic(serCompanyVO);
}
@Override
public int addCompanyBatch(List<SerCompanyVO> list) {
return serCompanyMapper.insertCompanyBatch(list);
}
@Override
public SerCompanyVO querySerCompanyById(Integer companyId) {
return serCompanyMapper.selectSerCompanyById(companyId);
}
@Override
public int updateCompany(SerCompanyVO serCompanyVO) {
return serCompanyMapper.updateCompany(serCompanyVO);
}
@Override
public int updateCompanyDynamic(SerCompanyVO serCompanyVO) {
return serCompanyMapper.updateCompanyDynamic(serCompanyVO);
}
@Override
public int deleteCompanyById(Integer companyId) {
return serCompanyMapper.deleteCompanyById(companyId);
}
}
controller
在com.study.controller中新建如下类:
package com.study.controller;
import com.study.model.SerCompanyVO;
import com.study.service.SerCompanyService;
import com.study.util.ResultUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@Controller
public class SerCompanyController {
private Logger log = LoggerFactory.getLogger(this.getClass().getName());
@Autowired
private SerCompanyService serCompanyService;
@RequestMapping(method= RequestMethod.GET, value = "querySerCompanyList")
@ResponseBody
public List<SerCompanyVO> querySerCompanyList(){
if(log.isDebugEnabled()){
log.debug("do querySerCompanyList begin.");
}
return serCompanyService.querySerCompanyList();
}
@RequestMapping(method= RequestMethod.GET, value = "querySerCompanyById")
@ResponseBody
public SerCompanyVO querySerCompanyById(Integer companyId){
return serCompanyService.querySerCompanyById(companyId);
}
@RequestMapping(method= RequestMethod.GET, value = "addCompany")
@ResponseBody
public Map<String, Object> addCompany(SerCompanyVO serCompanyVO){
if(log.isDebugEnabled()){
log.debug("companyName:{}", serCompanyVO.getCompanyName());
}
Timestamp timestamp = new Timestamp(System.currentTimeMillis());
serCompanyVO.setCompanyCrdt(timestamp.toString());
int num = serCompanyService.addCompany(serCompanyVO);
Map<String ,Object> map = ResultUtil.getRsMap(num);
map.put("serCompanyVO", serCompanyVO);
return map;
}
@RequestMapping(method= RequestMethod.GET, value = "addCompanyDynamic")
@ResponseBody
public Map<String, Object> addCompanyDynamic(SerCompanyVO serCompanyVO){
if (log.isDebugEnabled()){
log.debug("companyName:{}", serCompanyVO.getCompanyName());
}
Timestamp timestamp = new Timestamp(System.currentTimeMillis());
serCompanyVO.setCompanyCrdt(timestamp.toString());
int num = serCompanyService.addCompanyDynamic(serCompanyVO);
Map<String ,Object> map = ResultUtil.getRsMap(num);
map.put("serCompanyVO", serCompanyVO);
return map;
}
@RequestMapping(method = RequestMethod.GET, value = "addCompanyBatch")
@ResponseBody
public Map<String, Object> addCompanyBatch(){
Timestamp timestamp = new Timestamp(System.currentTimeMillis());
String timeStr = timestamp.toString();
SerCompanyVO serCompanyVO = new SerCompanyVO();
serCompanyVO.setCompanyName("导入1");
serCompanyVO.setCompanyCode("3301");
serCompanyVO.setCompanyCrdt(timeStr);
SerCompanyVO serCompanyVO1 = new SerCompanyVO();
serCompanyVO1.setCompanyName("导入2");
serCompanyVO1.setCompanyCode("3302");
serCompanyVO1.setCompanyCrdt(timeStr);
List<SerCompanyVO> list = new ArrayList<>();
list.add(serCompanyVO);
list.add(serCompanyVO1);
int num = serCompanyService.addCompanyBatch(list);
return ResultUtil.getRsMap(num);
}
@RequestMapping(method = RequestMethod.GET, value = "updateCompany")
@ResponseBody
public Map<String, Object> updateCompany(SerCompanyVO serCompanyVO){
Timestamp timestamp = new Timestamp(System.currentTimeMillis());
String timeStr = timestamp.toString();
serCompanyVO.setCompanyCrdt(timeStr);
int num = serCompanyService.updateCompany(serCompanyVO);
return ResultUtil.getRsMap(num);
}
@RequestMapping(method = RequestMethod.GET, value = "updateCompanyDynamic")
@ResponseBody
public Map<String, Object> updateCompanyDynamic(SerCompanyVO serCompanyVO){
Timestamp timestamp = new Timestamp(System.currentTimeMillis());
String timeStr = timestamp.toString();
serCompanyVO.setCompanyCrdt(timeStr);
int num = serCompanyService.updateCompanyDynamic(serCompanyVO);
return ResultUtil.getRsMap(num);
}
@RequestMapping(method = RequestMethod.GET, value = "deleteCompanyById")
@ResponseBody
public Map<String, Object> deleteCompanyById(Integer companyId){
int num = serCompanyService.deleteCompanyById(companyId);
return ResultUtil.getRsMap(num);
}
}
启动类
在com.study 中编写MainStarter类,用于spring boot启动,代码如下:
package com.study;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class MainStarter {
public static void main(String[] args) {
SpringApplication.run(MainStarter.class, args);
}
}
测试
右键运行MainStarter类。观察控制台输出如下,观察项目正常启动:
打开浏览器,输入如下地址进行接口测试,选择一个查询数据的接口:
http://localhost:8080/querySerCompanyList
结果如下
其他的接口地址都在controller类中可以找到,依次测试即可。
好了,spring boot整合 mybatis基本完成。
写在最后
开源是一种美德,尽早加入开源社区,共建美好生态!
|