tkMybatis数据持久层框架入门

gitee链接

Spring Boot版本:2.3.4.RELEASE

tkMybatis封装了底层SQL,使开发者在操作单表的情况下可以不考虑SQL的写法,通过Java函数接口操作数据库。

并且tkMybatis是基于Mybaits的,所以也能编写XML文件来执行复杂的SQL语句。

Maven依赖

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
xml复制代码<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:

1
2
3
4
5
6
7
8
9
10
11
12
13
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

1
2
3
4
5
6
7
8
9
markdown复制代码- src
- main
- java
- com
- cc
- model
- entity
TbProduct
TbUser

TbUser:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
java复制代码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:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
java复制代码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:

1
2
3
4
5
6
7
8
9
java复制代码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:

1
2
3
4
5
6
7
8
9
java复制代码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测试类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
java复制代码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:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
java复制代码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数据

1
2
3
4
5
6
7
8
9
10
11
12
java复制代码@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数据

1
2
3
4
5
6
7
8
9
10
11
12
java复制代码@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数据

1
2
3
4
5
6
7
8
9
java复制代码@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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
java复制代码@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数据

1
2
3
4
5
6
7
8
9
java复制代码@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

1
2
3
4
5
6
java复制代码## dao.xml的路径配置
mybatis:
mapper-locations:
- classpath:dao/*.xml # resource下的dao
configuration:
map-underscore-to-camel-case: true # 下划线自动转驼峰

然后在resources下创建dao文件夹,并且新建product.xml:

1
2
3
4
5
6
7
8
9
10
11
12
13
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下新增函数:

1
2
3
4
5
6
7
8
9
10
11
12
java复制代码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);
}

然后编写接口:

1
2
3
4
java复制代码@GetMapping("/selectProductByUserId")
public List<TbProduct> selectProductByUserId() {
return productDao.selectByUserId(1L);
}

删除user数据

1
2
3
4
5
6
7
java复制代码@GetMapping("/deleteUser")
public void deleteUser() {
int r = userDao.deleteByPrimaryKey(1L);
if (r <= 0) {
throw new RuntimeException("删除用户失败");
}
}

例子虽然不多,但是已经足够了解到,借助tkMybatis框架,我们操作单表的时候不用再写SQL语句,可以省略许多的代码,我们不用再为每一个实体类编写增删改查语句,仅仅只要新建一个映射实体类的Dao,不过几行通用代码而已。

还有当单表操作不满足于我们需求的时候,可以自行编写SQL语句并应用到XML下,真正做到按需开发,能省则省。

本文转载自: 掘金

开发者博客 – 和开发相关的 这里全都有

0%