把 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
指定的属性中把 SQL
中的常量替换为动态的参数
Mapper
接口:
@Delete("delete from userinfo where id = #{id};")
Integer delete(Integer id);
测试数据:
@Test
void delete() {
System.out.println("删除数据:"+userInfoMapper.delete(4));
}
把 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));
}
我们在上面查询时发现,有几个字段是没有赋值的,只有 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 属性不一致时,处理办法:
返回来的结果对应不上 我们就可以通过起别名的方式,来将结果对应上
给列名起别名,保持别名和实体类属性名一样
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());
}
其实问题的本质就是 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}
通常数据库使用蛇形命名法进行命名(下划线分割各个单词),而 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();