mybatis中的一些特殊操作
目录1.mybatis中的一些特殊操作1.1批量删除1.2动态获取表名1.3添加功能获取自增主键1.4自定义映射resultMap1.mybatis中的一些特殊操作1.1批量删除/*** 批量删除用户信息*/Integer deleteUserByIds(String ids);<!-- 批量删除用户信息 --><delete id="deleteUserByIds">de
1.mybatis中的一些特殊操作
1.1批量删除
/**
* 批量删除用户信息
*/
Integer deleteUserByIds(String ids);
<!-- 批量删除用户信息 -->
<delete id="deleteUserByIds">
delete from user where id in (${ids})
</delete>
/**
* 批量删除测试
*/
@Test
public void deleteUserByIdsTest() {
String ids = "18,19,20";
Integer num = userMapper.deleteUserByIds(ids);
if (num > 0) {
System.out.println("删除成功!!");
} else {
System.out.println("删除失败!!");
}
}
1.2动态获取表名
/**
* 动态获取表名
*/
List<Map<String, Object>> getList(String tableName);
<!-- 动态获取表名-->
<select id="getList" resultType="map">
select * from ${tablename}
</select>
/**
* 动态获取表名测试
*/
@Test
public void getListTest() {
List<Map<String, Object>> list = userMapper.getList("user_demo");
list.forEach(System.out::println);
}
动态获取表名的时候需要用${}的方式获取,因为我们在传入数据的时候就是自带引号的,如果我们使用
占位符的方式传入数据的话,那么就会导致最后拼出来的sql语句长这样: select * from
‘‘user’’ 也就是两个单引号的形式,那就找不到对应的表了,所以使用${}。
1.3添加功能获取自增主键
为什么需要获取自增主键?因为我们如果删除了某个数据,但是我们的序号依旧会按照删除之前的顺序
继续增加,就会导致序号不连续,没有可读性。应用场景如下:
- 添加班级信息
- 获取新添加的班级的id
- 为班级分配学生,即将某学的班级id修改为新添加的班级的id
可以看到我们的返回值是没有获取到新增user的id的,这就导致了用户是看不到这个序号的,我们通过
Mapper.xml中的两个属性来获取到我们的自增主键:
useGeneratedKeys:表示当前添加功能实现自增的主键
keyProperty:将添加的数据的自增的主键为实体类类型的参数的属性赋值(User对象中的id属
性)
代码如下:
/**
* 添加用户信息并获取自增主键
* @param user 用户实体类
*/
void insertUserKey(User user);
<!--
添加用户信息获取自增主键
useGeneratedKeys:表示当前添加功能实现自增的主键
keyProperty:将添加的数据的自增的主键为实体类类型的参数的属性赋值(User对象中的id属性)
-->
<insert id="insertUserKey" useGeneratedKeys="true" keyProperty="id">
insert into user values (null, #{username}, #{password}, #{age}, #{sex}, #
{email})
</insert>
/**
* 添加用户信息获取自增主键测试
*/
@Test
public void insertUserTest() {
User user = new User(null, "Steve", "123456", 23, "男", "Steve@qq.com");
userMapper.insertUserKey(user);
System.out.println(user);
}
添加属性之后我们就可以获取到自增的主键了:
1.4自定义映射resultMap
用于解决表中的列名和实体类中属性名不一致的情况,比如我现在的列名为: emp_xxx ,这样带有下划
线的形式,但是我们的实体类中一班用驼峰命名的方式来命名我们的属性,那就回导致属性名和列名不
一致,那我们可以通过 resultMap 这个属性来自定义映射,让属性和列对应上。
我们新建一个数据表: emp_user :
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for emp_user
-- ----------------------------
DROP TABLE IF EXISTS `emp_user`;
CREATE TABLE `emp_user` (
`emp_id` int NOT NULL,
`emp_name` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL
DEFAULT NULL,
`emp_age` int NULL DEFAULT NULL,
`emp_sex` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL
DEFAULT NULL,
`emp_email` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL
DEFAULT NULL,
PRIMARY KEY (`emp_id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci
ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of emp_user
-- ----------------------------
SET FOREIGN_KEY_CHECKS = 1;
然后随机加一些数据进去:
接着创建我们的实体类,生成对应的构造方法等:
public class Emp {
private Integer empId;
private String empName;
private Integer empAge;
private String empSex;
private String empEmail;
public Emp(Integer empId, String empName, Integer empAge, String empSex,
String empEmail) {
this.empId = empId;
this.empName = empName;
this.empAge = empAge;
this.empSex = empSex;
this.empEmail = empEmail;
}
public Emp() {
}
定义好我们的Mapper接口和映射文件,写一个简单的查询:
public Integer getEmpId() {
return empId;
}
public void setEmpId(Integer empId) {
this.empId = empId;
}
public String getEmpName() {
return empName;
}
public void setEmpName(String empName) {
this.empName = empName;
}
public Integer getEmpAge() {
return empAge;
}
public void setEmpAge(Integer empAge) {
this.empAge = empAge;
}
public String getEmpSex() {
return empSex;
}
public void setEmpSex(String empSex) {
this.empSex = empSex;
}
public String getEmpEmail() {
return empEmail;
}
public void setEmpEmail(String empEmail) {
this.empEmail = empEmail;
}
@Override
public String toString() {
return "Emp{" +
"empId=" + empId +
", empName='" + empName + '\'' +
", empAge=" + empAge +
", empSex='" + empSex + '\'' +
", empEmail='" + empEmail + '\'' +
'}';
}
}
定义好我们的Mapper接口和映射文件,写一个简单的查询:
public interface EmpMapper {
/**
* 通过id查询用户
* @param empId 员工id
* @return 返回用户对象
*/
Emp getEmpById(Integer empId);
}
<mapper namespace="com.qcby.mybatis.mappers.EmpMapper">
<!-- 通过员工id查询员工信息 -->
<select id="getEmpById" resultType="emp">
select * from emp_user where emp_id = #{empId}
</select>
</mapper>
写测试类进行测试:
@Test
public void getEmpByIdTest(){
Emp emp = empMapper.getEmpById(4);
System.out.println(emp);
}
可以发现,我们其实查询到了一条对应的数据,但是其中的属性值并没有输出,这就是应为我们数据表
的列名和我们 Emp 实体类中的属性名不一致导致的,那么我们有以下几种解决方法:
- 可以通过为字段起别名的方式,保证和实体类中的属性名保持一致
在我们的映射文件中去给每一个列名起别名(IDEA2024这么智能吗???)
<mapper namespace="com.qcby.mybatis.mappers.EmpMapper">
<!-- 通过员工id查询员工信息 -->
<select id="getEmpById" resultType="emp">
select emp_id empId, emp_name empName, emp_age empAge, emp_sex
empSex, emp_email empEmail from emp_user where emp_id = #{empId}
</select>
</mapper>
此时再次执行查询,我们就会发现属性名可以打印出来了:
- 若字段名和实体类中的属性名不一致,但是字段名符合数据库的规则(使用_),实体类中的属性
名符合Java的规则(使用驼峰),可以在MyBatis 的核心配置文件中设置一个全局配置信息
mapUnderscoreToCamelCase ,可以在查询表中数据时,自动将_类型的字段名转换为驼峰。
就是我们现在的情况:数据库中为 emp_xxx ,但是实体类中为 empXxx :那么我们在
MyBatisConfig中配置,注意标签在配置文件中的位置:
<settings>
<!-- 自动将_类型的字段名转换为驼峰-->
<!--<setting name="mapUnderscoreToCamelCase" value="true"/>-->
</settings>
同样可以实现相同的效果。
- 使用resultMap
在我们的映射文件中定义一个 resultMap ,和起别名差不多,手动的将列名和属性名一一对应:
<!-- 自定义resultMap -->
<resultMap id="empResultMap" type="emp">
<!-- 主键使用id -->
<id column="emp_id" property="empId"/>
<!-- 其他列使用result -->
<result column="emp_name" property="empName"/>
<result column="emp_age" property="empAge"/>
<result column="emp_sex" property="empSex"/>
<result column="emp_email" property="empEmail"/>
</resultMap>
结果也可以正确输出。
resultMap 标签:
id :唯一标识
type :处理映射关系的实体类的类型
常用标签:
id :处理主键映射,包含的属性: column :设置映射关系中的列名,必须是 sql 查询
的字段名(如果起了别名就写别名); property :设置映射关系中的映射属性名,必
须是实体类中的属性名
result :处理普通字段的映射,包含的属性: column :设置映射关系中的列名,必须
是 sql 查询的字段名(如果起了别名就写别名); property :设置映射关系中的映射
属性名,必须是实体类中的属性名
collction :处理一对多的关系
association :处理多对一的关系

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。
更多推荐
所有评论(0)