MyBatis特殊操作、优化配置、动态SQL、关联查询

x33g5p2x  于2021-09-26 转载在 其他  
字(5.6k)|赞(0)|评价(0)|浏览(448)

1.特殊操作

1.1模糊查询

需求:查询name中包含"精"的数据.并且按照年龄降序排列

  1. @Test
  2. public void test9(){
  3. SqlSession sqlSession = sqlSessionFactory.openSession(true);
  4. DemoUserMapper mapper = sqlSession.getMapper(DemoUserMapper.class);
  5. Map<String,Object> map=new HashMap<>();
  6. map.put("name","精");
  7. map.put("column","age");
  8. List<DemoUser> demoUsers=mapper.like(map);
  9. System.out.println(demoUsers);
  10. }

①$方式

  1. <select id="like" resultType="com.jt.pojo.DemoUser">
  2. select * from demo_user where name like '%${name}%' order by ${column} desc ;
  3. </select>

②%需要引号包裹

  1. <select id="like" resultType="com.jt.pojo.DemoUser">
  2. select * from demo_user where name like "%"#{name}"%" order by ${column} desc ;
  3. </select>

*这里只展示两种,方式很多 *

注意事项:MyBatis中的sql最好小写,因为不同的系统对于大小写不敏感 

转大小写快捷键:ctrl+shift+u

1.2批量查询

需求:将name为小乔/大乔/王昭君的年龄改为25岁,性别男

代码实现

  1. @Test/*11.将name为小乔/大乔/王昭君的年龄改为18岁,性别男*/
  2. public void test11(){
  3. SqlSession sqlSession = sqlSessionFactory.openSession(true);
  4. DemoUserMapper mapper = sqlSession.getMapper(DemoUserMapper.class);
  5. List list=new ArrayList();
  6. list.add("小乔");
  7. list.add("大乔");
  8. list.add("王昭君");
  9. Map<String,Object> map=new HashMap<>();
  10. map.put("names", list);
  11. map.put("age", 25);
  12. map.put("sex", "男");
  13. mapper.update2(map);
  14. }
  1. <update id="update2">
  2. update demo_user set age=#{age} ,sex=#{sex} where name in(
  3. <foreach collection="names" item="name" separator=",">
  4. #{name}
  5. </foreach>
  6. )
  7. </update>
  1. void update2(Map<String, Object> map);

2.优化配置

2.1别名

以上操作太麻烦,解决方案有三种

方式一:在核心配置文件mybatis-config.xml文件中配置别名标签

实现代码

mysql-config.xml文件配置内容

  1. <!--配置别名-->
  2. <typeAliases >
  3. <typeAlias type="com.jt.pojo.DemoUser" alias="DemoUser"></typeAlias>
  4. </typeAliases>

** mapper映射文件中sql语句内容**

  1. <select id="find1" resultType="DemoUser">
  2. select * from demo_user where id=#{id}
  3. </select>

**注意:核心配置文件的顺序 **

  1. The content of element type "configuration" must match "(properties?,settings?,typeAliases?,typeHandlers?,objectFactory?,objectWrapperFactory?,reflectorFactory?,plugins?,environments?,databaseIdProvider?,mappers?)".

方式二:使用别名包

一个个编辑别名标签也很麻烦,别名标签只对某个类有效,所以可以在配置文件中配置package标签,配置包路径

  1. <typeAliases >
  2. <!--别名标签-->
  3. <!-- <typeAlias type="com.jt.pojo.DemoUser" alias="DemoUser"></typeAlias>-->
  4. <!--配置包路径-->
  5. <package name="com.jt.pojo"/>
  6. </typeAliases>

原理是动态拼接:包路径+.类名

方式三:使用注解

@Alias("类的别名")  不常用

2.2简化sql标签

sql标签用法

  1. <!--简化sql标签-->
  2. <sql id="demo_user_sql">
  3. select * from demo_user
  4. </sql>
  5. <select id="find1" resultType="DemoUser">
  6. <include refid="demo_user_sql"/>where id=#{id}
  7. </select>

sql标签的利弊

利: **                                         ** 弊:

1.节省xml文件的大小                 1.sql只能抽取公共的sql语句,局限性大

2.代码结构相对简单                   2.如果大量使用sql标签,可读性太差

3.MyBatis动态sql

3.1 IF-WHERE标签

规则:where与if标签通常一起使用,where标签可以去除多余的and和or,if的test属性为判断条件

         判断对象中不为空的属性当作where条件

情景:用户并不是上传所有字段属性值,可能只有name,只有age

  1. <select id="find2" resultType="DemoUser">
  2. select * from demo_user
  3. <where>
  4. <if test="name!=null"> name = #{name}</if>
  5. <if test="age !=null"> and age = #{age}</if>
  6. <if test="sex !=null"> and sex = #{sex}</if>
  7. </where>
  8. </select>

3.2 SET标签

规则:判断对象中不为空的属性当作set条件,set标签可以把多余的逗号去除 

情景:用户并不是修改所有字段属性值,可能只有name,只有age

  1. <update id="update">
  2. update demo_user
  3. <set>
  4. <if test="name !=null">name=#{name},</if>
  5. <if test="age !=null"> age=#{age}</if>
  6. <if test="sex !=null">sex=#{sex}</if>
  7. </set>
  8. where id=#{id}
  9. </update>

3.3 Sql-choose when otherwise

需求:条件查询,如果有name那么按照name查询,如果没有,按照sex查询

**MyBatis的分支结构 **

  1. <select id="find3" resultType="DemoUser">
  2. select * from demo_user
  3. where
  4. <choose>
  5. <when test="name!=null">name=#{name}</when>
  6. <otherwise>sex=#{sex}</otherwise>
  7. </choose>
  8. </select>

解释:

choose代表分支结构,只有一个条件有效

when:和if类似

otherwise:上述的条件无效时,此处条件生效

3.4 ResuletType与ResultMap

  1. 建表→编辑Dept pojo类→mapper接口→映射文件→配置核心配置文件中的mapper
  2. 注意pojo类要实现序列化接口

resultType注意,结果集中的字段名称与属性名称一致时,才会实现自动的数据封装

resultMap,结果集中的字段名称与属性名称不一致时,也可以实现自定义的数据封装

resultMap标签用来自定义映射关系

** 建表(dept)**

pojo类

  1. package com.jt.pojo;
  2. import lombok.AllArgsConstructor;
  3. import lombok.Data;
  4. import lombok.NoArgsConstructor;
  5. import lombok.experimental.Accessors;
  6. import java.io.Serializable;
  7. @Data
  8. @Accessors(chain = true)
  9. @NoArgsConstructor
  10. @AllArgsConstructor
  11. public class Dept implements Serializable {
  12. private Integer deptId;
  13. private String deptName;
  14. }

mapper接口

  1. public interface DeptMapper {
  2. List<Dept> findAll(Dept dept);
  3. }

** 映射文件**

  1. <select id="findAll" resultMap="deptDp">
  2. select * from dept
  3. </select>
  4. <resultMap id="deptDp" type="Dept">
  5. <id column="dept_id" property="deptId"/>
  6. <result column="dept_name" property="deptName"/>
  7. </resultMap>

test类

  1. public class TestMybatis {
  2. SqlSessionFactory sqlSessionFactory;
  3. @Test
  4. @BeforeEach
  5. public void init() throws IOException {
  6. //1.指定资源文件
  7. String resource="mybatis/mybatis-config.xml";
  8. InputStream inputstream = Resources.getResourceAsStream(resource);
  9. sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputstream);
  10. }
  11. @Test
  12. public void test1(){
  13. SqlSession sqlSession = sqlSessionFactory.openSession(true);
  14. DeptMapper mapper = sqlSession.getMapper(DeptMapper.class);
  15. Dept dept= new Dept();
  16. List<Dept> list=mapper.findAll(dept);
  17. System.out.println(list);
  18. sqlSession.close();
  19. }

4.关联关系

4.1常见关联关系

1.一对一 

2.一对多

3.多对一

4.多对多

4.2 一对一

规则:一对一封装为对象,一对多封装成List

  1. 建表→编辑Emp pojo类→mapper接口→映射文件→配置核心配置文件中的mapper
  2. 注意pojo类要实现序列化接口

相关文章