ToB企服应用市场:ToB评测及商务社交产业平台

标题: Spring Boot 中使用 tkMapper [打印本页]

作者: 用户国营    时间: 2022-11-10 00:44
标题: Spring Boot 中使用 tkMapper
说明:基于 MyBatis 有很多第三方功能插件,这些插件可以完成数据操作方法的封装、数据库逆向工程的生成等。
tkMapper 和 MyBatis-plus 都是基于 MyBatis 提供的第三方插件,功能类似,下面介绍 tkMapper 的使用。
简介

tkMapper 就是一个 MyBatis 插件,基于 MyBatis 提供很多工具,提高开发效率,主要有以下两个功能。
MyBatis 基础环境

tkMapper 的使用需要基于 MyBatis。
tkMapper 环境搭建

tkMapper 对数据的通用操作

tkMapper 提供针对单表通用的数据库操作方法。
数据准备

1. 创建数据库表
  1. DROP TABLE IF EXISTS `users`;
  2. CREATE TABLE `users`  (
  3.   `user_id` int(11) NOT NULL AUTO_INCREMENT,
  4.   `user_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
  5.   `user_pwd` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
  6.   `user_realname` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
  7.   `user_img` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
  8.   PRIMARY KEY (`user_id`) USING BTREE
  9. ) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Compact;
复制代码
2. 创建实体类
  1. @Data
  2. @NoArgsConstructor
  3. @AllArgsConstructor
  4. @Table(name = "users") //数据库表名和实体类类名不一致需要指定映射关系!
  5. public class User {
  6.     @Id //指定主键
  7.     private Integer userId;
  8.     private String userName;
  9.     private String userPwd;
  10.     private String userRealname;
  11.     private String userImg;
  12. }
复制代码
3. 创建 Dao 接口【重点】

注意:创建的 Dao 接口需要继承 tkMapper 中提供的 Mapper 和 MySqlMapper 两个接口,这两个接口提供了对单表的通用操作。
  1. public interface UserDao extends Mapper<User>, MySqlMapper<User> {
  2. }
复制代码
可选优化策略【建议使用】:
如果不想每次创建 dao 接口时都继承 tkMapper  中的两个接口,可以自己写一个通用的接口模板,只需要让这个通用的接口模板继承 tkMapper  中的两个接口,然后自己创建的 dao 接口只需要继承这个通用的接口模板即可!
但是,需要注意的是,这个通用的接口模板千万不能写在 dao 目录下!因为 dao 目录下的接口会被扫描到,有固定的功能用处;而我们自定义的通用接口模板只是为了继承,没有其他特殊功能!
使用示例:
1、可在 dao 目录同级创建 general 目录,在 general 目录下创建 GeneralDao 接口,并继承 tkMapper  中的两个接口。
  1. package com.luis.general;
  2. import tk.mybatis.mapper.common.Mapper;
  3. import tk.mybatis.mapper.common.MySqlMapper;
  4. /**
  5. * @Author: Luis
  6. * @date: 2022/11/9 14:39
  7. * @description: 自定义的通用接口模板
  8. */
  9. public interface GeneralDao<T> extends Mapper<T>, MySqlMapper<T> {
  10. }
复制代码
2、创建 dao 接口,继承 GeneralDao 即可!
  1. public interface UserDao extends GeneralDao<User> {
  2. }
复制代码
4. 测试

添加 Junit 和 springboot test 两个测试依赖:
  1. <dependency>
  2.     <groupId>junit</groupId>
  3.     <artifactId>junit</artifactId>
  4.     <scope>test</scope>
  5. </dependency>
  6. <dependency>
  7.     <groupId>org.springframework.boot</groupId>
  8.     <artifactId>spring-boot-starter-test</artifactId>
  9. </dependency>
复制代码
写测试类进行测试:
  1. @RunWith(SpringRunner.class)
  2. @SpringBootTest(classes = SpringbootTkMapperDemoApplication.class) //启动类.class
  3. public class UserDaoTest {
  4.     @Autowired
  5.     private UserDao userDao; //如果爆红线不用管(或Dao接口上添加@Repository注解)
  6.     @Test
  7.     public void test() {
  8.         User user = new User();
  9.         user.setUserName("mike");
  10.         user.setUserPwd("123");
  11.         user.setUserRealname("zhangsan");
  12.         user.setUserImg("user/default.jpg");
  13.         int i = userDao.insert(user);
  14.         System.out.println("========> i = " + i);
  15.     }
  16. }
复制代码
tkMapper 常用方法之增删改

  1. @RunWith(SpringRunner.class)
  2. @SpringBootTest(classes = SpringbootTkMapperDemoApplication.class) //启动类.class
  3. public class UserDaoTest {
  4.     @Autowired
  5.     private UserDao userDao; //如果爆红线不用管(或Dao接口上添加@Repository注解)
  6.     @Test
  7.     public void testInsert() {
  8.         User user = new User();
  9.         user.setUserName("juno4");
  10.         user.setUserPwd("321");
  11.         user.setUserRealname("lin");
  12.         user.setUserImg("user/default.jpg");
  13.         /**
  14.          * insert: 添加(自增的id不会返回)
  15.          */
  16.         int i = userDao.insert(user);
  17.         System.out.println("========> i = " + i);
  18.         System.out.println(user.getUserId()); //null
  19.     }
  20.     @Test
  21.     public void testInsertUseGeneratedKeys() {
  22.         User user = new User();
  23.         user.setUserName("juno3");
  24.         user.setUserPwd("321");
  25.         user.setUserRealname("lin");
  26.         user.setUserImg("user/default.jpg");
  27.         /**
  28.          * insertUseGeneratedKeys: 添加(自增的id可以返回)
  29.          * 注意:
  30.          *  1. 数据库中主键字段需要设置为自增
  31.          *  2. 实体类中主键属性需要使用@Id注解指定;并且需要使用包装类型Integer,不要使用int
  32.          */
  33.         int i = userDao.insertUseGeneratedKeys(user);
  34.         System.out.println("========> i = " + i);
  35.         System.out.println(user.getUserId()); //10
  36.     }
  37.     @Test
  38.     public void testUpdateByPrimaryKey() {
  39.         User user = new User();
  40.         user.setUserId(10); //必须指定要修改的id
  41.         user.setUserName("juno new");
  42.         user.setUserPwd("000");
  43.         user.setUserRealname("lin new");
  44.         user.setUserImg("new.jpg");
  45.         /**
  46.          * updateByPrimaryKey:根据主键修改
  47.          */
  48.         int i = userDao.updateByPrimaryKey(user);
  49.         System.out.println("========> i = " + i);
  50.         System.out.println(user);
  51.     }
  52.     @Test
  53.     public void testDeleteByPrimaryKey() {
  54.         /**
  55.          * deleteByPrimaryKey:根据主键删除
  56.          */
  57.         int i = userDao.deleteByPrimaryKey(9);
  58.         System.out.println("========> i = " + i);
  59.     }
  60. }
复制代码
PS:其实还有根据自定义条件修改或删除的方法(使用方法参考带条件的查询示例)
tkMapper 常用方法之查询

  1. @RunWith(SpringRunner.class)
  2. @SpringBootTest(classes = SpringbootTkMapperDemoApplication.class) //启动类.class
  3. public class UserDaoTest {
  4.     @Autowired
  5.     private UserDao userDao; //如果爆红线不用管(或Dao接口上添加@Repository注解)
  6.     @Test
  7.     public void testSelectAll() {
  8.         /**
  9.          * selectAll:查询所有
  10.          */
  11.         List<User> users = userDao.selectAll();
  12.         for (User user : users) {
  13.             System.out.println(user);
  14.         }
  15.     }
  16.     @Test
  17.     public void testSelectByPrimaryKey() {
  18.         /**
  19.          * selectByPrimaryKey:根据主键查询
  20.          */
  21.         User user = userDao.selectByPrimaryKey(10);
  22.         System.out.println(user);
  23.     }
  24.     @Test
  25.     public void testSelectByExample() {
  26.         //封装查询条件
  27.         Example example = new Example(User.class);
  28.         Example.Criteria criteria = example.createCriteria();
  29.         //条件信息(根据Criteria对象的各种方法进行设置)
  30.         criteria.andEqualTo("userRealname", "lin");
  31.         // criteria.orEqualTo("userPwd", "123");
  32.         // criteria.andLike("userName", "%i%");
  33.         /**
  34.          * selectByPrimaryKey:根据条件查询(PS:根据条件修改或删除与此类似)
  35.          *      注意:需要设置查询条件信息,并传入条件对象
  36.          */
  37.         List<User> users = userDao.selectByExample(example);
  38.         for (User user : users) {
  39.             System.out.println("========> " + user);
  40.         }
  41.     }
  42.     @Test
  43.     public void testSelectByRowBounds() {
  44.         //分页查询信息
  45.         int pageNum = 2; //第几页
  46.         int pageSize = 3; //每页显示多少行
  47.         int start = (pageNum - 1) * pageSize; //起始显示的下标
  48.         RowBounds rowBounds = new RowBounds(start, pageSize);
  49.         /**
  50.          * selectByRowBounds:查所有的分页查询
  51.          */
  52.         List<User> users = userDao.selectByRowBounds(new User(), rowBounds);
  53.         for (User user : users) {
  54.             System.out.println("========> " + user);
  55.         }
  56.         /**
  57.          * selectCount:查询总记录数
  58.          */
  59.         int count = userDao.selectCount(new User());
  60.         System.out.println("========> count = " + count);
  61.     }
  62.     @Test
  63.     public void testSelectByExampleAndRowBounds() {
  64.         //封装查询条件
  65.         Example example = new Example(User.class);
  66.         Example.Criteria criteria = example.createCriteria();
  67.         criteria.andEqualTo("userRealname", "lin");
  68.         //分页查询信息
  69.         int pageNum = 2; //第几页
  70.         int pageSize = 2; //每页显示多少行
  71.         int start = (pageNum - 1) * pageSize; //起始显示的下标
  72.         RowBounds rowBounds = new RowBounds(start, pageSize);
  73.         /**
  74.          * selectByExampleAndRowBounds:带条件的分页查询
  75.          */
  76.         List<User> users = userDao.selectByExampleAndRowBounds(example, rowBounds);
  77.         for (User user : users) {
  78.             System.out.println("========> " + user);
  79.         }
  80.         /**
  81.          * selectCountByExample:根据条件查询总记录数
  82.          */
  83.         int count = userDao.selectCountByExample(example);
  84.         System.out.println("========> count = " + count);
  85.     }
  86. }
复制代码
tkMapper 关联/多表查询

说明:所有的关联/多表查询都可以由多个单表查询组成
关联/多表查询实现方式:
方式一:多次使用单表查询,然后封装数据
方式二:自定义查询方法和 SQL
情景:基于以上的用户表,新添加一个订单表 orders,订单表中有订单信息,但是也有用户 id;
要求:在查询用户表的同时还要查询出用户的订单信息,这就涉及到了两张表的查询。
具体业务要求:根据用户名查询用户的所有信息,包括订单信息。
数据准备

新建订单表 orders:
  1. DROP TABLE IF EXISTS `orders`;
  2. CREATE TABLE `orders`  (
  3.   `order_id` int(11) NOT NULL AUTO_INCREMENT,
  4.   `user_id` int(11) NOT NULL,
  5.   `receiver_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
  6.   `receiver_mobile` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
  7.   `receiver_address` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
  8.   PRIMARY KEY (`order_id`) USING BTREE
  9. ) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Compact;
  10. INSERT INTO `orders` VALUES (1, 1, 'luis', '13344445555', '湖北武汉');
复制代码
新建实体类 Order:
  1. @Data
  2. @NoArgsConstructor
  3. @AllArgsConstructor
  4. @Table(name = "orders")
  5. public class Order {
  6.     @Id
  7.     private Integer orderId;
  8.     private Integer userId;
  9.     private String receiverName;
  10.     private String receiverMobile;
  11.     private String receiverAddress;
  12. }
复制代码
新建 dao 接口:
注意,此处 dao 接口继承的是自定义的通用接口模板,相关说明参见之前创建示例 UserDao 的步骤。
也可以直接继承 tkMapper 的两个接口。(注意灵活运用!)
  1. public interface OrderDao extends GeneralDao<Order> {
  2. }
复制代码
说明:进行关联/多表查询前,需要修改下之前的 User 实体类,在实体类中需要添加一个订单的字段,以便查询出用户所关联的订单信息。
  1. @Data
  2. @NoArgsConstructor
  3. @AllArgsConstructor
  4. @Table(name = "users") //数据库表名和实体类类名不一致需要指定映射关系!
  5. public class User {
  6.     @Id //指定主键
  7.     private Integer userId;
  8.     private String userName;
  9.     private String userPwd;
  10.     private String userRealname;
  11.     private String userImg;
  12.    
  13.     //订单
  14.     private List<Order> orderList;
  15. }
复制代码
方式一:多次单表查询
  1. @RunWith(SpringRunner.class)
  2. @SpringBootTest(classes = SpringbootTkMapperDemoApplication.class) //启动类.class
  3. public class UserDaoTest {
  4.     @Autowired
  5.     private UserDao userDao; //如果爆红线不用管(或Dao接口上添加@Repository注解)
  6.     @Autowired
  7.     private OrderDao orderDao;
  8.     @Test
  9.     public void test() {
  10.         //根据用户名查询用户信息
  11.         Example example = new Example(User.class);
  12.         Example.Criteria criteria = example.createCriteria();
  13.         criteria.andEqualTo("userName", "luis");
  14.         //条件查询
  15.         List<User> users = userDao.selectByExample(example);
  16.         User user = users.get(0);
  17.         //根据用户id查询订单信息
  18.         Example example1 = new Example(Order.class);
  19.         Example.Criteria criteria1 = example.createCriteria();
  20.         criteria.andEqualTo("userId", user.getUserId());
  21.         //条件查询
  22.         List<Order> orders = orderDao.selectByExample(example1);
  23.         //将查询到的订单信息设置到user中
  24.         user.setOrderList(orders);
  25.         System.out.println("========> " + user);
  26.     }
  27. }   
复制代码
方式二:自定义连接查询

逆向工程

所谓逆向工程,就是通过数据库表,来自动生成实体类、dao 接口和 mapper 文件。
需要注意的是,本逆向工程是最好配合 tkMapper 环境使用,因为,有一些配置和 tkMapper 相关,如生成的 dao 接口会继承自定义的通用接口模板,而该通用的接口模板就是继承了 tkMapper 中的两个接口,从而才能使用 tkMapper 提供的通用数据操作方法;还有,生成的实体类上的注解需要依赖 tkMapper 环境。
重要说明:本逆向工程使用的 mysql 版本是低版本 5.1.36!经测试,如果使用高版本如 8.xxx,很大概率会生成有问题!所以建议项目中统一使用低版本的 MySQL。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!




欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) Powered by Discuz! X3.4