网页制作与网站建设实战教程,squarespace wordpress,制作动画片软件,中国政务网站建设绩效评估目录 一、MyBatis的各种查询功能1.1 查询一个实体类对象1.2 查询一个List集合1.3 查询单个数据1.4 查询一条数据为map集合1.5 查询多条数据为map集合1.5.1 方法一#xff1a;1.5.2 方法二#xff1a; 二、特殊SQL的执行2.1 模糊查询2.2 批量删除2.3 动态设置表名2.4 添加功能… 目录 一、MyBatis的各种查询功能1.1 查询一个实体类对象1.2 查询一个List集合1.3 查询单个数据1.4 查询一条数据为map集合1.5 查询多条数据为map集合1.5.1 方法一1.5.2 方法二 二、特殊SQL的执行2.1 模糊查询2.2 批量删除2.3 动态设置表名2.4 添加功能获取自增的主键 三、自定义映射resultMap3.1 多对一映射处理3.2 一对多映射处理3.3 延迟加载 四、动态SQL4.1 if4.2 where4.3 trim4.4 choose、when、otherwise4.5 foreach4.6 SQL片段 一、MyBatis的各种查询功能
如果查询出的数据只有一条可以通过 实体类对象接收List集合接收Map集合接收结果{password123456, sex男, id1, age23, usernameadmin} 如果查询出的数据有多条一定不能用实体类对象接收会抛异常TooManyResultsException可以通过 实体类类型的LIst集合接收Map类型的LIst集合接收在mapper接口的方法上添加MapKey注解
1.1 查询一个实体类对象
/**
* 根据用户id查询用户信息
* param id
* return
*/
User getUserById(Param(id) int id);!--User getUserById(Param(id) int id);--
select idgetUserById resultTypeUserselect * from t_user where id #{id}
/select1.2 查询一个List集合
/*** 查询所有用户信息* return*/
ListUser getUserList();!--ListUser getUserList();--
select idgetUserList resultTypeUserselect * from t_user
/select1.3 查询单个数据
/** * 查询用户的总记录数 * return * 在MyBatis中对于Java中常用的类型都设置了类型别名 * 例如java.lang.Integer--int|integer * 例如int--_int|_integer * 例如Map--map,List--list */
int getCount();!--int getCount();--
select idgetCount resultType_integerselect count(id) from t_user
/select1.4 查询一条数据为map集合
/** * 根据用户id查询用户信息为map集合 * param id * return */
MapString, Object getUserToMap(Param(id) int id);!--MapString, Object getUserToMap(Param(id) int id);--
select idgetUserToMap resultTypemapselect * from t_user where id #{id}
/select
!--结果{password123456, sex男, id1, age23, usernameadmin}--1.5 查询多条数据为map集合
1.5.1 方法一
/** * 查询所有用户信息为map集合 * return * 将表中的数据以map集合的方式查询一条数据对应一个map若有多条数据就会产生多个map集合此时可以将这些map放在一个list集合中获取 */
ListMapString, Object getAllUserToMap();!--MapString, Object getAllUserToMap();--
select idgetAllUserToMap resultTypemap select * from t_user
/select
!--结果[{password123456, sex男, id1, age23, usernameadmin},{password123456, sex男, id2, age23, username张三},{password123456, sex男, id3, age23, username张三}]
--1.5.2 方法二
/*** 查询所有用户信息为map集合* return* 将表中的数据以map集合的方式查询一条数据对应一个map若有多条数据就会产生多个map集合并且最终要以一个map的方式返回数据此时需要通过MapKey注解设置map集合的键值是每条数据所对应的map集合*/
MapKey(id)
MapString, Object getAllUserToMap();!--MapString, Object getAllUserToMap();--
select idgetAllUserToMap resultTypemapselect * from t_user
/select
!--结果{1{password123456, sex男, id1, age23, usernameadmin},2{password123456, sex男, id2, age23, username张三},3{password123456, sex男, id3, age23, username张三}}
--二、特殊SQL的执行
2.1 模糊查询
/*** 根据用户名进行模糊查询* param username * date 2022/2/26 21:56*/
ListUser getUserByLike(Param(username) String username);!--ListUser getUserByLike(Param(username) String username);--
select idgetUserByLike resultTypeUser!--select * from t_user where username like %${mohu}%-- !--select * from t_user where username like concat(%,#{mohu},%)-- select * from t_user where username like %#{mohu}%
/select其中select * from t_user where username like “%”#{mohu}%是最常用的 2.2 批量删除
只能使用${}如果使用#{}则解析后的sql语句为delete from t_user where id in (‘1,2,3’)这样是将1,2,3看做是一个整体只有id为1,2,3的数据会被删除。正确的语句应该是delete from t_user where id in (1,2,3)或者delete from t_user where id in (‘1’,‘2’,‘3’)
/*** 根据id批量删除* param ids * return int* date 2022/2/26 22:06*/
int deleteMore(Param(ids) String ids);delete iddeleteMoredelete from t_user where id in (${ids})
/delete//测试类
Test
public void deleteMore() {SqlSession sqlSession SqlSessionUtils.getSqlSession();SQLMapper mapper sqlSession.getMapper(SQLMapper.class);int result mapper.deleteMore(1,2,3,8);System.out.println(result);
}2.3 动态设置表名
只能使用${}因为表名不能加单引号
/*** 查询指定表中的数据* param tableName */
ListUser getUserByTable(Param(tableName) String tableName);!--ListUser getUserByTable(Param(tableName) String tableName);--
select idgetUserByTable resultTypeUserselect * from ${tableName}
/select2.4 添加功能获取自增的主键
使用场景 t_clazz(clazz_id,clazz_name)t_student(student_id,student_name,clazz_id) 添加班级信息获取新添加的班级的id为班级分配学生即将某学生班级id修改为新添加的班级的id 在mapper.xml中设置两个属性 useGeneratedKeys设置使用自增的主键keyProperty因为增删改有统一的返回值是受影响的行数因此只能将获取的自增的主键放在传输的参数user对象的某个属性中指定实体类中的哪个变量接收自增id
/*** 添加用户信息* param user * date 2022/2/27 15:04*/
void insertUser(User user);!--void insertUser(User user);--
insert idinsertUser useGeneratedKeystrue keyPropertyidinsert into t_user values (null,#{username},#{password},#{age},#{sex},#{email})
/insert//测试类
Test
public void insertUser() {SqlSession sqlSession SqlSessionUtils.getSqlSession();SQLMapper mapper sqlSession.getMapper(SQLMapper.class);User user new User(null, ton, 123, 23, 男, 123321.com);mapper.insertUser(user);System.out.println(user);//输出user{id10, usernameton, password123, age23, sex男, email123321.com}自增主键存放到了user的id属性中
}三、自定义映射resultMap
resultMap处理字段和属性的映射关系
resultMap设置自定义映射 属性 id表示自定义映射的唯一标识不能重复type查询的数据要映射的实体类的类型 子标签 id设置主键的映射关系result设置普通字段的映射关系子标签属性 property设置映射关系中实体类中的属性名column设置映射关系中表中的字段名 若字段名和实体类中的属性名不一致则可以通过resultMap设置自定义映射即使字段名和属性名一致的属性也要映射也就是全部属性都要列出来
resultMap idempResultMap typeEmpid propertyeid columneid/idresult propertyempName columnemp_name/resultresult propertyage columnage/resultresult propertysex columnsex/resultresult propertyemail columnemail/result
/resultMap
!--ListEmp getAllEmp();--
select idgetAllEmp resultMapempResultMapselect * from t_emp
/select若字段名和实体类中的属性名不一致但是字段名符合数据库的规则使用_实体类中的属性名符合Java的规则使用驼峰。此时也可通过以下两种方式处理字段名和实体类中的属性的映射关系 .
可以通过为字段起别名的方式保证和实体类中的属性名保持一致
!--ListEmp getAllEmp();--
select idgetAllEmp resultTypeEmpselect eid,emp_name empName,age,sex,email from t_emp
/select可以在MyBatis的核心配置文件中的setting标签中设置一个全局配置信息mapUnderscoreToCamelCase可以在查询表中数据时自动将_类型的字段名转换为驼峰例如字段名user_name设置了mapUnderscoreToCamelCase此时字段名就会转换为userName。
settingssetting namemapUnderscoreToCamelCase valuetrue/
/settings3.1 多对一映射处理 查询员工信息以及员工所对应的部门信息 public class Emp { private Integer eid; private String empName; private Integer age; private String sex; private String email; private Dept dept;//...构造器、get、set方法等
}第一种方法级联方式处理映射关系
resultMap idempAndDeptResultMapOne typeEmpid propertyeid columneid/idresult propertyempName columnemp_name/resultresult propertyage columnage/resultresult propertysex columnsex/resultresult propertyemail columnemail/resultresult propertydept.did columndid/resultresult propertydept.deptName columndept_name/result
/resultMap
!--Emp getEmpAndDept(Param(eid)Integer eid);--
select idgetEmpAndDept resultMapempAndDeptResultMapOneselect * from t_emp left join t_dept on t_emp.eid t_dept.did where t_emp.eid #{eid}
/select第二种方法使用association处理映射关系
association处理多对一的映射关系property需要处理多对的映射关系的属性名javaType该属性的类型
resultMap idempAndDeptResultMapTwo typeEmpid propertyeid columneid/idresult propertyempName columnemp_name/resultresult propertyage columnage/resultresult propertysex columnsex/resultresult propertyemail columnemail/resultassociation propertydept javaTypeDeptid propertydid columndid/idresult propertydeptName columndept_name/result/association
/resultMap
!--Emp getEmpAndDept(Param(eid)Integer eid);--
select idgetEmpAndDept resultMapempAndDeptResultMapTwoselect * from t_emp left join t_dept on t_emp.eid t_dept.did where t_emp.eid #{eid}
/select第三种方法分步查询
查询员工信息 select设置分布查询的sql的唯一标识namespace.SQLId或mapper接口的全类名.方法名 column设置分步查询的条件
//EmpMapper里的方法
/*** 通过分步查询员工及所对应的部门信息* 分步查询第一步查询员工信息* param */
Emp getEmpAndDeptByStepOne(Param(eid) Integer eid);resultMap idempAndDeptByStepResultMap typeEmpid propertyeid columneid/idresult propertyempName columnemp_name/resultresult propertyage columnage/resultresult propertysex columnsex/resultresult propertyemail columnemail/resultassociation propertydeptselectcom.lx.mybatis.mapper.DeptMapper.getEmpAndDeptByStepTwocolumndid/association
/resultMap
!--Emp getEmpAndDeptByStepOne(Param(eid) Integer eid);--
select idgetEmpAndDeptByStepOne resultMapempAndDeptByStepResultMapselect * from t_emp where eid #{eid}
/select2.查询部门信息
//DeptMapper里的方法
/*** 通过分步查询员工及所对应的部门信息* 分步查询第二步通过did查询员工对应的部门信息* param*/
Dept getEmpAndDeptByStepTwo(Param(did) Integer did);!--此处的resultMap仅是处理字段和属性的映射关系--
resultMap idEmpAndDeptByStepTwoResultMap typeDeptid propertydid columndid/idresult propertydeptName columndept_name/result
/resultMap
!--Dept getEmpAndDeptByStepTwo(Param(did) Integer did);--
select idgetEmpAndDeptByStepTwo resultMapEmpAndDeptByStepTwoResultMapselect * from t_dept where did #{did}
/select3.2 一对多映射处理
public class Dept {private Integer did;private String deptName;private ListEmp emps;//...构造器、get、set方法等
}javacollection collection用来处理一对多的映射关系ofType表示该属性对应的集合中存储的数据的类型 resultMap idDeptAndEmpResultMap typeDeptid propertydid columndid/idresult propertydeptName columndept_name/resultcollection propertyemps ofTypeEmpid propertyeid columneid/idresult propertyempName columnemp_name/resultresult propertyage columnage/resultresult propertysex columnsex/resultresult propertyemail columnemail/result/collection
/resultMap
!--Dept getDeptAndEmp(Param(did) Integer did);--
select idgetDeptAndEmp resultMapDeptAndEmpResultMapselect * from t_dept left join t_emp on t_dept.did t_emp.did where t_dept.did #{did}
/select分步查询 1.查询部门信息
/*** 通过分步查询查询部门及对应的所有员工信息* 分步查询第一步查询部门信息* param did */
Dept getDeptAndEmpByStepOne(Param(did) Integer did);resultMap idDeptAndEmpByStepOneResultMap typeDeptid propertydid columndid/idresult propertydeptName columndept_name/resultcollection propertyempsselectcom.lx.mybatis.mapper.EmpMapper.getDeptAndEmpByStepTwocolumndid/collection
/resultMap
!--Dept getDeptAndEmpByStepOne(Param(did) Integer did);--
select idgetDeptAndEmpByStepOne resultMapDeptAndEmpByStepOneResultMapselect * from t_dept where did #{did}
/select2.根据部门id查询部门中的所有员工
/*** 通过分步查询查询部门及对应的所有员工信息* 分步查询第二步根据部门id查询部门中的所有员工* param did*/
ListEmp getDeptAndEmpByStepTwo(Param(did) Integer did);!--ListEmp getDeptAndEmpByStepTwo(Param(did) Integer did);--
select idgetDeptAndEmpByStepTwo resultTypeEmpselect * from t_emp where did #{did}
/select3.3 延迟加载
分步查询的优点可以实现延迟加载但是必须在核心配置文件中设置全局配置信息 lazyLoadingEnabled延迟加载的全局开关。当开启时所有关联对象都会延迟加载aggressiveLazyLoading当开启时任何方法的调用都会加载该对象的所有属性。 否则每个属性会按需加载 此时就可以实现按需加载获取的数据是什么就只会执行相应的sql。此时可通过association和collection中的fetchType属性设置当前的分步查询是否使用延迟加载fetchType“lazy(延迟加载)|eager(立即加载)”
settings!--开启延迟加载--setting namelazyLoadingEnabled valuetrue/
/settingsTest
public void getEmpAndDeptByStepOne() {SqlSession sqlSession SqlSessionUtils.getSqlSession();EmpMapper mapper sqlSession.getMapper(EmpMapper.class);Emp emp mapper.getEmpAndDeptByStepOne(1);System.out.println(emp.getEmpName());
}关闭延迟加载两条SQL语句都运行了 开启延迟加载只运行获取emp的SQL语句 fetchType当开启了全局的延迟加载之后可以通过该属性手动控制延迟加载的效果fetchType“lazy(延迟加载)|eager(立即加载)”
resultMap idempAndDeptByStepResultMap typeEmpid propertyeid columneid/idresult propertyempName columnemp_name/resultresult propertyage columnage/resultresult propertysex columnsex/resultresult propertyemail columnemail/resultassociation propertydeptselectcom.atguigu.mybatis.mapper.DeptMapper.getEmpAndDeptByStepTwocolumndidfetchTypelazy/association
/resultMap四、动态SQL
Mybatis框架的动态SQL技术是一种根据特定条件动态拼装SQL语句的功能它存在的意义是为了解决拼接SQL语句字符串时的痛点问题
4.1 if
if标签可通过test属性即传递过来的数据的表达式进行判断若表达式的结果为true则标签中的内容会执行反之标签中的内容不会执行在where后面添加一个恒成立条件11 这个恒成立条件并不会影响查询的结果这个11可以用来拼接and语句例如当empName为null时 如果不加上恒成立条件则SQL语句为select * from t_emp where and age ? and sex ? and email ?此时where会与and连用SQL语句会报错如果加上一个恒成立条件则SQL语句为select * from t_emp where 1 1 and age ? and sex ? and email ?此时不报错
!--ListEmp getEmpByCondition(Emp emp);--
select idgetEmpByCondition resultTypeEmpselect * from t_emp where 11if testempName ! null and empName !and emp_name #{empName}/ifif testage ! null and age !and age #{age}/ifif testsex ! null and sex !and sex #{sex}/ifif testemail ! null and email !and email #{email}/if
/select4.2 where
where和if一般结合使用
若where标签中的if条件都不满足则where标签没有任何功能即不会添加where关键字若where标签中的if条件满足则where标签会自动添加where关键字并将条件最前方多余的and/or去掉
!--ListEmp getEmpByCondition(Emp emp);--
select idgetEmpByCondition resultTypeEmpselect * from t_empwhereif testempName ! null and empName !emp_name #{empName}/ifif testage ! null and age !and age #{age}/ifif testsex ! null and sex !and sex #{sex}/ifif testemail ! null and email !and email #{email}/if/where
/select注意where标签不能去掉条件后多余的and/or !--这种用法是错误的只能去掉条件前面的and/or条件后面的不行--
if testempName ! null and empName !emp_name #{empName} and
/if
if testage ! null and age !age #{age}
/if4.3 trim
trim用于去掉或添加标签中的内容常用属性 prefix在trim标签中的内容的前面添加某些内容suffix在trim标签中的内容的后面添加某些内容prefixOverrides在trim标签中的内容的前面去掉某些内容suffixOverrides在trim标签中的内容的后面去掉某些内容 若trim中的标签都不满足条件则trim标签没有任何效果也就是只剩下select * from t_emp
!--ListEmp getEmpByCondition(Emp emp);--
select idgetEmpByCondition resultTypeEmpselect * from t_emptrim prefixwhere suffixOverridesand|orif testempName ! null and empName !emp_name #{empName} and/ifif testage ! null and age !age #{age} and/ifif testsex ! null and sex !sex #{sex} or/ifif testemail ! null and email !email #{email}/if/trim
/select//测试类
Test
public void getEmpByCondition() {SqlSession sqlSession SqlSessionUtils.getSqlSession();DynamicSQLMapper mapper sqlSession.getMapper(DynamicSQLMapper.class);ListEmp emps mapper.getEmpByCondition(new Emp(null, 张三, null, null, null, null));System.out.println(emps);
}4.4 choose、when、otherwise
choose、when、otherwise相当于if…else if…elsewhen至少要有一个otherwise至多只有一个
select idgetEmpByChoose resultTypeEmpselect * from t_empwherechoosewhen testempName ! null and empName ! emp_name #{empName}/whenwhen testage ! null and age ! age #{age}/whenwhen testsex ! null and sex ! sex #{sex}/whenwhen testemail ! null and email ! email #{email}/whenotherwisedid 1/otherwise/choose/where
/selectTest
public void getEmpByChoose() {SqlSession sqlSession SqlSessionUtils.getSqlSession();DynamicSQLMapper mapper sqlSession.getMapper(DynamicSQLMapper.class);ListEmp emps mapper.getEmpByChoose(new Emp(null, 张三, 23, 男, 123qq.com, null));System.out.println(emps);
}只要满足一个when条件后面的when就不会再判断了。
4.5 foreach
属性 collection设置要循环的数组或集合item表示集合或数组中的每一个数据separator设置循环体之间的分隔符分隔符前后默认有一个空格如,open设置foreach标签中的内容的开始符close设置foreach标签中的内容的结束符 批量删除
!--int deleteMoreByArray(Integer[] eids);--
delete iddeleteMoreByArraydelete from t_emp where eid inforeach collectioneids itemeid separator, open( close)#{eid}/foreach
/deleteTest
public void deleteMoreByArray() {SqlSession sqlSession SqlSessionUtils.getSqlSession();DynamicSQLMapper mapper sqlSession.getMapper(DynamicSQLMapper.class);int result mapper.deleteMoreByArray(new Integer[]{6, 7, 8, 9});System.out.println(result);
}批量添加
!--int insertMoreByList(Param(emps) ListEmp emps);--
insert idinsertMoreByListinsert into t_emp valuesforeach collectionemps itememp separator,(null,#{emp.empName},#{emp.age},#{emp.sex},#{emp.email},null)/foreach
/insertTest
public void insertMoreByList() {SqlSession sqlSession SqlSessionUtils.getSqlSession();DynamicSQLMapper mapper sqlSession.getMapper(DynamicSQLMapper.class);Emp emp1 new Emp(null,a,1,男,123321.com,null);Emp emp2 new Emp(null,b,1,男,123321.com,null);Emp emp3 new Emp(null,c,1,男,123321.com,null);ListEmp emps Arrays.asList(emp1, emp2, emp3);int result mapper.insertMoreByList(emps);System.out.println(result);
}4.6 SQL片段
sql片段可以记录一段公共sql片段在使用的地方通过include标签进行引入声明sql片段sql标签
sql idempColumnseid,emp_name,age,sex,email/sql引用sql片段include标签
!--ListEmp getEmpByCondition(Emp emp);--
select idgetEmpByCondition resultTypeEmpselect include refidempColumns/include from t_emp
/select