使用SpringBoot+TKmybatis+mysql实现简单demo(后台管理增删改查)
目录
- 一、概念
- 二、TKmybatis的使用
- 1.Springboot项目中加入tk.mybatis依赖
- 2.创建实体类
- 3.base类
- 4.定义dao
- 5.定义Controller
- 5.1 新增 insertSelective
- 5.2 编辑updateByPrimaryKeySelective
- 5.3 查看详情 selectByPrimaryKey
- 5.4 查看单条记录 selectOne
- 5.5 查看所有 selectAll
- 5.6 根据条件(and) 查看列表 selectByExample
- 5.7 根据条件(or) 查看列表 selectByExample
- 5.8 分页查看用户列表 PageHelper、selectByExample
- 5.9 限制条数查询 selectByExampleAndRowBounds
- 5.10(条件1 and 条件2) or ( 条件3 and 条件4) 查看
- 5.11(条件1 or 条件2) and 条件3查看
- 6.启动类中配置
- 7.进行测试
- 8.完整代码
一、概念
1.TKmybatis 是什么?
TKmybatis 是基于 Mybatis 框架开发的一个工具,通过调用它提供的方法实现对单表的数据操作,不需要写任何 sql 语句,这极大地提高了项目开发效率。
2.TKmybatis 与 mybatis-plus
可参考https://www.codeleading.com/article/98311983977/
3.TKmybatis的底层原理
TKmybatis 的封装依赖一个 @SelectProvider 注解来完成,如果你使用过 @Select 注解,那么 @SelectProvider 与它没有质的区别,只是在定义注解的方式上有所不同, 一个是直接定义 sql, 一个是在外部定义好 sql 直接引用。
增删改查依赖注解:@InsertProvider 注解、@DeleteProvider 注解、@UpdateProvider 注解、@SelectProvider 注解
public interface Mapper {
@Select("select user_id,user_name from t_user ")
List<Map<String, String>> getUserInfo();
}
public interface SelectAllMapper<T> {
@SelectProvider(type = BaseSelectProvider.class,method ="dynamicSQL"
)
List<T> selectAll();
}
@SelectProvider 引用的各种 *Provider.class 实现类,就是依赖反射、注解等手段拼接 SQL 语句的过程。
/**
* 查看全部
*/
public String selectAll(MappedStatement ms) {
Class<?> entityClass = this.getEntityClass(ms);
this.setResultType(ms, entityClass);
StringBuilder sql = new StringBuilder();
sql.append(SqlHelper.selectAllColumns(entityClass));
sql.append(SqlHelper.fromTable(entityClass, this.tableName(entityClass)));
sql.append(SqlHelper.orderByDefault(entityClass));
return sql.toString();
}
TKmybatis 底层源码如下:



二、TKmybatis的使用
springBoot整合tkMybatis实现步骤:
1: 引入依赖
2: 实体类配置注解(@Id @Table)
3: Mapper继承tk的接口
4:启动类定义扫描Mapper接口的路径(@MapperScan)
5:配置文件定义扫描mapper.xml文件的路径(yml 或者 properties文件)
6:调用tk提供的接口和数据库交互
1.Springboot项目中加入tk.mybatis依赖
在pom.xml中引入tk.mybatis的引用:
<!--tk.mybatis依赖-->
<dependency>
<groupId>tk.mybatis</groupId>
<artifactId>mapper-spring-boot-starter</artifactId>
<version>1.2.4</version>
</dependency>
<!--web依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--mysql驱动-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
配置 application.yml:
# 服务端口
server:
port: 8083
# 数据源配置
spring:
datasource:
name: test
url: jdbc:mysql://localhost:3306/db_user?&allowMultiQueries=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&useSSl=false
username: root
password: root
driver-class-name: com.mysql.jdbc.Driver
type: com.alibaba.druid.pool.DruidDataSource
## 配置连接池信息
## 初始化大小,最小,最大
initialSize: 5
minIdle: 5
maxActive: 30
## 配置获取连接等待超时的时间
maxWait: 60000
# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
timeBetweenEvictionRunsMillis: 60000
# 配置一个连接在池中最小生存的时间,单位是毫秒
minEvictableIdleTimeMillis: 300000
validationQuery: SELECT 1 FROM DUAL
testWhileIdle: true
testOnBorrow: false
testOnReturn: false
poolPreparedStatements: true
maxPoolPreparedStatementPerConnectionSize: 20
# 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙
filters: stat,wall
# 通过connectProperties属性来打开mergeSql功能;慢SQL记录
connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
# 超过时间限制是否回收
removeAbandoned: true
# 超时时间;单位为秒。180秒=3分钟
removeAbandonedTimeout: 180
# 关闭abanded连接时输出错误日志
logAbandoned: true
##配置打印sql
mybatis:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
2.创建实体类
package com.example.tkmybatisdemo.entity;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import javax.persistence.*;
import java.util.Date;
/**
* 用户实体
*
* 其中@Table即数据表表名,@Column即列名,@Id作为主键,需要注意,@Id注解不可有多个,@Transient即冗余字段,不与数据库任何字段对应。
* 注意多数据源的情况:则@Table注解中可以写成“{数据库名}.{架构名}.{表名}”,如:@Table(name=“db.dbo.tableName”)
*
* GenerationType的参数说明:
* TABLE:使用一个特定的数据库表格来保存主键。(用的比较少)
* SEQUENCE:根据底层数据库的序列来生成主键,条件是数据库支持序列。(mysql不支持,其实和auto一样)
* IDENTITY:主键由数据库自动生成(主要是自动增长型,这个用的比较多)
* AUTO:主键由程序控制。(不是自增)
* @author qzz
*/
@Data
@Table(name="t_user")
public class User {
/**
* IDENTITY:主键由数据库自动生成(主要是自动增长型,这个用的比较多)
*/
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
@Column
private String name;
@Column
private Integer age;
@Column
private String remarks;
@Column
private String phone;
/**
* 性别 0 男 1 女
*/
@Column
private Integer sex;
/**
* 状态 0启用 1禁用
*/
@Column
private Integer status;
/**
* @JsonFormat:由后端传递给前端
* @DateTimeFormat:由前端传递给后端
*/
@Column
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date createTime;
@Column
private String createUser;
@Column
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date updateTime;
@Column
private String updateUser;
}
在实体类中常用注解和说明:
@Table:描述数据表信息,主要属性有name(表名)、schema、catalog、uniqueConstraints等;
@Id:指定表主键字段,无属性值。作为主键,需要注意,@Id注解不可有多个;
@Column:描述数据库字段信息,主要属性有name(字段名)、columnDefinition、inserttable、length、nullable(是否为空)、precision、scale、table、unique、updatable等;
@ColumnType:描述数据库字段类型,可对一些特殊类型作配置,进行特殊处理,主要属性jdbcType、column、typeHandler
@Transient即冗余字段,不与数据库任何字段对应。
3.base类
首先自定义一个公共的MyMapper继承一些tkmybatis的现有的mapper,注意这个类不能被spring扫描到,否则会出现java.lang.NoSuchMethodException: tk.mybatis.mapper.provider.base.BaseSelectProvider.异常.
package com.example.tkmybatisdemo.config.mybatis;
import tk.mybatis.mapper.common.*;
/**
* 自定义一个公共的MyMapper继承一些tkmybatis的现有的mapper
* 注意这个类不能被spring扫描到,否则会出现java.lang.NoSuchMethodException: tk.mybatis.mapper.provider.base.BaseSelectProvider.异常.
* @author qzz
*/
public interface MyMapper<T> extends MySqlMapper<T>, Mapper<T>, ConditionMapper<T>, IdsMapper<T> {
/**
* MySqlMapper:mysql独有的一些通用的方法
* Mapper:主要的方法来源,包含BaseMapper<T>, ExampleMapper<T>, RowBoundsMapper<T>, Marker
* ConditionMapper:按照自定义的条件查询
* IdsMapper:按照ids查询,比较鸡肋,要求id是自增的.
*/
}
4.定义dao
package com.example.tkmybatisdemo.mapper;
import com.example.tkmybatisdemo.config.mybatis.MyMapper;
import com.example.tkmybatisdemo.entity.User;
/**
* @author qzz
*/
public interface UserDao extends MyMapper<User> {
}
5.定义Controller
实现基本的增删改查
@RestController
@RequestMapping("/user")
public class UserController {
}
5.1 新增 insertSelective
核心代码:
@Autowired
private UserDao userDao;
/**
* 新增
* @param user
* @return
*/
@PostMapping("/add")
public Result add(@RequestBody User user){
user.setCreateUser("admin");
user.setCreateTime(new Date());
//insertSelective 保存一个实体,null的属性不会保存,会使用数据库默认值
int i= userDao.insertSelective(user);
if(i>0){
return new Result().ok("新增成功");
}else{
return new Result().error("新增失败");
}
}
5.2 编辑updateByPrimaryKeySelective
/**
* 编辑
* @param user
* @return
*/
@PostMapping("/update")
public Result update(@RequestBody User user){
user.setUpdateUser("admin");
user.setUpdateTime(new Date());
//根据主键id更新用户信息 updateByPrimaryKeySelective:根据主键更新属性不为null的值
int i= userDao.updateByPrimaryKeySelective(user);
if(i>0){
return new Result().ok("更新成功");
}else{
return new Result().error("更新失败");
}
}
5.3 查看详情 selectByPrimaryKey
/**
* 查看用户详情
* @return
*/
@GetMapping("/userInfo")
public Result getUserById(@RequestParam("userId") Integer id){
User userInfo = userDao.selectByPrimaryKey(id);
return new Result().ok(userInfo);
}
5.4 查看单条记录 selectOne
/**
* 查看单条记录
* @return
*/
@GetMapping("/single")
public Result getSingle(@RequestParam("userId") Integer id){
User user = new User();
user.setId(id);
User userInfo = userDao.selectOne(user);
return new Result().ok(userInfo);
}
5.5 查看所有 selectAll
/**
* 查看所有
* @return
*/
@GetMapping("/list")
public Result getList(){
List<User> list = userDao.selectAll();
return new Result().ok(list);
}
5.6 根据条件(and) 查看列表 selectByExample
/**
* 根据条件查看符合条件的列表
* @return
*/
@GetMapping("/getListByCondition")
public Result getListByCondition(@RequestParam("name") String name,@RequestParam("age") Integer age){
//根据名称获取用户信息
//通用的Example查询对象
Example example = new Example(User.class);
Example.Criteria criteria = example.createCriteria();
criteria.andLike("name","%"+name+"%");
criteria.andEqualTo("age",age);
List<User> list = userDao.selectByExample(example);
return new Result().ok(list);
}
5.7 根据条件(or) 查看列表 selectByExample
/**
* 根据条件查看符合条件的列表 条件或 or
* @return
*/
@GetMapping("/getListByOrCondition")
public Result getListByOrCondition(@RequestParam("name") String name,@RequestParam("age") Integer age){
//根据名称获取用户信息
//通用的Example查询对象
Example example = new Example(User.class);
Example.Criteria criteria = example.createCriteria();
criteria.andLike("name","%"+name+"%");
criteria.orEqualTo("age",age);
List<User> list = userDao.selectByExample(example);
return new Result().ok(list);
}
5.8 分页查看用户列表 PageHelper、selectByExample
/**
* 条件分页查看用户列表
*/
@GetMapping("/page1")
public PageInfo<UserInfo> page(@RequestParam("page") Integer page, @RequestParam("pageSize") Integer pageSize,@RequestParam("age") Integer age){
PageHelper.startPage(page,pageSize);
Example example = new Example(User.class);
Example.Criteria criteria = example.createCriteria();
criteria.andGreaterThan("age",age);
example.setOrderByClause("id desc");
//selectByExample几乎可以解决所有的查询
List<User> list = userDao.selectByExample(example);
//把结果集赋值给另一个结果集,分页的参数属性不起作用(如:total 等)
List<UserInfo> list1 =new ListUtils<UserInfo>().copyProperties(list,UserInfo.class);
return new PageInfo<>(list1);
}
5.9 限制条数查询 selectByExampleAndRowBounds
/**
* 限制条数查询
* @param limit
* @return
*/
public List<UserInfo> getUserListByLimit(@RequestParam("limit") Integer limit,@RequestParam("age") Integer age){
Example example = new Example(User.class);
//创建查询标准
Example.Criteria criteria = example.createCriteria();
//查询条件
criteria.andGreaterThan("age",age);
//排序条件
example.setOrderByClause("id desc");
//查询后可以根据selectByExampleAndRowBounds指定获取几条特定的查询语句,类似 select中的limit。
List<User> list = userDao.selectByExampleAndRowBounds(example,new PageRowBounds(0,limit));
//把结果集赋值给另一个结果集,分页的参数属性不起作用(如:total 等)
List<UserInfo> list1 =new ListUtils<UserInfo>().copyProperties(list,UserInfo.class);
return list1;
}
5.10(条件1 and 条件2) or ( 条件3 and 条件4) 查看
/**
* 根据(条件1 and 条件2) or ( 条件3 and 条件4)查看符合条件的列表
* @return
*/
@GetMapping("/getListByCondition2")
public Result getListByCondition2(@RequestParam("name") String name,@RequestParam("age") Integer age){
//根据名称获取用户信息
//通用的Example查询对象
Example example = new Example(User.class);
//条件1 and 条件2
Example.Criteria criteria1 = example.createCriteria();
criteria1.andLike("name","%"+name+"%");
criteria1.andEqualTo("age",age);
//条件3 and 条件4
Example.Criteria criteria2 = example.createCriteria();
criteria2.andLike("phone","%"+name+"%");
criteria2.andEqualTo("sex",0);
//把上面的两个组合条件 进行or
example.or(criteria2);
List<User> list = userDao.selectByExample(example);
return new Result().ok(list);
}
5.11(条件1 or 条件2) and 条件3查看
思路 :分拆 : (条件1 or 条件2)and 条件3 ==> ( 条件1 and 条件3) or ( 条件2 and 条件3 )
/**
* 根据(条件1 or 条件2) and 条件3 查看符合条件的列表
* 思路 : 分拆 : (条件1 or 条件2)and 条件3 ==> ( 条件1 and 条件3) or ( 条件2 and 条件3 )
* @return
*/
@GetMapping("/getListByCondition3")
public Result getListByCondition3(@RequestParam("name") String name){
//根据名称获取用户信息
//通用的Example查询对象
Example example = new Example(User.class);
//条件1 and 条件3
Example.Criteria criteria1 = example.createCriteria();
criteria1.andLike("name","%"+name+"%");
criteria1.andEqualTo("status",0);
//条件2 and 条件3
Example.Criteria criteria2 = example.createCriteria();
criteria2.andLike("phone","%"+name+"%");
criteria2.andEqualTo("status",0);
//把上面的两个组合条件 进行or
example.or(criteria2);
List<User> list = userDao.selectByExample(example);
return new Result().ok(list);
}
6.启动类中配置
在启动类中配置@MapperScan扫描
/**
* 注意使用org.mybatis.spring.annotation.MapperScan包下的此注解会连带扫描自定义的MyMapper,会出现
* java.lang.NoSuchMethodException: tk.mybatis.mapper.provider.base.BaseSelectProvider.异常
*
*/
@SpringBootApplication
@MapperScan("com.example.tkmybatisdemo.mapper")
public class TkMybatisDemoApplication {
public static void main(String[] args) {
SpringApplication.run(TkMybatisDemoApplication.class, args);
}
/*
* 以上的解决方案:
* 一、使用import tk.mybatis.spring.annotation.MapperScan包下的@MapperScan注解
* 二、或者不使用@MapperScan注解,改为在dao层的UserDao上添加@Mapper注解来单独标注mapper接口
* */
}
7.进行测试
7.1 测试 (条件1 and 条件2) or ( 条件3 and 条件4) 查看

控制台:

7.2 测试 (条件1 or条件2) and 条件3 查看

控制台:

8.完整代码
可点击此处下载
本文详细介绍了如何使用SpringBoot结合TKmybatis和mysql实现后台管理的简单demo,包括TKmybatis的概念、与mybatis-plus的区别、底层原理以及具体的操作步骤,如实体类配置、Mapper接口定义、DAO实现、Controller控制层的编写和测试。

756

被折叠的 条评论
为什么被折叠?



