CGB2107-Day04-mybatis高级用法
1. Mybatis作业
1.1 模糊查询
1.1.1编辑测试类
/*
Mybatis作业:
需求: 查询name中包含"精"的数据.并且按照年龄降序排列
*/
@Test
public void findLike(){
SqlSession sqlSession = sqlSessionFactory.openSession(true);
DemoUserMapper demoUserMapper = sqlSession.getMapper(DemoUserMapper.class);
//String name = "精";
String name = "%精%";
List<DemoUser> list = demoUserMapper.findLike(name);
System.out.println(list);
sqlSession.close();
}
1.1.2 编辑xml映射文件
<!--关于模糊查询的说明: 使用%号需要使用""号包裹.
注意事项: mybatis中的sql 最好小写. 因为不同的系统对于大小写 不敏感.
键位: eclipse ctrl + shift + y 小写
ctrl + shift + u 大写/小写
-->
<select id="findLike" resultType="com.jt.pojo.DemoUser">
<!--select * from demo_user where name like "%"#{name}"%" order by age desc -->
select * from demo_user where name like #{name} order by age desc
</select>
1.2 批量更新操作
1.2.1 编辑测试方法
/**
* 作业2: 将name为小乔/大乔/王昭君的年龄改为18岁,性别女
*/
@Test
public void updateUser(){
SqlSession sqlSession = sqlSessionFactory.openSession(true);
DemoUserMapper demoUserMapper = sqlSession.getMapper(DemoUserMapper.class);
Map<String,Object> map = new HashMap<>();
String[] array = {"小乔","大乔","王昭君"};
map.put("names",array);
map.put("age",18);
map.put("sex","女");
demoUserMapper.updateUser(map);
sqlSession.close();
}
1.2.2 编辑xml映射文件
<!--批量更新操作-->
<update id="updateUser">
update demo_user set age = #{age},sex = #{sex}
where name in (
<foreach collection="names" item="name" separator=",">
#{name}
</foreach>
)
</update>
2. Mybatis优化设置
关于Mybatis 核心配置文件的顺序
The content of element type "configuration" must match "(properties?,settings?,typeAliases?,typeHandlers?,objectFactory?,objectWrapperFactory?,reflectorFactory?,plugins?,environments?,databaseIdProvider?,mappers?)".
2.1 mybatis简化-别名包
2.1.1 业务说明
在mybatis xml映射文件中需要写POJO实体对象的路径. 如果每次编辑都写全路径,则开发相对繁琐. 所以mybatis引入别名包的规则.
2.1.2 实现别名配置
在mybatis的核心配置文件中 定义别名
2.1.3 使用别名映射
2.1.4 使用别名包
需求: 如果项目中有多个POJO实体类,如果一个一个编辑别名标签,则更为繁琐. 所以Mybatis提供了别名包的功能.
例子:
com.jt.pojo.User,
com.jt.pojo.Dept,
com.jt.pojo.Order
原理说明: 可以设定公共的包路径 com.jt.pojo,如果设定了包路径.以后自动拼接类的全路径.
xml核心文件配置:
<!-- 配置别名 -->
<typeAliases>
<!--别名标签只对某个类有效.-->
<!--<typeAlias type="com.jt.pojo.DemoUser" alias="DemoUser"></typeAlias>-->
<!--package 指定的是包路径的信息.-->
<package name="com.jt.pojo"/>
</typeAliases>
xml映射文件配置:
<mapper namespace="com.jt.mapper.DemoUserMapper">
<!--映射原理:
如果配置文件中定义了包路径,则映射对象时会自动的完成路径的拼接
resultType="com.jt.pojo.DemoUser"
-->
<select id="findAll" resultType="DemoUser">
select id,name,age,sex from demo_user
</select>
</mapper>
2.1.5 别名的注解定义
2.2 Mybatis简化-Sql标签
2.2.1 业务说明
mybatis的xml映射文件中会有大量的Sql语句. 随着业务的增加,Sql语句的数量也会增加. 其中有部分**"Sql片段"则可能重复. 如果想简化Sql语句,则可以使用Sql标签**简化操作.
例子:
\1. select id,name,age,sex from demo_user where id = 1
\2. select id,name,age,sex from demo_user where name = xxx
2.2.2 sql标签用法
<!--2.简化Sql标签 -->
<sql id="demo_user_sql">
select id,name,age,sex from demo_user
</sql>
<!--include 代表包含Sql标签 -->
<select id="findAll" resultType="DemoUser">
<include refid="demo_user_sql"/>
</select>
2.2.3 关于Sql标签的说明
优势:
1.使用Sql标签可以节省xml的文件大小.
2.代码的结构相对简单.
弊端:
1.Sql只能抽取公共的Sql语句,局限性稍大.
2.如果大量的使用Sql标签,则代码的可读性差
3. Mybatis-动态Sql
3.1 IF-WHERE用法
3.1.1 业务需求
根据user对象查询数据.要求根据对象中不为null的属性充当where条件.实现动态的查询.
案例: 实际业务中经常出现多个查询条件 如图:
3.1.2 编辑测试类
/*
* 封装DemoUser的对象,根据对象中不为null的属性查询
* */
@Test
public void testFindWhere(){
SqlSession sqlSession = sqlSessionFactory.openSession();
DemoUserMapper demoUserMapper = sqlSession.getMapper(DemoUserMapper.class);
DemoUser demoUser = new DemoUser();
demoUser.setAge(3000);
List<DemoUser> list = demoUserMapper.findWhere(demoUser);
System.out.println(list);
sqlSession.close();
}
3.1.3 编辑xml映射文件
<!--动态Sql案例
思路: 如果数据不为null,mybatis才会当做条件
if标签说明:
test: 判断的条件 直接写属性即可
where标签: 去除条件中多余的 and 或者 or的
说明: if和 where 几乎一起出现.
-->
<select id="findWhere" resultType="DemoUser">
select id,name,age,sex from demo_user
<where>
<if test="name != null">name = #{name}</if>
<if test="age !=null"> and age=#{age}</if>
<if test="sex !=null"> and sex=#{sex}</if>
</where>
</select>
3.2 动态Sql-SET标签
3.2.1 编辑测试案例
/**
* 需求: 根据Id,动态的实现数据的更新.
*/
@Test
public void testUpdateSet(){
SqlSession sqlSession = sqlSessionFactory.openSession(true);
DemoUserMapper demoUserMapper = sqlSession.getMapper(DemoUserMapper.class);
DemoUser user = new DemoUser();
user.setId(1).setName("守山大使");
demoUserMapper.updateUser(user);
sqlSession.close();
}
3.2.2 编辑mapper接口
3.2.3 编辑xml映射文件
<!--
规则: 根据对象中不为null的属性当做set条件
set标签说明: 去除set条件中多余的 ,号
-->
<update id="updateUser">
update demo_user
<set>
<if test="name !=null">name = #{name},</if>
<if test="age !=null">age = #{age},</if>
<if test="sex !=null">sex = #{sex}</if>
</set>
where
id = #{id}
</update>
3.3 动态Sql-choose when otherwise
3.3.1 业务需求
根据条件实现数据的查询. 如果存在name则按照name查询,否则按照sex查询.
补充说明:
条件: name = “张三” , sex=“男”
select * from demo_user where name = #{name}
3.3.2 编辑测试类
/**
* 需求: 如果存在name则按照name查询,否则按照sex查询.
*/
@Test
public void testSelectChoose(){
SqlSession sqlSession = sqlSessionFactory.openSession(true);
DemoUserMapper demoUserMapper = sqlSession.getMapper(DemoUserMapper.class);
DemoUser user = new DemoUser();
user.setSex("男");
List<DemoUser> list = demoUserMapper.selectChoose(user);
System.out.println(list);
sqlSession.close();
}
3.3.3 编辑xml映射文件
<!--
需求: 如果不想将全部的条件当做if的判断.则mybatis提供了分支结构 switch
语法说明:
choose:代表分支结构,只有一个条件有效.
when: 指定判断的条件 和if类似.
otherwise: 如果上述的条件都不满足时,该行代码有效.
-->
<select id="selectChoose" resultType="DemoUser">
select * from demo_user
where
<choose>
<when test="name !=null">name = #{name}</when>
<otherwise>sex = #{sex}</otherwise>
</choose>
</select>
4 ResultMap
4.1 项目构建
4.1.1 创建表
- 创建dept表 int dept_id 主键自增, varchar类型(40) dept_name
4.1.2 编辑Dept POJO对象
@Data
@Accessors(chain = true)
@NoArgsConstructor
@AllArgsConstructor
public class Dept implements Serializable{
//驼峰命名规则
private Integer deptId;
private String deptName;
}
4.2 resultType与resultMap用法
4.2.1 标签说明
resultType说明:
当结果集中的字段名称,如果与属性的名称一致时,才会实现自动的数据封装
resultMap说明:
当结果集中的字段名称,与对象中的属性不一致时,可以使用resultMap实现自定义的封装.
4.2.2 编辑测试类
@Test
public void testFindDept(){
SqlSession sqlSession = sqlSessionFactory.openSession();
DeptMapper deptMapper = sqlSession.getMapper(DeptMapper.class);
List<Dept> list = deptMapper.findAll();
System.out.println(list);
sqlSession.close();
}
12345678
4.2.3 编辑业务接口
4.2.4 编辑xml映射文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.jt.mapper.DeptMapper">
<!--
ORM思想: 对象关系映射.
属性: deptId,deptName
字段: dept_id,dept_name
resultType说明:
当结果集中的字段名称,如果与属性的名称一致时,
才会实现自动的数据封装.
resultMap="" 自定义的封装数据的结构
-->
<select id="findAll" resultMap="deptRM">
select * from dept
</select>
<!--自定义映射关系的
语法:
1.id标签代表主键 (每张表中都会有一个主键)
1.1.column: 代表结果集中的字段.
1.2.property: 对象中的属性
2.result 除了主键之外的配置信息
-->
<resultMap id="deptRM" type="Dept">
<id column="dept_id" property="deptId"/>
<result column="dept_name" property="deptName"/>
</resultMap>
</mapper>
5. 关联关系
5.1 常见关联关系
- 一对一 例子: 1.人和身份证号 2. 老公和老婆 3. 员工和部门
- 一对多 例子: 一个部门对应多个员工.
- 多对多 老师和学生
一个老师对应多个学生.
一个学生对应多个老师.
核心: 考虑问题从一头出发.
5.2 一对一
5.2.1 创建表
表名: emp 员工表
字段: id,name,age,dept_id
表数据说明:
5.2.2 构建代码结构
5.2.2.1 创建POJO
@Data
@Accessors(chain = true)
@NoArgsConstructor
@AllArgsConstructor
public class Emp implements Serializable {
private Integer id;
private String name;
private Integer age;
private Integer deptId;
}
5.2.2.2 创建EmpMapper接口
5.2.2.3 创建EmpMapper.xml 映射文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.jt.mapper.EmpMapper">
</mapper>
5.2.2.4 mybatis加载xml映射文件
说明: 编辑mybatis-config.xml文件,添加映射文件.
5.2.3 一对一业务封装
规则: 如果对一 则使用对象封装.
如果对多 则使用List集合封装
总结
-
作业: 模糊查询的用法 “%”#{xxxx}"%", setName("%xxxx%")
-
如果遇到多值传参, 一般封装为Map集合. 1
-
mybatis-config.xml 文件的配置是有顺序的. 不能随意
-
别名写法 1.别名标签 2. 别名包 3. 注解
-
Sql标签 将公共的sql进行抽取 通过sql标签进行定义.
-
动态Sql where-if / set / choose when
-
resultMap用法: 解决字段与属性名称不一致的问题.
-
resultType: 单表查询时/属性与字段一样时,
-
关联关系的用法 一对一 一对多