做厂房出租有那些推广网站/百度快照怎么删除
前面了解了springboot + mybatis的单数据源和多数据源的集成已经使用,本篇文章来聊聊mybatis的高端用法吧
1.环境搭配
1.1 pom依赖
- 基于springboot 2.5.6,也可以参看mybatis的第一篇文章
<!--Mysql依赖包-->
<dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><scope>runtime</scope>
</dependency>
<!--mybatis-->
<dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>2.2.0</version>
</dependency>
1.2 yml配置
spring:datasource:driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://192.168.0.100:3306/demo_test?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=falseusername: rootpassword: 123456#mybatis资源文件扫描和其他相关配置
mybatis:mapperLocations: classpath:mapper/*/*.xmlexecutorType: SIMPLEconfiguration:# 驼峰式 测试用先关闭
# map-underscore-to-camel-case: truelog-impl: org.apache.ibatis.logging.stdout.StdOutImpl
1.3 数据库表
user_info 用户的信息表
user_card 用户身份证表 一个用户一个身份证 一对一
user_mobile 用户手机号表 一个用户有多个手机号
-- 导出 表 demo_test.user_card 结构
CREATE TABLE IF NOT EXISTS `user_card` (`user_id` bigint(20) NOT NULL COMMENT '用户ID',`card` varchar(50) DEFAULT NULL COMMENT '身份证',`create_time` datetime DEFAULT CURRENT_TIMESTAMP,`update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,PRIMARY KEY (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='身份证表';-- 正在导出表 demo_test.user_card 的数据:~3 rows (大约)
DELETE FROM `user_card`;
/*!40000 ALTER TABLE `user_card` DISABLE KEYS */;
INSERT INTO `user_card` (`user_id`, `card`, `create_time`, `update_time`) VALUES(1, '111111', '2022-02-17 16:45:28', '2022-02-17 16:45:28');
/*!40000 ALTER TABLE `user_card` ENABLE KEYS */;-- 导出 表 demo_test.user_info 结构
CREATE TABLE IF NOT EXISTS `user_info` (`id` bigint(20) NOT NULL AUTO_INCREMENT,`name` varchar(50) DEFAULT NULL COMMENT '名称',`age` int(11) DEFAULT NULL COMMENT '年龄',`create_time` datetime DEFAULT CURRENT_TIMESTAMP,`update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;-- 正在导出表 demo_test.user_info 的数据:~3 rows (大约)
DELETE FROM `user_info`;
/*!40000 ALTER TABLE `user_info` DISABLE KEYS */;
INSERT INTO `user_info` (`id`, `name`, `age`, `create_time`, `update_time`) VALUES(1, '张三', 22, '2022-02-17 16:45:01', '2022-02-17 16:47:21');
/*!40000 ALTER TABLE `user_info` ENABLE KEYS */;-- 导出 表 demo_test.user_mobile 结构
CREATE TABLE IF NOT EXISTS `user_mobile` (`id` bigint(20) NOT NULL AUTO_INCREMENT,`userId` bigint(20) DEFAULT NULL COMMENT '用户id',`mobile` varchar(50) NOT NULL COMMENT '手机号',`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,PRIMARY KEY (`id`),UNIQUE KEY `userId` (`userId`,`mobile`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8 COMMENT='用户手机表';-- 正在导出表 demo_test.user_mobile 的数据:~2 rows (大约)
DELETE FROM `user_mobile`;
/*!40000 ALTER TABLE `user_mobile` DISABLE KEYS */;
INSERT INTO `user_mobile` (`id`, `userId`, `mobile`, `create_time`, `update_time`) VALUES(1, 1, '13011112222', '2022-02-17 16:45:51', '2022-02-17 16:45:51'),(2, 1, '13011112223', '2022-02-17 16:45:51', '2022-02-17 16:47:02'),(3, 1, '13011112224', '2022-02-17 16:45:51', '2022-02-17 16:47:02');
1.4 测试代码
@ResourceTestMapper testMapper;@GetMapping("/data/selectBean")public Object selectBean(@RequestParam(required = false) Long id) {UserInfo userInfo = new UserInfo();userInfo.setId(id);List<UserInfo> userInfos = testMapper.selectBean(userInfo);return userInfos;}
1.5 java bean
分别对user_info、user_card、user_mobile生成实体bean,并添加getter、setter方法
只贴下user_info的bean,后面一对一,一对多查询用
@Data
public class UserInfo {Long id;String name;Integer age;//个人的身份证,一对一关系UserCard userCard;//个人的手机号 一对多关系Set<UserMobile> userMobiles;String createTime;String updateTime;
}
2. resultMap 映射
2.1 直接映射
- xml文件,注意传参的
parameterType
和出参的resultType
<select id="selectBean" parameterType="com.example.demo.entity.UserInfo"
resultType="com.example.demo.entity.UserInfo">select * from user_info where id = #{id}
</select>
- 测试结果输出
[{"id": 1,"name": "张三","age": 22,"userCard": null,"userMobileList": null,"createTime": null,"updateTime": null
}]
结果可以看到,原本表中的createTime和updateTime有值的,但也输出是空。
解决方法:
- 打开yml里面的驼峰式配置
map-underscore-to-camel-case: true
- 使用自定义的映射resultMap
接下来方便测试,从这里打开驼峰式的配置
2.2 自定义映射map
- xml代码做如下修改
//例如这个xml下有很多个查询都需要用到userInfo,就可以抽离出来使用
//id 别名的意思 需保持唯一 type:映射到javabean中的实体类
<resultMap id="userInfoMap" type="com.example.demo.entity.UserInfo">//id 主键 column/数据库中的列名 property/对应实体类中的列名<id property="id" column="id"/><result property="name" column="name"/><result property="age" column="age"/><result property="createTime" column="create_time"/><result property="updateTime" column="update_time"/>
</resultMap>//这里的出参就要使用resultMap了 指向上面的id
<select id="selectBean" parameterType="com.example.demo.entity.UserInfo"resultMap="userInfoMap">select * from user_info where id = #{id}
</select>
- 测试结果输出
[{"id": 1,"name": "张三","age": 22,"userCard": null,"userMobileList": null,"createTime": "2022-02-17 16:45:01","updateTime": "2022-02-17 16:47:21"
}]
user_Info表中的数据都能看到了,接下来看看userCard一对一的扩展该怎么实现
3. 一对一数据查询
3.1 关联实现
<resultMap id="userInfoMap" type="com.example.demo.entity.UserInfo"><id property="id" column="id"/><result property="name" column="name"/><result property="age" column="age"/><result property="createTime" column="create_time"/><result property="updateTime" column="update_time"/><association property="userCard" javaType="com.example.demo.entity.UserCard"><id property="userId" column="user_id"/><result property="card" column="card"/><result property="createTime" column="create_time"/><result property="updateTime" column="update_time"/></association>
</resultMap><select id="selectBean" parameterType="com.example.demo.entity.UserInfo"resultMap="userInfoMap">select * from user_info uleft join user_card uc on u.id=uc.user_idwhere u.id = #{id}
</select>
- 测试结果输出
[{"id": 1,"name": "张三","age": 22,"userCard": {"userId": 1,"card": "111111","createTime": "2022-02-17 16:45:01","updateTime": "2022-02-17 16:47:21"},"userMobileList": null,"createTime": "2022-02-17 16:45:01","updateTime": "2022-02-17 16:47:21"
}]
有个很明显的问题,如果两张表存在相同的字段,mysql查询会自动去掉后者。这种情况需要建立很多的别名来使用
如果这种满足不了需求,还可以用下面这种方法实现
3.2 主键查询实现
通过执行另外一个SQL映射语句来返回预期的复杂类型
- xml代码修改
<resultMap id="userInfoMap" type="com.example.demo.entity.UserInfo"><id property="id" column="id"/><result property="name" column="name"/><result property="age" column="age"/><result property="createTime" column="create_time"/><result property="updateTime" column="update_time"/>//关联查询 property对应实体类中的userCard列 //使用当前id列的值在进行查询 对应的sql查询id selectUserCard<association property="userCard" column="id" select="selectUserCard">//下面的映射大同小异<id property="userId" column="user_id"/><result property="card" column="card"/><result property="createTime" column="create_time"/><result property="updateTime" column="update_time"/></association></resultMap><select id="selectBean" parameterType="com.example.demo.entity.UserInfo"resultMap="userInfoMap">select * from user_info where id = #{id}</select>//单独的查询,其他业务可以用<select id="selectUserCard" parameterType="Long" resultType="com.example.demo.entity.UserCard">select * from user_card where user_id=#{id}</select>
- 测试结果输出
[{"id": 1,"name": "张三","age": 22,"userCard": {"userId": 1,"card": "111111","createTime": "2022-02-17 16:45:28","updateTime": "2022-02-17 16:45:28"},"userMobileList": null,"createTime": "2022-02-17 16:45:01","updateTime": "2022-02-17 16:47:21"
}]
结果可以看出,一对一的需求实现了,接下来分析一对多的
3. 一对多数据查询
- xml代码修改
<resultMap id="userInfoMap" type="com.example.demo.entity.UserInfo"><id property="id" column="id"/><result property="name" column="name"/><result property="age" column="age"/><result property="createTime" column="create_time"/><result property="updateTime" column="update_time"/>//以id列的值再进行一次查询 sql id为selectUserMobile<collection property="userMobiles" column="id" select="selectUserMobile"><id property="userId" column="user_id"/><result property="mobile" column="mobile"/><result property="createTime" column="create_time"/><result property="updateTime" column="update_time"/></collection></resultMap><!--left join user_card uc on u.id=uc.user_id--><select id="selectBean" parameterType="com.example.demo.entity.UserInfo"resultMap="userInfoMap">select * from user_info u where u.id = #{id}</select><select id="selectUserMobile" parameterType="Long" resultType="com.example.demo.entity.UserMobile">select * from user_mobile where user_id=#{id}</select>
- 测试结果输出
[{"id": 1,"name": "张三","age": 22,"userCard": null,"userMobiles": [{"userId": 1,"mobile": "13011112223","createTime": "2022-02-17 16:45:51","updateTime": "2022-02-17 16:47:02"}, {"userId": 1,"mobile": "13011112224","createTime": "2022-02-17 16:45:51","updateTime": "2022-02-17 16:47:02"}, {"userId": 1,"mobile": "13011112222","createTime": "2022-02-17 16:45:51","updateTime": "2022-02-17 16:45:51"}],"createTime": "2022-02-17 16:45:01","updateTime": "2022-02-17 16:47:21"
}]
以上均为作者在项目中所用过的,还想了解其他的用法的自行了解哦
以上就是本章的全部内容了。
上一篇:mybatis第二话 - mybatis,多数据源的快乐你懂吗?
下一篇:mybatis第四话 - 让我们一层一层来剥开mybatis的心,源码分析
及时当勉励,岁月不待人