Spring Boot版本:2.3.4.RELEASE
tkMybatis封装了底层SQL,使开发者在操作单表的情况下可以不考虑SQL的写法,通过Java函数接口操作数据库。
并且tkMybatis是基于Mybaits的,所以也能编写XML文件来执行复杂的SQL语句。
Maven依赖
<dependencies>
<!--springboot启动器-->
<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>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<!-- Spring-data-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>
<version>8.0.21</version>
</dependency>
<!--tkMybatis通用mapper-->
<dependency>
<groupId>tk.mybatis</groupId>
<artifactId>mapper-spring-boot-starter</artifactId>
<version>2.0.2</version>
</dependency>
</dependencies>
复制代码
配置文件
application.yml:
server:
port: 8888
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://myserverhost:3306/mytest?createDatabaseIfNotExist=true&characterEncoding=utf-8&useSSL=false&serverTimezone=UTC
username: root
password: admin
# 开启hibernate表自动更新
jpa:
hibernate:
ddl-auto: update
show-sql: true
复制代码
配置文件中开启了hibernate自动建表方便测试,建表前检查下数据库有没有同名表,有则删除。
新建两个实体类
TbUser和TbProduct
- src
- main
- java
- com
- cc
- model
- entity
TbProduct
TbUser
复制代码
TbUser:
package com.cc.model.entity;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
import java.io.Serializable;
@Entity
@Table(name = "tb_user")
public class TbUser implements Serializable {
@Id
@Column(name = "id", columnDefinition = "BIGINT(20) UNSIGNED NOT NULL auto_increment COMMENT '主键id'")
private Long id;
@Column(name = "username", columnDefinition = "VARCHAR(64) UNIQUE NOT NULL COMMENT '用户名,唯一'")
private String username;
@Column(name = "password", columnDefinition = "VARCHAR(64) NOT NULL COMMENT '密码'")
private String password;
private static final long serialVersionUID = 1L;
...
}
复制代码
TbProduct:
package com.cc.model.entity;
import java.math.BigDecimal;
import java.io.Serializable;
import javax.persistence.Entity;
import javax.persistence.Table;
import javax.persistence.Column;
import javax.persistence.Id;
@Entity
@Table(name = "tb_product")
public class TbProduct implements Serializable {
@Id
@Column(name = "id", columnDefinition = "BIGINT(20) UNSIGNED NOT NULL auto_increment COMMENT '主键id'")
private Long id;
@Column(name = "name", columnDefinition = "VARCHAR(64) UNIQUE NOT NULL COMMENT '用户名,唯一'")
private String name;
@Column(name = "price", columnDefinition = "DECIMAL(10,2) NOT NULL DEFAULT 0.00 COMMENT '价格'")
private BigDecimal price;
@Column(name = "user_id", columnDefinition = "BIGINT(20) UNSIGNED NOT NULL DEFAULT 0 COMMENT '用户id'")
private Long userId;
private static final long serialVersionUID = 1L;
...
}
复制代码
创建操作user表和product表的dao类:
UserDao:
package com.cc.dao;
import com.cc.model.entity.TbUser;
import org.springframework.stereotype.Repository;
import tk.mybatis.mapper.common.Mapper;
@Repository
public interface UserDao extends Mapper<TbUser> {
}
复制代码
ProductDao:
package com.cc.dao;
import com.cc.model.entity.TbProduct;
import org.springframework.stereotype.Repository;
import tk.mybatis.mapper.common.Mapper;
@Repository
public interface ProductDao extends Mapper<TbProduct> {
}
复制代码
tkmybatis配置类
为了使dao类能被扫描到,还需要mybatis测试类:
package com.cc.config;
import org.springframework.context.annotation.Configuration;
import tk.mybatis.spring.annotation.MapperScan;
/**
* MyBatis配置类
* @author cc
* @date 2021-07-09 14:38
*/
@Configuration
@MapperScan({"com.cc.dao"})
public class MyBatisConfig {
}
复制代码
创建一个controller来测试
TestController:
package com.cc.controller;
import com.cc.dao.ProductDao;
import com.cc.dao.UserDao;
import com.cc.model.entity.TbUser;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class TestController {
private final UserDao userDao;
private final ProductDao productDao;
public TestController(UserDao userDao, ProductDao productDao) {
this.userDao = userDao;
this.productDao = productDao;
}
}
复制代码
启动程序使其生效。
实战
实战的内容为:
- 插入一个user数据
- 更新一个user数据
- 查询所有user数据
- 查询指定名称的user
- 插入几条product数据
- 根据userId查询关联的所有product数据(连表查询)
- 删除user数据
为了简单,接口的参数都是写死的。
插入一个user数据
@GetMapping("/insertUser")
public void insertUser(@RequestBody TbUser user) {
user = new TbUser();
user.setId(1L);
user.setUsername("cc");
user.setPassword("1");
int r = userDao.insertSelective(user);
if (r <= 0) {
throw new RuntimeException("插入失败");
}
}
复制代码
更新一个user数据
@GetMapping("/updateUser")
public void updateUser(@RequestBody TbUser user) {
user = new TbUser();
user.setId(1L);
user.setUsername("cc");
user.setPassword("123456");
int r = userDao.updateByPrimaryKeySelective(user);
if (r <= 0) {
throw new RuntimeException("更新失败");
}
}
复制代码
查询所有user数据
@GetMapping("/selectAllUser")
public List<TbUser> selectAllUser(@RequestBody TbUser user) {
user = new TbUser();
user.setId(1L);
user.setUsername("cc");
user.setPassword("123456");
return userDao.selectAll();
}
复制代码
查询指定id/名称的user
@GetMapping("/selectUserById")
public TbUser selectUserById(@RequestBody TbUser user) {
return userDao.selectByPrimaryKey(1L);
}
@GetMapping("/selectUserByUsername")
public TbUser selectUserByUsername(@RequestBody TbUser user) {
user = new TbUser();
user.setUsername("cc");
Example example = new Example(TbUser.class);
Example.Criteria criteria = example.createCriteria();
criteria.andEqualTo("username", user.getUsername());
return userDao.selectOneByExample(example);
}
复制代码
插入几条product数据
@GetMapping("/insertSomeProduct")
public void insertSomeProduct() {
for (long i = 0; i < 5; i++) {
TbProduct product = new TbProduct();
product.setId(i);
product.setName("test" + i);
productDao.insertSelective(product);
}
}
复制代码
根据userId查询关联的所有product数据(连表查询)
因为dao只能操作单表,所以我们需要编写xml来实现连表操作。
首先要在配置文件文件中添加包扫描:
application.yml
## dao.xml的路径配置
mybatis:
mapper-locations:
- classpath:dao/*.xml # resource下的dao
configuration:
map-underscore-to-camel-case: true # 下划线自动转驼峰
复制代码
然后在resources下创建dao文件夹,并且新建product.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.cc.dao.ProductDao">
<select id="selectByUserId" resultType="com.cc.model.entity.TbProduct">
SELECT
*
FROM
tb_product AS p
LEFT JOIN tb_user u ON u.id = p.user_id
WHERE
u.id = #{userId}
</select>
</mapper>
复制代码
在ProductDao下新增函数:
package com.cc.dao;
import com.cc.model.entity.TbProduct;
import org.springframework.stereotype.Repository;
import tk.mybatis.mapper.common.Mapper;
import java.util.List;
@Repository
public interface ProductDao extends Mapper<TbProduct> {
List<TbProduct> selectByUserId(Long userId);
}
复制代码
然后编写接口:
@GetMapping("/selectProductByUserId")
public List<TbProduct> selectProductByUserId() {
return productDao.selectByUserId(1L);
}
复制代码
删除user数据
@GetMapping("/deleteUser")
public void deleteUser() {
int r = userDao.deleteByPrimaryKey(1L);
if (r <= 0) {
throw new RuntimeException("删除用户失败");
}
}
复制代码
例子虽然不多,但是已经足够了解到,借助tkMybatis框架,我们操作单表的时候不用再写SQL语句,可以省略许多的代码,我们不用再为每一个实体类编写增删改查语句,仅仅只要新建一个映射实体类的Dao,不过几行通用代码而已。
还有当单表操作不满足于我们需求的时候,可以自行编写SQL语句并应用到XML下,真正做到按需开发,能省则省。