MyBatis动态SQL详解

MyBatis动态SQL详解,第1张

MyBatis动态SQL详解 一:MyBatis动态 sql 是?

1.动态 SQL 是 MyBatis 的强大特性之一。在 JDBC 或其它类似的框架中,开发人员通常需要手动拼接 SQL 语句。根据不同的条件拼接 SQL 语句是一件极其痛苦的工作。例如,拼接时要确保添加了必要的空格,还要注意去掉列表最后一个列名的逗号。而动态 SQL 恰好解决了这一问题,可以根据场景动态的构建查询

2.动态SQL:code that is executed dynamically。 它一般是根据用户输入或外部条件动态组合的SQL语句块。 动态SQL能灵活的发挥SQL强大的功能、方便的解决一些其它方法难以解决的问题。 相信使用过动态SQL的人都能体会到它带来的便利,然而动态SQL有时候在执行性能 (效率)上面不如静态SQL,而且使用不恰当,往往会在安全方面存在隐患 (SQL 注入式攻击)。

1.Mybatis 动态 sql 是做什么的?

Mybatis 动态 sql 可以让我们在 Xml 映射文件内,以标签的形式编写动态 sql,完成逻辑判断和动态拼接 sql 的功能。

2.Mybatis 的 9 种 动 态 sql 标 签有哪些?

 

元素作用备注if判断语句单条件分支判断choose(when、otherwise)相当于 Java 中的 switch case 语句多条件分支判断trim,where辅助元素用于处理一些SQL拼装问题foreach循环语句在in语句等列举条件常用bind辅助元素拼接参数

 

3.动态 sql 的执行原理?

原理为:使用 OGNL 从 sql 参数对象中计算表达式的值,根据表达式的值动态拼接 sql,以此来完成动态 sql 的功能。

二:MyBatis标签 1.if标签:条件判断

MyBatis if 类似于 Java 中的 if 语句,是 MyBatis 中最常用的判断语句。使用 if 标签可以节省许多拼接 SQL 的工作,把精力集中在 XML 的维护上。

(1)不使用动态sql

    
    select * from user where username=#{username} and sex=#{sex}

if 语句使用方法简单,常常与 test 属性联合使用。语法如下。

    SQL语句
(2)使用动态sql

上面的查询语句,我们可以发现,如果 #{username} 为空,那么查询结果也是空,如何解决这个问题呢?使用 if 来判断,可多个 if 语句同时使用。以下语句表示为可以按照网站名称(name)或者网址(url)进行模糊查询。如果您不输入名称或网址,则返回所有的网站记录。但是,如果你传递了任意一个参数,它就会返回与给定参数相匹配的记录。


            
            
                
                    sacc like concat('%' #{sacc} '%')
                
                
                    AND sname like concat('%' #{sname} '%')
                
                
                    AND sex=#{sex}
                
                
                    AND phone=#{phone}
                
            
        

这个“where”标签会知道如果它包含的标签中有返回值的话,它就插入一个‘where’。此外,如果标签返回的内容是以AND 或OR 开头的,则它会剔除掉。

 3.set标签

set可以用来修改

 


        update student
        
            sname=#{sname},
            spwd=#{spwd},
            sex=#{sex},
            phone=#{phone}
        sid=#{sid}
        
        where sid=#{sid}
    
 4.choose(when,otherwise) 语句

有时候,我们不想用到所有的查询条件,只想选择其中的一个,查询条件有一个满足即可,使用 choose 标签可以解决此类问题,类似于 Java 的 switch 语句

 


     WHERe sid in
    
        #{ids}
    

//批量删除

    delete  from  student  where  sid in
    
        #{ids}
    

整合案例

xml




    
        select  *  from  student
    
    
    
        
    
​
    
​
        
​
    
        update student
        
            sname=#{sname},
            spwd=#{spwd},
            sex=#{sex},
            phone=#{phone}
        sid=#{sid}
        
        where sid=#{sid}
    
​
    
        insert  into student
        
            sname,
            spwd,
            sex,
            phone,
        
​
        
            #{sname},
            #{spwd},
            #{sex},
            #{phone}
        
​
    
    
​
    
        delete  from  student  where  sid in
        
            #{ids}
        
    
​
​
​

测试类:

package com.yzx.test;
​
import com.yzx.entity.Student;
import com.yzx.mapper.StuMapper;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
​
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
​
public class StuTest {
    SqlSession sqlSession=null;
    InputStream is=null;
​
    @Before
    public   void  before() throws IOException {
        //1.读取核心配置文件
        is= Resources.getResourceAsStream("sqlMapperConfig.xml");
        //2.拿到工厂构建类
        SqlSessionFactoryBuilder sqlSessionFactoryBuilder=new SqlSessionFactoryBuilder();
        //3.拿到具体工厂
        SqlSessionFactory build=sqlSessionFactoryBuilder.build(is);
        //4.拿到session
        sqlSession = build.openSession();
    }
​
    @After
    public  void  after(){
        //7,提交事务
        sqlSession.commit();
        //8.关闭资源
        sqlSession.close();
        if(is!=null){
            try {
                is.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        };
    }
​
    //查询所有
    @Test
    public  void  find(){
        //5.获取具体的mapper接口
        StuMapper mapper=sqlSession.getMapper(StuMapper.class);
        //6.调用执行
        List list=mapper.find();
        list.forEach(a-> System.out.println(a));
    }
    //查询单个
    @Test
    public  void  findbyid(){
​
        StuMapper mapper=sqlSession.getMapper(StuMapper.class);
        List list=mapper.findbyid(2);
        list.forEach(a-> System.out.println(a));
    }
    //模糊查询
    @Test
    public  void  findQuery(){
​
        StuMapper mapper=sqlSession.getMapper(StuMapper.class);
​
        Student  stu=new Student();
        stu.setSname("小");
        stu.setSex("男");
        List list=mapper.findQuery(stu);
        list.forEach(a-> System.out.println(a));
    }
    //修改
    @Test
    public  void  upd(){
​
        StuMapper mapper=sqlSession.getMapper(StuMapper.class);
​
        Student  stu=new Student();
        stu.setSid(3);
        stu.setSname("小若");
        stu.setSex("人妖");
        int i=mapper.upd(stu);
        System.out.println("修改了"+i+"条数据"+"  "+stu.toString());
​
    }
    //添加
    @Test
    public  void  add(){
​
        StuMapper mapper=sqlSession.getMapper(StuMapper.class);
​
        Student  stu=new Student();
        stu.setSname("小贺");
        stu.setSex("男");
        stu.setPhone("99999999");
        int i=mapper.add(stu);
        System.out.println("添加了"+i+"条数据"+"  "+stu.toString());
​
    }
​
    //批量 *** 作
    @Test
    public  void  findAll(){
​
        StuMapper mapper=sqlSession.getMapper(StuMapper.class);
        Integer[] i={1,2,3,4};
        List list=mapper.findAll(i);
        list.forEach(a-> System.out.println(a));
    }
    //批量 *** 作
​
    //批量删除
    @Test
    public  void  del(){
        StuMapper mapper=sqlSession.getMapper(StuMapper.class);
        Integer[] i={1,2,3,4};
        int i1=mapper.del(i);
        System.out.println("删除了"+i1+"条数据");
    }
}
​
7.sql
  • 在实际开发中会遇到许多相同的SQL,比如根据某个条件筛选,这个筛选很多地方都能用到,我们可以将其抽取出来成为一个公用的部分,这样修改也方便,一旦出现了错误,只需要改这一处便能处处生效了,此时就用到了这个标签了。

  • 当多种类型的查询语句的查询字段或者查询条件相同时,可以将其定义为常量,方便调用。为求 9.如何引用其他XML中的SQL片段

    • 比如你在com.xxx.dao.xxMapper这个Mapper的XML中定义了一个SQL片段如下:

     ID,MAJOR,BIRTHDAY,AGE,NAME,HOBBY

    此时我在com.xxx.dao.PatinetMapper中的XML文件中需要引用,如下:

    
    
    三:MyBatis关联查询 1.MyBatis一对多关联查询
        
            
            
            
            
            
                
                
                
            
        
        
        
        
        select  *  from  teacher  t right join student1 s on  t.sid=s.sid
        
    3.MyBatis多对多关联查询
        

    欢迎分享,转载请注明来源:内存溢出

    原文地址: http://outofmemory.cn/zaji/5597466.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-15
下一篇 2022-12-15

发表评论

登录后才能评论

评论列表(0条)

保存