用于web三层架构的Dao层,封装了JDBC,用于简化程序连接数据库的过程,能够基于注解配置SQL语句
一、基础操作
删除
@Mapper
public interface EmpMapper {
// 根据id删除数据
@Delete("delete from emp where id = #{id}")
public void delete(Integer id);
}
#{id} 传递方法形参
删除(预编译)
两个参数占位符

新增
推荐将多个值封装到一个对象中
@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(useGeneratedKeys = true, keyProperty = "id") // 核心修正:开启主键回显,指定主键字段
@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);
更新
// 更新员工
@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查询)
如果直接使用简单方法
@Select("select * from emp where id = #(id)")
public Emp getByld(Integer id);
会发现有的字段值没有被封装起来
原因:
实体类属性名和数据库表查询返回的字段名一致,mybatis会自动封装。
如果实体类属性名和数据库表查询返回的字段名不一致,不能自动封装。
解决:
方案一
给字段起别名
方案二
通过@Results,@result注解手动映射封装

方案三
开启mybatis的驼峰命名自动映射开关
开启驼峰命名:如果字段名与属性名符合驼峰命名规则,mybatis 会自动通过驼峰命名规则映射。
在项目配置文件application.properties中写入
#开启驼峰命名自动映射,即从数据库字段名 a_column 映射到 Java 属性名 aColumn。mybatis.configuration.map-underscore-to-camel-case=true
查询(条件查询)
//条件查询员工
@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);
#{}的方式不能出现在引号中,所以name的占位符用${name}
这种方式不安全,有SQL注入问题,可以用下列方法
— 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的1.X版本或单独使用mybatis时,要想传递多参数时,需要用注解@Param()指定要传递的参数名
比如public List<Emp> list(@Param("name") String name); 这是因为之前版本对mapper接口编译过程中不会对方法的形参名称进行保留,生成的字节码文件名会变为

二、XML映射文件
对于逻辑复杂、内容较长的 SQL 语句,直接写在代码行中会导致可读性差、维护困难,这时就可以借助 XML 映射文件来管理这类 SQL,让语句结构更清晰、便于调试。
定义XML文件规范
规范
-
XML映射文件的名称与Mapper接口名称一致,并且将XML映射文件和Mapper接口放置在相同包下(同包同名)。
-
XML映射文件的namespace属性与Mapper接口全限定名一致。 图中紫色部分
-
XML映射文件中sql语句的id与Mapper接口中的方法名一致,并保持返回类型一致。 图中黄色部分

三、动态SQL
随着用户的输入或外部条件的变化而变化的SQL语句,我们称为动态SQL
<if>
前面的条件查询语句(XML映射文件)
<select id="list" resultType="com.itheima.pojo.Emp">
select * from emp where name like concat('%',#{name},'%') and gender = #{gender} and entrydate between #{begin} and #{end} order by update_time desc
</select>
这样必须每一个参数都输入值才能输出内容,修改后的代码
<select id="list" resultType="com.itheima.pojo.Emp">
select id, username, password, name, gender, image, job,
entrydate, dept_id, create_time, update_time from emp
where
<if test="name != null">
name like concat('%',#{name},'%')
</if>
<if test="gender != null">
and gender = #{gender}
</if>
<if test="begin != null and end != null">
and entrydate between #{begin} and #{end}
</if>
order by update_time desc
</select>
但如果第一个条件name为空,SQL语句就会直接拼接第二个条件前面的and,导致报错
解决:将where换成<where></where>标签,会自动去除子句前的and或or
这样就会动态生成where关键字(如果where中条件都不符合,就不生成where关键字)
<foreach>
要实现多选操作
正常SQL语句
delete from emp where id in (1,2,3);
接口方法
//批量删除
public void deleteByIds(List<Integer> ids);
XML映射文件
<delete id="deleteByIds">
delete from emp where id in
<foreach collection="ids" item="id" separator="," open="(" close=")">
#{id}
</foreach>
</delete>
属性
collection:要遍历的集合名称
item:集合遍历出来的元素/项
separator:每一次遍历使用的分隔符
open:遍历开始前拼接的片段
close:遍历结束后拼接的片段
<sql> <include>
两个需要配套使用,类似于java中的方法,简化重复内容
<select id="list" resultType="com.itheima.pojo.Emp">
select id, username, password, name, gender, image, job, entrydate, dept_id, create_time, update_time from emp
where
<if test="name != null">
name like concat('%',#{name},'%')
</if>
<if test="gender != null">
and gender = #{gender}
</if>
<if test="begin != null and end != null">
and entrydate between #{begin} and #{end}
</if>
order by update_time desc
</select>
<select id="getById" resultType="com.itheima.pojo.Emp">
select id, username, password, name, gender, image, job, entrydate, dept_id, create_time, update_time from emp
where id = #{id}
</select>
观察这两个XML文件中的SQL语句
发现select所要查询的内容相同,为使这种大量重复内容方便修改,java中我们会使用方法
在SQL中我们可以使用<sql> <include>
使用方法,<sql>编写一个指定id的标签语句
<sql id="commonSelect">
select id, username, password, name, gender, image, job, entrydate, dept_id, create_time, update_time from emp
</sql>
<include>在需要位置指定refid调用
<include refid = "commonSelect"/>
