Mybatis(二)
Mybatis基础操作
删除
根据主键删除
- SQL语句:
delete from emp where id = 17;
- 接口方法:
@Delete("delete from emp where id = #{id}")
public void delete(Integer id);
注意事项
- 如果mapper接口方法形参只有一个普通类型的参数,#{…} 里面的属性名可以随便写,如:#{id}、#{value},建议保持一致以增强可读性。
- delete、create、remove和update方法均有返回值,代表此次操作影响到的记录数。
- 可以在application.properties中,打开mybatis的日志,并指定输出到控制台:
#指定mybatis输出日志的位置,输出控制台
mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
参数占位符
占位符 | 作用 | 使用时机 |
---|---|---|
# | 执行SQL时,会将#{…}替换为?,生成预编译SQL,会自动设置参数值 | 参数传递都使用# |
$ | 拼接SQL。直接将参数拼接在SQL语句中,存在SQL注入问题 | 对表名、列表进行动态设置时使用。 |
SQL预编译
- 形式:SQL语句:
delete from emp where id = ?
;参数:delete方法的入参;执行:使用参数将?
替换后的SQL语句。
优势
-
性能更高,使用Mybatis操作MySQL数据库时,Java将SQL语句传递给MySQL后,MySQL会依次执行以下操作:
- 检查缓存中是否有刚才传入的SQL语句,如果有,直接执行它(如果是预编译的话还需要使用参数),且不用再执行后两步。
- 依次对刚才传入的SQL语句执行SQL语法解析检查、优化SQL和编译SQL的操作,并在编译SQL之后将编译好的SQL语句存入缓存。
- 执行编译好的SQL语句。
如果使用预编译的SQL语句,则它放入缓存后,能够匹配更多新传入的SQL语句,从而减少SQL语法解析检查、优化SQL和编译SQL的执行,提高性能。
-
更安全(防止SQL注入):SQL注入是通过操作输入的数据来修改事先定义好的SQL语句,以达到执行代码对服务器进行攻击的方法。直接拼接字符串可能会导致出现这种问题,而使用预编译的SQL语句则不会。
插入
- SQL语句:
insert into emp(username, name, gender, image, job, entrydate, dept_id, create_time, update_time) values ('songyuanqiao','宋远桥',1,'1.jpg',2,'2012-10-09',2,'2022-10-01 10:00:00','2022-10-01 10:00:00');
- 接口方法(将变量封装进实体对象进行传递):
@Insert("insert into emp(username, name, gender, image, job, entrydate, dept_id, create_time," +
"update_time) values(#{username}, #{name}, #{gender}, #{image}, #{job}, #{entrydate}, #{deptId}," +
"#{createTime}, #{updateTime})")
public void insert(Emp emp);
主键返回
- 在数据添加成功后,可以获取自动生成的插入数据库数据的主键。
- 在接口方法上加一行注解即可:
@Options(keyProperty = "id", useGeneratedKeys = true) //会自动将生成的主键值,赋值给入参对象的id属性
更新
- SQL语句(根据ID更新员工信息):
update emp set username = 'songdaxia', name = '宋大侠', gender = 1 , image = '1.jpg' , job = 2, entrydate = '2012-01-01', dept_id = 2, update_time = '2022-10-01 12:12:12' where id = 19;
- 接口方法:
@Update("update emp set username=#{username}, name=#{name}, gender=#{gender}, image=#{image}, " +
"job=#{job}, entrydate=#{entrydate}, dept_id=#{deptId}, update_time=#{updateTime} where id=#{id}")
public void update(Emp emp);
查询
根据ID查询
- SQL语句
select * from emp where id = 19;
- 接口方法
@Select("select * from emp where id = #{id}")
public Emp getById(Integer id);
数据封装
- 如果实体类属性名和数据库表查询返回的字段名一致,mybatis会自动封装。
- 如果实体类属性名和数据库表查询返回的字段名不一致,不能自动封装。
数据封装解决方法
- 起别名:在SQL语句中,对不一样的列名起别名,别名和实体类属性名一样。
@Select("select id, username, password, name, gender, image, job, entrydate, dept_id deptId, create_time " +
"createTime, update_time updateTime from emp where id = #{id}")
public Emp getById(Integer id);
- 手动结果映射:通过 @Results及@Result 进行手动结果映射。
@Select("select * from emp where id = #{id}")
@Results({
@Result(column = "dept_id", property = "deptId"),
@Result(column = "create_time", property = "createTime"),
@Result(column = "update_time", property = "updateTime")})
public Emp getById(Integer id);
- 开启驼峰命名(推荐使用):如果字段名与属性名符合驼峰命名规则,mybatis会自动通过驼峰命名规则映射。
#application.properties文件中
#开启驼峰命名自动映射,即从数据库字段名a_column映射到Java属性名aColumn。
mybatis.configuration.map-underscore-to-camel-case=true
条件查询
- SQL语句:
select * from emp where name like '%张%' and gender = 1 and entrydate between '2010-01-01' and '2020-01-01' order by update_time desc;
- 接口方法一:
//在字符串内部不能使用#{···},因为预编译生成的?占位符不能出现在引号内
//可以使用${···}代替,但是这样做会导致性能低、不安全、存在SQL注入问题
@Select("select * from emp where name like '%${name}%' and gender = #{gender} and entrydate between " +
"#{begin} and #{end} order by update_time desc")
public List<Emp> list(String name, Short gender, LocalDate begin, LocalDate end);
- 接口方法二:
//使用MySQL的concat函数代替${···},能够避免出现那些问题,推荐使用
@Select("select * from emp where name like concat('%',#{name},'%') and gender = #{gender} and " +
"entrydate between #{begin} and #{end} order by update_time desc")
public List<Emp> list(String name, Short gender, LocalDate begin, LocalDate end);
参数名说明
- 在springBoot的2.x版本中,方法入参名直接使用与占位符中名称相同即可完成参数传递。
- 在springBoot的1.x版本中或单独使用mybatis时,方法入参之前必须加上
@Param("占位符中名称")
的注解,因为在这些环境下编译生成的的字节码文件中入参的名称不会保留:
//源代码
@Select("select * from emp where name like concat('%',#{name},'%') and gender = #{gender} and " +
"entrydate between #{begin} and #{end} order by update_time desc")
public List<Emp> list(String name, Short gender, LocalDate begin, LocalDate end);
//编译生成的字节码文件
...
public List<Emp> list(String var1, Short var2, LocalDate var3, LocalDate var4);
XML映射文件
规范
- XML映射文件的名称与Mapper接口名称一致,并且将XML映射文件和Mapper接口放置在相同包下。(同包同名)
- XML映射文件的namespace属性与Mapper接口的全类名保持一致。
- XML映射文件中sql语句的id与Mapper接口中的方法名一致,并保持返回类型一致。
两种方法的选择
- 如果只是完成一些简单的增删改查功能,那么使用Mybatis的注解比较好。
- 如果需要实现复杂的SQL功能,建议使用XML来配置映射语句,简化Java源码。
MybatisX
MybatisX 是一款基于 IDEA 的快速开发Mybatis的插件,为效率而生,在IDEA中搜索并安装即可。
Mybatis动态SQL
随着用户的输入或外部条件的变化而变化的SQL语句,我们称为动态SQL。
<if>
- 用于判断条件是否成立。使用test属性进行条件判断,如果条件为true,则拼接SQL。
- 语法:
<if test="条件语句">
...
</if>
<where>
- where元素只会在子元素有内容的情况下才插入where子句,而且会自动去除子句的开头的AND 或OR。
- 语法:
<!--用于替换SQL语句中的where关键字-->
<where>
...
</where>
<set>
- 动态地在行首插入 SET 关键字,并会删掉额外的逗号。(用在update语句中)
- 语法:
<!--动态地在行首插入 SET 关键字,并会删掉额外的逗号。(用在update语句中)-->
<set>
...
</set>
<foreach>
- 用于遍历集合中的元素,拼接进SQL语句,同时还可以加上拼接的起始符、分隔符和结束符。
- 语法:
<foreach collection="集合名称" item="集合遍历出来的元素/项" separator="每一次遍历使用的分隔符" open="遍历开始前拼接的片段" close="遍历结束后拼接的片段">
...#{集合遍历出来的元素/项}...
</foreach>
<sql>,<include>
- <sql>:定义可重用的 SQL 片段。
- <include>:通过属性refid,引用包含的sql片段。
- 这两个标签配合使用,可以提升代码的复用性,方便开发和维护。
- 语法:
<sql id="唯一的id">
SQL语句
</sql>
<include refid="要引用的sql片段的id"/>
标签:语句,第九天,JavaWeb,gender,笔记,emp,SQL,id,name
From: https://www.cnblogs.com/zgg1h/p/18105344