网站是否必须做认证,网站前端设计图,湖南seo推广软件,七牛备份wordpress目录
一.准备基础代码
Mybatis的通用配置
二. 基本CURD操作
1.查询-根据id查询一条
2.查询-查询数量
3.删除
4.新增
获取主键值
5.修改
6.查询-模糊查询
预编译SQL
#{}与${}的区别【面试题】
三. Mybatis的方法参数与结果集
1.SQL里取方法参数的值
2.查询结果集…目录
一.准备基础代码
Mybatis的通用配置
二. 基本CURD操作
1.查询-根据id查询一条
2.查询-查询数量
3.删除
4.新增
获取主键值
5.修改
6.查询-模糊查询
预编译SQL
#{}与${}的区别【面试题】
三. Mybatis的方法参数与结果集
1.SQL里取方法参数的值
2.查询结果集的封装
方案一SQL语句里给字段起别名
方案二使用Results和Result手动映射
四.Mybatis的XML映射文件
1.介绍
2.用法
3.示例
4.给idea配置代码模板
五、Mybatis的动态SQL【重点】
1. 动态SQL介绍
2. if标签和where标签
3. set标签
4. foreach标签
5. sql标签和include标签 一.准备基础代码
把基础工程《资料\00.基础工程\web09-mybatis-curd》拷贝到不含中文、空格、特殊字符的目录里然后使用idea直接open打开项目 准备基础环境 依赖pom.xml
propertiesmaven.compiler.source11/maven.compiler.sourcemaven.compiler.target11/maven.compiler.targetproject.build.sourceEncodingUTF-8/project.build.sourceEncoding/propertiesparentgroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-parent/artifactIdversion2.7.3/version/parentdependenciesdependencygroupIdorg.mybatis.spring.boot/groupIdartifactIdmybatis-spring-boot-starter/artifactIdversion2.2.2/version/dependencydependencygroupIdcom.mysql/groupIdartifactIdmysql-connector-j/artifactIdversion8.0.33/versionscoperuntime/scope/dependencydependencygroupIdorg.projectlombok/groupIdartifactIdlombok/artifactIdoptionaltrue/optional/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-test/artifactIdscopetest/scope/dependency/dependencies
配置文件application.properties
spring.datasource.driver-class-namecom.mysql.cj.jdbc.Driver
spring.datasource.urljdbc:mysql://localhost:3306/db4
spring.datasource.usernameroot
spring.datasource.passwordroot
引导类
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;SpringBootApplication
public class MybatisCurdApplication {public static void main(String[] args) {SpringApplication.run(MybatisCurdApplication.class, args);}
}
查询所有员工 实体类
import lombok.Data;import java.time.LocalDate;
import java.time.LocalDateTime;Data
public class Emp {private Integer id;private String username;private String password;private String name;private Integer gender;private String image;private Integer job;private LocalDate entrydate;private Integer deptId;private LocalDateTime createTime;private LocalDateTime updateTime;
}
EmpMapper
import com.itheima.pojo.Emp;
import org.apache.ibatis.annotations.Select;import java.util.List;Mapper
public interface EmpMapper {Select(select * from emp)ListEmp queryAll();
}
功能测试
import com.itheima.mapper.EmpMapper;
import com.itheima.pojo.Emp;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;import java.util.List;SpringBootTest
public class CurdTest {Autowiredprivate EmpMapper empMapper;Testpublic void testQueryAll(){ListEmp emps empMapper.queryAll();emps.forEach(System.out::println);}
}
Mybatis的通用配置
Mybatis的日志输出
直接修改application.properties增加配置
mybatis.configuration.log-implorg.apache.ibatis.logging.stdout.StdOutImpl
Mybatis下划线与驼峰命名转换
直接修改application.properties增加配置
#开启下划线与驼峰命名的自动映射。
# 如果设置为true那么数据库里下划线命名风格的字段会自动映射到Java里驼峰式命名的属性
# 比如数据库字段是dept_id Java里的成员变量名是deptId。 Mybatis会认为这两个是对应的
mybatis.configuration.map-underscore-to-camel-casetrue
基本CURD操作
使用Mybatis无论什么功能都只需要 在Mapper接口里写一个方法 给方法配置SQL语句用注解
二. 基本CURD操作
1.查询-根据id查询一条
EmpMapper实现功能
/*** 0. 先准备好SQL语句* 1. 方法的参数根据SQL语句需要的参数来定* 这些参数都是给SQL语句使用。SQL语句里需要几个参数方法上就要加几个形参* SQL语句里要获取参数值如果方法只有一个参数写法是#{随意写}建议写成#{参数名}* 2. 方法的返回值根据我们想要得到什么结果来定* 我们期望Mybatis帮我们把查询结果封装成什么对象。* 写成EmpMybatis就会把查询的结果封装成一个Emp对象* 注意实体类里的属性名要和表的字段名 一致(相同或者符合下划与驼峰命名的规则)*/
Select(select * from emp where id #{id})
Emp queryById(Integer id);
CurdTest功能测试
Test
public void testQueryById(){Emp emp empMapper.queryById(1);System.out.println(emp emp);
}
2.查询-查询数量
EmpMapper实现功能
/*** 查询数量SQL语句 select count(*) from emp* 方法要参数吗不需要。因为SQL语句不需要参数* 方法返回值是什么类型能够封装查询结果即可可使用int、long*/
Select(select count(*) from emp)
int queryCount();
CurdTest功能测试
Test
public void testQueryCount(){int count empMapper.queryCount();System.out.println(count count);
}
3.删除
EmpMapper实现功能
/*** 根据id删除一个员工delete from emp where id ?* 配置查询语句Select* 配置新增语句Insert* 配置修改语句Update* 配置删除语句Delete*/
Delete(delete from emp where id #{id})
void deleteById(Integer id);
CurdTest功能测试
Test
public void testDeleteById(){empMapper.deleteById(17);
}
4.新增
EmpMapper实现功能
/*** 插入一条员工数据* INSERT INTO emp (id, username, password, name, gender, image, job, entrydate, dept_id, create_time, update_time)* VALUES (16, songyuanqiao, 123456, 宋远桥, 1, 16.jpg, 2, 2010-01-01, 2, 2023-08-19 10:39:37, 2023-08-19 10:39:37);** 方法的参数* 如果SQL语句需要的参数过多方法的形参可以使用一个实体类* SQL语句里使用 #{JavaBean的属性名}* 注意* 不要写成 #{JavaBean属性名}* #{属性名}的顺序必须与前边的字段顺序是一致对应的*/
Insert(INSERT INTO emp (username, password, name, gender, image, job, entrydate, dept_id, create_time, update_time)\n VALUES (#{username}, #{password}, #{name}, #{gender}, #{image}, #{job}, #{entrydate}, #{deptId}, #{createTime}, #{updateTime}))
void insert(Emp emp);
CurdTest功能测试
Test
public void testInsert(){Emp emp new Emp();emp.setUsername(tom);emp.setPassword(123);emp.setName(汤姆);emp.setGender(1);emp.setCreateTime(LocalDateTime.now());emp.setUpdateTime(LocalDateTime.now());empMapper.insert(emp);
}
获取主键值
如果执行insert时需要获取数据的主键值我们可以做 在Mapper接口里插入的方法上再增加注解Options(useGeneratedKeystrue, keyPropertyJavaBean里的属性名)
/*** 插入一条员工数据* INSERT INTO emp (id, username, password, name, gender, image, job, entrydate, dept_id, create_time, update_time)* VALUES (16, songyuanqiao, 123456, 宋远桥, 1, 16.jpg, 2, 2010-01-01, 2, 2023-08-19 10:39:37, 2023-08-19 10:39:37);** 方法的参数* 如果SQL语句需要的参数过多方法的形参可以使用一个实体类* SQL语句里使用 #{JavaBean的属性名}* 注意* 不要写成 #{JavaBean属性名}* #{属性名}的顺序必须与前边的字段顺序是一致对应的* 如果插入数据之后需要获取数据的主键值Options* useGeneratedKeys利用数据库的主键自增得到主键值* keyProperty把得到的主键值存储到参数实体类对象的哪个属性上*/Options(useGeneratedKeys true, keyProperty id)Insert(INSERT INTO emp (username, password, name, gender, image, job, entrydate, dept_id, create_time, update_time)\n VALUES (#{username}, #{password}, #{name}, #{gender}, #{image}, #{job}, #{entrydate}, #{deptId}, #{createTime}, #{updateTime}))void insert(Emp emp);
5.修改
EmpMapper实现功能
/*** 修改id为19的数据* UPDATE emp SET username jerry, password 123, name 杰瑞, gender 1, image null, job null, entrydate null, dept_id null, create_time 2023-08-19 14:54:29, update_time 2023-08-19 14:54:29 WHERE id 19;*/
Update(UPDATE emp SET username #{username}, password #{password}, name #{name}, gender #{gender}, image #{image}, job #{job}, entrydate #{entrydate}, dept_id #{deptId}, create_time #{createTime}, update_time #{updateTime} WHERE id #{id})
void updateById(Emp emp);
CurdTest功能测试
Test
public void testUpdateById(){Emp emp empMapper.queryById(19);emp.setUsername(robin li);emp.setGender(2);empMapper.updateById(emp);
}
6.查询-模糊查询
EmpMapper实现功能
/*** 模糊查询查询姓名里包含“张”的员工列表* select * from emp where name like %张%;* SQL语句里拼接字符串函数concat(字符串1, 字符串2, 字符串3,....)*/Select(select * from emp where name like concat(%, #{name}, %))ListEmp queryByName1(String name);Select(select * from emp where name like %${name}%)ListEmp queryByName2(String name);
CurdTest功能测试 Testpublic void testQueryByName1(){ListEmp list empMapper.queryByName1(张);list.forEach(System.out::println);}Testpublic void testQueryByName2(){ListEmp list empMapper.queryByName2(张);list.forEach(System.out::println);}
预编译SQL
预编译不是Mybatis的概念而是JDBC的概念。 不使用预编译RDBMS先编译SQL解析SQL语句确定SQL的执行方案再执行SQL语句得到结果 使用了预编译先把SQL语句进行解析确定执行方案然后设置参数值执行SQL
好处1-预编译执行SQL性能更高 好处2-可以防止SQL注入漏洞 #{}与${}的区别【面试题】 #{}底层使用的是预编译方式。 更安全因为可以防止SQL注入漏洞 执行SQL的性能更高 ${}没有使用预编译是直接拼接SQL字符串 不安全可能存在SQL注入漏洞 执行SQL的性能不如预编译
三. Mybatis的方法参数与结果集
1.SQL里取方法参数的值
如果方法只有一个参数 如果参数是简单值(8种基本数据类型及包装类、String)SQL语句里取参数值是#{参数名} 如果参数是JavaBean对象SQL语句里取JavaBean的属性值#{属性名}
如果方法有多个参数SQL语句里取参数值 从SpringBoot2版本开始#{形参名} 在SpringBoot2以前版本【了解】 首先给方法参数起名称添加注解Param(名称) 然后在SQL语句里使用#{名称} 获取对应参数值
/*** 需求根据姓名、性别、入职时间范围 搜索员工信息* SQLselect * from emp where name like ? and gender ? and entrydate between ? and ?* 如果方法有多个参数SQL语句里取参数值#{参数名称}。从SpringBoot2开始提供的功能*/
Select(select * from emp where name like concat(%,#{name}, %) and gender #{gender} and entrydate between #{begin} and #{end})
ListEmp queryEmpList(String name,Integer gender,LocalDate begin,LocalDate end);Select(select * from emp where name like concat(%,#{a}, %) and gender #{b} and entrydate between #{c} and #{d})
ListEmp queryEmpList2(Param(a) String name,Param(b) Integer gender,Param(c) LocalDate begin,Param(d) LocalDate end);
2.查询结果集的封装
Mybatis会自动帮我们把查询的结果集封装成实体类对象前提条件是 要么 JavaBean的属性名和 表的字段名完全相同。 比如字段名是genderEmp类里的属性名也叫gender 要么 JavaBean的属性名和 表的字段名按照 下划线与驼峰映射 是一致的。 比如字段名是dept_idEmp类里属性名是deptId 前提开启下划线与驼峰的命名转换修改application.properties配置文件添加参数 mybatis.configuration.map-underscore-to-camel-casetrue
如果JavaBean的属性名和字段名完全不匹配就需要处理这种情况
Data
NoArgsConstructor
AllArgsConstructor
public class Employee {private Integer id;/*对应的字段名是username*/private String uname;/*对应的字段名是password*/private String pword;private String name;private Integer gender;private String image;private Integer job;private LocalDate entrydate;private Integer deptId;private LocalDateTime createTime;private LocalDateTime updateTime;
}
方案一SQL语句里给字段起别名
/*** JavaBean属性名 与 表字段名 完全不匹配* SQL语句里给字段起别名别名和JavaBean属性名相同*/
Select(select id, username as uname, password as pword,name,gender,image,job, entrydate,dept_id,create_time, update_time from emp)
ListEmployee queryEmployeeList2();
方案二使用Results和Result手动映射
只需要把不同的字段配置一下如果字段和属性名匹配就不需要做配置
/*** JavaBean属性名 与 表字段名 完全不匹配* 我们使用Results和Result注解手动设置一下哪个字段对应哪个属性* 注解1Results用于配置当前查询里所有字段的映射关系* 注解2Result用于配置某一个字段与属性的对应关系* property写的是JavaBean的属性名* column写的是表里的字段名*/
Select(select * from emp)
Results({Result(property uname, column username),Result(property pword, column password)
})
ListEmployee queryEmployeeList3();
四.Mybatis的XML映射文件
1.介绍
Mybatis的SQL语句可以使用注解直接配置到Mapper接口里的方法上也可以定义到XML文件里 如果SQL语句写到接口里的方法上注解方式适合于简单SQL或者固定不变的SQL 如果SQL语句写到XML文件里xml方式更适合于复杂SQL或者动态变化的SQL
注意XML方式和注解方式可以同时使用但是要注意 一个方法的SQL语句要么用注解方式配置要么用XML方式配置不能重复配置
2.用法
XML文件的要求 XML文件的位置要和Mapper同一包下按照maven规范要放到resources里边的同名文件夹下 XML文件的名称要和Mapper接口的名称相同
XML内容的要求 根标签mapper namespaceMapper接口的全限定类名表示当前XML是给哪个Mapper接口配置语句的 在mapper标签里边配置SQL语句 select标签配置select语句SQL语句写到标签里边。需要配置id属性和resultType属性 id属性配置方法名。表示当前SQL语句是给哪个方法配置的 resultType属性告诉Mybatis要把查询结果中的每一行数据封装成什么对象 insert标签配置insert语句SQL语句写到标签里边。需要配置id属性 id属性配置方法名。表示当前SQL语句是给哪个方法配置的 update标签配置update语句SQL语句写到标签里边。需要配置id属性 id属性配置方法名。表示当前SQL语句是给哪个方法配置的 delete标签配置delete语句SQL语句写到标签里边。需要配置id属性 id属性配置方法名。表示当前SQL语句是给哪个方法配置的
3.示例
Mapper接口
/*** 使用XML方式配置SQL语句* XML文件的位置Mapper接口在什么包XML文件就必须在同包下。* 在resources目录下右键创建Directory文件夹以/为分隔符千万不要以.为分隔符。* 比如com/itheima/mapper* XML文件的名称Mapper接口叫什么名字XML文件也叫什么名字**/
ListEmp queryEmpListXml(String name,Integer gender,LocalDate begin,LocalDate end);
XML映射文件
?xml version1.0 encodingUTF-8 ?
!DOCTYPE mapperPUBLIC -//mybatis.org//DTD Mapper 3.0//ENhttp://mybatis.org/dtd/mybatis-3-mapper.dtd
!--
mapper标签根标签namespace要写Mapper接口的全限定类名。表示当前xml文件是给哪个Mapper接口配置的
mapper的子标签select标签配置select语句SQL语句写到标签里边insert标签配置insert语句SQL语句写到标签里边update标签配置update语句SQL语句写到标签里边delete标签配置delete语句SQL语句写到标签里边以上标签都有的属性id写方法名。表示当前语句是给哪个方法配置的resultTypeselect标签专用的属性用于告诉MybatisSQL查询语句的结果要封装成什么对象写JavaBean的全限定类名不需要写List、Set等等
--
mapper namespacecom.itheima.mapper.EmpMapperselect idqueryEmpListXml resultTypecom.itheima.pojo.Empselect * from empwhere name like concat(%,#{name}, %)and gender #{gender}and entrydate between #{begin} and #{end}/select
/mapper
功能测试
Test
public void testQueryEmpListXml(){LocalDate begin LocalDate.of(2010, 1, 1);LocalDate end LocalDate.of(2015, 12, 31);ListEmp emps empMapper.queryEmpListXml(张, 1, begin, end);for (Emp emp : emps) {System.out.println(emp emp);}
}
4.给idea配置代码模板
配置方式File | Settings | Editor | Live Templates ?xml version1.0 encodingUTF-8 ?
!DOCTYPE mapperPUBLIC -//mybatis.org//DTD Mapper 3.0//ENhttp://mybatis.org/dtd/mybatis-3-mapper.dtd
mapper namespace$namespace$$END$
/mapper 五、Mybatis的动态SQL【重点】
1. 动态SQL介绍
当进行多条件搜索时搜索条件通常是不确定的导致SQL语句的条件也是不确定的需要根据条件来确定要拼接哪些查询条件。这样的SQL语句就是所谓的动态SQL
Mybatis提供了一些xml的标签用于实现动态SQL语句 if标签用于判断 where标签用于代替where关键字 set标签用于代替set关键字 foreach标签用于循环遍历 sql标签和include标签用于抽取重用sql片段
2. if标签和where标签
if标签用于进行判断。如果判断为true标签里的sql才会生效
if test判断条件 如果判断为true这里的内容才会生效 /if
where标签用于代替where关键字它可以帮我们处理多余的and和or还有处理我们的空集合不是null
演示
Mapper接口 /*** 动态SQL根据条件查询员工。根据name和gender动态查询*/ListEmp searchEmp1(String name, Integer gender);
XML映射
!--if标签用于判断语法if test判断条件表达式如果判断为true这里的内容将会生效/if判断条件表达式其实使用的是OGNL的表达式语法名称取对应参数的值。#{}是怎么取参数值的这里也怎么取参数值判断运算, , , , , !逻辑运算, ||, ! 或者 and or not调用参数的属性或者方法where标签用于代替where关键字还会帮我们处理掉SQL语句里多余的and关键字使用了where标签之后建议给所有的条件前边都加上and--select idsearchEmp1 resultTypecom.itheima.pojo.Empselect * from empwhere!-- 如果参数name值非空 并且不是空串就添加上name的条件--if testname!null and name.length()0and name like concat(%,#{name}, %)/if!-- 如果参数gender非空就添加上gender的条件 --if testgender!nulland gender #{gender}/if/where/select
3. set标签
set标签用于代替update语句里的set关键字可以帮我们处理多余的逗号
Mapper
void update(Emp emp);
XML映射
!--
set标签用于代替update语句里的set关键字可以帮我们处理掉多余的,逗号把所有要修改的字段sql片段都写到set标签里边
--
update idupdateupdate empsetif testusername!null and username.length()0username#{username},/ifif testpassword!null and password.length()0password #{password},/ifif testname!null and name.length()0name #{name},/ifif testgender!nullgender #{gender},/ifif testimage!null and image.length()0image #{image},/ifif testentrydate!nullentrydate #{entrydate},/ifif testdeptId!nulldept_id #{deptId},/ifif testupdateTime!nullupdate_time #{updateTime}/if/setwhere id #{id}
/update
4. foreach标签
foreach标签用于循环遍历比如我们的批量删除多个数据
Mapper
void batchDelete(ListInteger ids);
XML映射
!--
foreach标签collection被循环的集合或数组item定义一个变量名通过这个变量名可以获取集合或数组里的每个值separator拼接每个值时候使用的分隔符open拼接结果的前缀部分close拼接结果的后缀部分
假如ids值是 1,2,3
循环拼接的结果是delete from emp where id in (1,2,3)(1,2,3)
for(Integer id:ids){}
--
delete idbatchDeletedelete from emp whereforeach collectionids openid in( itemid separator, close)#{id}/foreach
/delete
5. sql标签和include标签
sql标签定义一个sql片段
include标签引用一个sql片段
用法 如果多条SQL语句里有某些片段是完全相同的可以使用sql标签抽取出去需要使用时用include引用即可
!--定义一个SQL片段--
sql idselectEmpselect * from emp/sql!-- 引用一个SQL片段 --
select idqueryEmpListXml resultTypecom.itheima.pojo.Emp!--利用include标签引用select * from emp--include refidselectEmp/includewhere name like concat(%,#{name}, %)and gender #{gender}and entrydate between #{begin} and #{end}
/select