目录
前言
接下来我们会使用的数据表如下:
对应的实体类为:UserInfoMapper
所有的准备工作都在如下文章。
1.配置MyBatis⽇志打印
在Mybatis当中我们可以借助⽇志, 查看到sql语句的执⾏、执⾏传递的参数以及执⾏结果 在配置⽂件中进⾏配置即可如果是application.yml, 配置内容如下
mybatis:
configuration: # 配置打印 MyBatis 执行的 SQL
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
如果是application.properties, 配置内容如下
#指定mybatis输出⽇志的位置, 输出控制台
mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
打印形式如下:
2.参数传递
像select * from userinfo where id=4这种SQL语句已经写死,只能查找id=4 的数据。我们想要更加自由的使用SQL语句,我们就需要动态的数值。
解决⽅案:
将⽅法中的参数,传给SQL语句,使⽤ #{}或${} 的⽅式获取⽅法中的参数
2.1 #{} 和 ${}区别
1.预编译SQL和即时SQL 的区别
1.#{} 使⽤的是预编译SQL, 通过 ? 占位的⽅式, 提前对SQL进⾏编译, 然后把参数填充到SQL语句 中. #{} 会根据参数类型, ⾃动拼接引号 " " 2.${} 会直接进⾏字符替换, ⼀起对SQL进⾏编译. 如果参数为字符串, 需要加上引号 " "
1.#{}
@Select("select * from userinfo where username = #{userName}")
public Userinfo getUserByName(String userName);
测试结果:
2.${}
@Select("select * from userinfo where username = '${userName}'")
public Userinfo getUserByName2(String userName);
测试结果:
2.#{}的效率更高
绝⼤多数情况下, 某⼀条 SQL 语句可能会被反复调⽤执⾏, 或者每次执⾏的时候只有个别的值不同 如果每次都需要 经过1.语法解析, 2.SQL优化、3.SQL编译等,则效率就明显不⾏了。 预编译SQL,编译⼀次之后会将编译后的SQL语句缓存起来,后⾯再次执⾏这条语句时,不会再次编译 (只是输⼊的参数不同), 省去了解析优化等过程, 以此来提⾼效率
3.#{}更安全(防⽌SQL注⼊)
因为${} 会直接进⾏字符替换, ⼀起对SQL进⾏编译
SQL注⼊:
是通过操作输⼊的数据来修改事先定义好的SQL语句,以达到执⾏代码对服务器进⾏攻击的 ⽅法。
可以得出结论: ${} 会有SQL注⼊的⻛险, 所以我们尽量使⽤#{}完成查询
既然如此, 是不是 ${} 就没有存在的必要性了呢?
当然不是,#{} 会根据参数类型, 如果参数类型为String,⾃动拼接引号 " ",当我们不想要⾃动拼接引号 " "时,我们选择${},但一旦使用了${},就一定要考虑SQL注入。
例子1:排序
使用 ${}时
@Select("select * from userinfo order by id ${sort}")
public List<Userinfo> queryAllUser2(String sort);
测试结果:
使用 #{}时
@Select("select * from userinfo order by id #{sort}")
public List<Userinfo> queryAllUser3(String sort);
测试结果:
2.like 查询
@Select("select * from userinfo where username like '%${key}%'")
public List<Userinfo> queryAllUser3(String key);
#{}会SQL错误,但是${}存在SQL注⼊的问题, 所以不能直接使⽤ ${}
解决办法: 使⽤ mysql 的内置函数 concat() 来处理,实现代码如下:
@Select("select * from userinfo where username like concat('%',#{username},'%')")
public List<Userinfo> queryAllUser4(String key);
2.2传递多个参数
1.如果SQL语句中只有一个变量,变量名不需要与参数名对应。
2.如果SQL语句中有多个变量,变量名必需与参数名对应。
3.会自动生成对应参数比如param1自动对应函数的第一个参数。
@Select("select * from userinfo where username = #{userName} and age = #{age}")
public List<Userinfo> queryAllUser5(String userName1,int age);
测试结果:
也可以通过 @Param , 设置参数的别名, 如果使⽤ @Param 设置别名, #{...}⾥⾯的属性名必须和 @Param 设置的⼀样3.增删改查
3.1增(Insert)
@Insert("insert into userinfo (username, password, age, gender) " +
"values (#{username},#{password},#{age},#{gender})")
Integer insert(Userinfo userinfo);
测试代码:
@Test
void insert() {
Userinfo userinfo = new Userinfo();
userinfo.setUsername("wh");
userinfo.setPassword("123456");
userinfo.setAge((byte) 18);
userinfo.setGender((byte) 1);
Integer insert = userInfoMapper.insert(userinfo);
System.out.println(insert);
}
结果:
注意:如果设置了 @Param 属性, #{...}对象就只能是一个整体需要使⽤ 参数.属性 来获取。
@Insert("insert into userinfo (username, password, age, gender) " +
"values (#{userinfo.username},#{userinfo.password},#{userinfo.age},#{userinfo.gender})")
Integer insert2(@Param("userinfo") Userinfo userinfo);
返回主键
如果想要拿到⾃增id, 需要在Mapper接⼝的⽅法上添加⼀个Options的注解
keyProperty:指定能够唯⼀识别对象的属性
@Options(useGeneratedKeys = true,keyProperty = "id")
@Insert("insert into userinfo (username, password, age, gender) " +
"values (#{username},#{password},#{age},#{gender})")
Integer insert3(Userinfo userinfo);
测试代码:
@Test
void insert3() {
Userinfo userinfo = new Userinfo();
userinfo.setUsername("bbb");
userinfo.setPassword("bbb");
userinfo.setAge((byte) 18);
userinfo.setGender((byte) 1);
Integer insert = userInfoMapper.insert3(userinfo);
System.out.println(userinfo.getId());
}
3.2删(Delete)
@Delete("delete from userinfo where id = #{id}")
Integer delete(Integer id);
3.3改(Update)
@Update("update userinfo set password = #{password} where id = #{id}")
Integer update(UserInfo userInfo);
3.4查(Select)
@Select("select * from userinfo")
public List<UserInfo> queryAllUser();
测试结果:
原因;
当⾃动映射查询结果时,MyBatis 会获取结果中返回的列名并在 Java 类中查找相同名字的属性
解决办法:
1.起别名
2.结果映射
/**
* 起别名
* @return
*/
@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();
/**
* 指定结果映射关系
* @return
*/
@Results(id ="resultMap" , value = {
@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();
3.开启驼峰命名(推荐)
通常数据库列使⽤蛇形命名法进⾏命名(下划线分割各个单词), ⽽ Java 属性⼀般遵循驼峰命名法约定. 为了在这两种命名⽅式之间启⽤⾃动映射,需要将 mapUnderscoreToCamelCase 设置为 true。 我们进行如下配置即可 以application.yml为例:mybatis:
configuration:
map-underscore-to-camel-case: true #自动驼峰转换
以上为我个人的小分享,如有问题,欢迎讨论!!!
都看到这了,不如关注一下,给个免费的赞
标签:username,标签,age,userinfo,SQL,MyBatis,操作,id,Select From: https://blog.csdn.net/WHabc2002/article/details/142745011