【MyBatis】实现数据库的增、删、改、查
文章目录
- 增(Insert)
- 返回主键
- 删(Delete)
- 改(Update)
- 查(Select)
- 属性不一致
- 1. 起别名
- 2. 结果映射
- 3. 自动驼峰转换(推荐)
增(Insert)
把 SQL
中的常量替换成动态的参数
Mapper
接口:
@Insert("insert into userinfo (username, password, age, gender) values (#{username}, #{password}, #{age}, #{gender})")
Integer insert(UserInfo userInfo);
直接使用 UserInfo
对象的属性名来获取参数
测试代码:
@Test
void insert() { UserInfo userInfo = new UserInfo(); userInfo.setUsername("zhaoliu"); userInfo.setPassword("zhaoliu"); userInfo.setAge(18); userInfo.setGender(1); Integer result = userInfoMapper.insert(userInfo); System.out.println("result: "+result);
}
运行后,观察数据库执行结果:
- 如果设置了
@Param
属性,#{...}
需要使用参数. 属性
来获取
返回主键
Insert
语句默认返回的是受影响的行数,但是有些情况下,数据插入之后,还需要有后续的关联操作,需要获取到新插入数据的 id
- 比如订单系统
- 当我们下单之后,需要通知物流系统、库存系统、结算系统等,这时就需要拿到订单的
id
如果想要拿到自增 id
,需要在 Mapper
接口的方法上添加一个 Options
的注解
//数据库的“增”操作
@Options(useGeneratedKeys = true, keyProperty = "id")
@Insert("insert into userinfo (username, password, age, gender) values (#{username}, #{password}, #{age}, #{gender})")
Integer insert(UserInfo userInfo);
useGeneratedKeys
: 这会令MyBatis
使用JDBC
的getGeneratedKeys
方法取出由数据库内部生成的主键(比如:像MySQL
和SQL Server
这样的关系型数据库管理系统的自动递增字段),默认值:false
keyProperty
:指定能够唯一识别对象的属性,MyBatis
会使用getGeneratedKeys
的返回值或insert
语句的selectKey
子元素设置它的值,默认值:未设置(unset
)
测试数据:
@Test
void insert() { UserInfo userInfo = new UserInfo(); userInfo.setUsername("zhaoliu"); userInfo.setPassword("zhaoliu"); userInfo.setAge(18); userInfo.setGender(1); Integer result = userInfoMapper.insert(userInfo); System.out.println("添加的数据: " + result + "数据id: " + userInfo.getId());
}
运行结果:
- 注意:设置
useGeneratedKeys=true
之后,方法返回值依然是受影响的行数,自增id
会设置在上述Property
指定的属性中
删(Delete)
把 SQL
中的常量替换为动态的参数
Mapper
接口:
@Delete("delete from userinfo where id = #{id};")
Integer delete(Integer id);
测试数据:
@Test
void delete() { System.out.println("删除数据:"+userInfoMapper.delete(4));
}
改(Update)
把 SQL
中的常量替换为动态的参数
Mapper
接口:
@Update("update userinfo set password = #{password}, age = #{age}")
Integer update(UserInfo userInfo);
测试数据:
@Test
void update() { UserInfo userInfo = new UserInfo(); userInfo.setPassword("123123"); userInfo.setAge(11); System.out.println("更新数据为:"+userInfoMapper.update(userInfo));
}
查(Select)
我们在上面查询时发现,有几个字段是没有赋值的,只有 Java 对象属性和数据库字段一模一样时,才会进行赋值
我们查询一些数据:
@Select("select id, username, password, age, gender, phone, delete_flag, create_time, update_time from userinfo")
List<UserInfo> queryAllUser();
查询结果:
从运行结果上可以看到,我们 SQL
语句中,查询了 delete_flag
,create_time
,update_time
,但是这几个属性却并没有赋值
MyBatis
会根据方法的返回结果进行赋值- 方法用对象
UserInfo
接收返回结果,MySQL
查询出来数据为一条,就会自动赋值给对象 - 方法用
List<UserInfo>
接收返回结果,,MySQL
查询出来数据为一条或多条时时,也会自动赋值给List
- 但如果
MySQL
查询返回多条,但是方法使用UserInfo
接收,MyBatis
执行就会报错
原因分析:
- 当自动映射查询结果时,
MyBatis
会获取结果中返回的列名,并在Java
类中查找相同名字的属性(忽略大小写) - 这意味着如果发现了
ID
列和id
属性,MyBatis
会将列ID
的值赋给id
属性
如果数据库的字段,和 Java 对象属性一致,就自动赋值。要是不一致,就为 null
属性不一致
结果映射,数据库字段和 Java 属性不一致时,处理办法:
- 起别名
- 进行结果映射
- 驼峰自动转换
1. 起别名
返回来的结果对应不上
我们就可以通过起别名的方式,来将结果对应上
给列名起别名,保持别名和实体类属性名一样
Mapper
接口:
// 起别名
@Select("SELECT id, username, password, age, gender, phone, delete_flag as deleteFlag, " + "create_time as createTime, update_time as updateTime FROM userinfo")
List<UserInfo> selectUserInfos();
SQL
语段太长,使用+
进行字符串拼接
测试数据:
@Test
void selectUserInfos() { System.out.println(userInfoMapper.selectUserInfos());
}
2. 结果映射
其实问题的本质就是 mybatis
不知道把那三个数据给谁。那我们就可以直接通过注解告诉 mybatis
把数据给谁就好了
这里我们**指定结果映射关系
// 2. 指定结果映射关系
// 在开发中,尽量不要使用 * ,需要查询什么字段,就全部列出来
@Results({ @Result(column = "delete_flag", property = "deleteFlag"), @Result(column = "create_time", property = "createTime"), @Result(column = "update_time", property = "updateTime")
})
@Select("SELECT * FROM userinfo")
List<UserInfo> selectUserInfos2();
column
是数据库字段名;property
是 java 属性,也就是把这个字段的值,赋值给谁- 使用
Results
注解Results
里面是多个Result
注解- 数组定义:
{1, 2, 3, 4}
3. 自动驼峰转换(推荐)
通常数据库使用蛇形命名法进行命名(下划线分割各个单词),而 java
属性一般遵循驼峰命名法约定。
为了在这两种命名方式之间启动自动映射,需要将 mapUnderscoreToCamelCase
设为 true
mybatis: configuration: # 配置打印 MyBatis⽇志 map-underscore-to-camel-case: true # 开启驼峰自动转换
驼峰命名规则:abc_xyz
==>> abcXyz
- 表中的字段名:
abc_xyz
- 类中属性名:
abcXyz
java 代码不需要做任何处理
// 3. 驼峰自动转换
@Select("SELECT id, username, password, age, gender, phone, delete_flag, " + "create_time, update_time FROM userinfo")
List<UserInfo> selectUserInfo3();