需求:查询name中包含"精"的数据.并且按照年龄降序排列
@Test
public void test9(){
SqlSession sqlSession = sqlSessionFactory.openSession(true);
DemoUserMapper mapper = sqlSession.getMapper(DemoUserMapper.class);
Map map=new HashMap<>();
map.put("name","精");
map.put("column","age");
List demoUsers=mapper.like(map);
System.out.println(demoUsers);
}
①$方式
select * from demo_user where name like '%${name}%' order by ${column} desc ;
②%需要引号包裹
这里只展示两种,方式很多
1.2批量查询注意事项:MyBatis中的sql最好小写,因为不同的系统对于大小写不敏感
转大小写快捷键:ctrl+shift+u
需求:将name为小乔/大乔/王昭君的年龄改为25岁,性别男
代码实现
@Test
public void test11(){
SqlSession sqlSession = sqlSessionFactory.openSession(true);
DemoUserMapper mapper = sqlSession.getMapper(DemoUserMapper.class);
List list=new ArrayList();
list.add("小乔");
list.add("大乔");
list.add("王昭君");
Map map=new HashMap<>();
map.put("names", list);
map.put("age", 25);
map.put("sex", "男");
mapper.update2(map);
}
update demo_user set age=#{age} ,sex=#{sex} where name in( #{name} )
void update2(Map2.优化配置 2.1别名map);
以上操作太麻烦,解决方案有三种
方式一:在核心配置文件mybatis-config.xml文件中配置别名标签实现代码:
mysql-config.xml文件配置内容
mapper映射文件中sql语句内容
注意:核心配置文件的顺序
The content of element type "configuration" must match "(properties?,settings?,typeAliases?,typeHandlers?,objectFactory?,objectWrapperFactory?,reflectorFactory?,plugins?,environments?,databaseIdProvider?,mappers?)".方式二:使用别名包
一个个编辑别名标签也很麻烦,别名标签只对某个类有效,所以可以在配置文件中配置package标签,配置包路径
原理是动态拼接:包路径+.类名
方式三:使用注解@Alias("类的别名") 不常用
2.2简化sql标签 sql标签用法
select * from demo_user
where id=#{id}
sql标签的利弊
3.MyBatis动态sql 3.1 IF-WHERe标签利: 弊:
1.节省xml文件的大小 1.sql只能抽取公共的sql语句,局限性大
2.代码结构相对简单 2.如果大量使用sql标签,可读性太差
3.2 SET标签规则:where与if标签通常一起使用,where标签可以去除多余的and和or,if的test属性为判断条件
判断对象中不为空的属性当作where条件
情景:用户并不是上传所有字段属性值,可能只有name,只有age
规则:判断对象中不为空的属性当作set条件,set标签可以把多余的逗号去除
情景:用户并不是修改所有字段属性值,可能只有name,只有age
3.3 Sql-choose when otherwiseupdate demo_user where id=#{id} name=#{name}, age=#{age} sex=#{sex}
需求:条件查询,如果有name那么按照name查询,如果没有,按照sex查询
MyBatis的分支结构
3.4 ResuletType与ResultMap解释:
choose代表分支结构,只有一个条件有效
when:和if类似
otherwise:上述的条件无效时,此处条件生效
建表→编辑Dept pojo类→mapper接口→映射文件→配置核心配置文件中的mapper 注意pojo类要实现序列化接口
resultType注意,结果集中的字段名称与属性名称一致时,才会实现自动的数据封装
resultMap,结果集中的字段名称与属性名称不一致时,也可以实现自定义的数据封装
resultMap标签用来自定义映射关系
建表(dept)
pojo类
package com.jt.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import java.io.Serializable;
@Data
@Accessors(chain = true)
@NoArgsConstructor
@AllArgsConstructor
public class Dept implements Serializable {
private Integer deptId;
private String deptName;
}
mapper接口
public interface DeptMapper {
List findAll(Dept dept);
}
映射文件
test类
public class TestMybatis {
SqlSessionFactory sqlSessionFactory;
@Test
@BeforeEach
public void init() throws IOException {
//1.指定资源文件
String resource="mybatis/mybatis-config.xml";
InputStream inputstream = Resources.getResourceAsStream(resource);
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputstream);
}
@Test
public void test1(){
SqlSession sqlSession = sqlSessionFactory.openSession(true);
DeptMapper mapper = sqlSession.getMapper(DeptMapper.class);
Dept dept= new Dept();
List list=mapper.findAll(dept);
System.out.println(list);
sqlSession.close();
}
4.关联关系
4.1常见关联关系
一对一 、一对多、多对一、多对多
4.2 一对一规则:一对一封装为对象,一对多封装成List
建表→编辑Emp pojo类→mapper接口→映射文件→配置核心配置文件中的mapper 注意pojo类要实现序列化接口4.2.1准备工作
建表(emp)
pojo类
@Data
@Accessors(chain = true)
@NoArgsConstructor
@AllArgsConstructor
public class Emp implements Serializable{
private Integer id;
private String name;
private Integer age;
//private Integer deptId;
private Dept dept;//一个员工对应一个部门
}
映射文件
核心配置文件
需求:查询员工表的id,name,age,dept_id
测试代码
@Test
public void oneToOne(){
SqlSession sqlSession = sqlSessionFactory.openSession(true);
EmpMapper mapper = sqlSession.getMapper(EmpMapper.class);
Emp emp= new Emp();
List list=mapper.findAll(emp);
System.out.println(list);
sqlSession.close();
}
sql语句
结果:
[Emp(id=1, name=妲己, age=18, dept=null), Emp(id=2, name=貂蝉, age=19, dept=null), Emp(id=3, name=八戒, age=99, dept=null)]
会发现员工的部门为空
思路:将两张表建立连接,最好使用连接left join
sql语句实现两表联查:SELECT * FROM emp LEFT JOIN dept ON emp.dept_id=dept.dept_id;
问题:有重名字段
解决方案:不要查询*全部 查询字段
实现方式一:关联查询实现一对一封装规则:Mybatis要求实现数据封装时,要求字段唯一
resultMap标签最好保留主键字段信息
使用标签association封装单个对象
遇到关联封装时,要全部配置映射关系,但是太麻烦,如果字段与属性名相同,可以使用autoMapping
映射文件代码
实现方式二:子查询实现一对一封装select e.id,e.name,e.age,d.dept_id,d.dept_name from emp e , dept d where e.dept_id=d.dept_id
子查询sql简单,封装复杂;关联查询sql复杂,封装简单
实现代码:
4.3一对多
关系:一个部门对应多个员工
连接查询实现一对多封装思路→实现多表联查
SELECT d.dept_id,d.dept_name,e.id,e.name,e.age FROM emp e LEFT JOIN dept d ON e.dept_id=d.dept_id
实现代码:
@Test
public void test4(){
SqlSession sqlSession = sqlSessionFactory.openSession(true);
DeptMapper mapper = sqlSession.getMapper(DeptMapper.class);
Dept dept=new Dept();
List list=mapper.findAll2(dept);
System.out.println(list);
sqlSession.close();
}
select d.dept_id,d.dept_name,e.id,e.name,e.age from emp e left join dept d on e.dept_id=d.dept_id
4.4驼峰规则映射与一对一区分开,一对一使用association标签,内部使用JavaType属性,一对多使用collection标签,内部使用ofType属性其余结构相同
在核心配置文件内配置settings
实现代码:
注意:要使用autoMapping属性+最好保留属性



