Mybatis动态SQL

Mybatis动态SQL

**动态SQL:**根据不同的查询条件生成不同的sql语句

搭建环境

1.数据库表blog

CREATE TABLE `blog` (
`id` varchar(50) NOT NULL COMMENT '博客id',
`title` varchar(100) NOT NULL COMMENT '博客标题',
`author` varchar(30) NOT NULL COMMENT '博客作者',
`create_time` datetime NOT NULL COMMENT '创建时间',
`views` int(30) NOT NULL COMMENT '浏览量'
) ENGINE=InnoDB DEFAULT CHARSET=utf8

2.MybatisUtils工具类

/**
 * Mybatis工具类
 * @author 刘淳
 */
public class MybatisUtils {
    private static SqlSessionFactory sqlSessionFactory;
    static {
        try {
            //使用Mybatis第一步:   获取SqlSessionFactory对象
            String resource="mybatis-config.xml";  //配置文件路径
            InputStream inputStream= Resources.getResourceAsStream(resource);  //读取配置文件到输入流
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);  //使用配置文件创建工厂对象
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    //使用Mybatis第二部:   获取SqlSession对象
    //SqlSession:完全包含面向数据库执行sql命令的所有方法
    public static SqlSession getSqlSession(){
        return sqlSessionFactory.openSession();
    }
}

3.IdUtil工具类

/**
 * 生成唯一ID的工具类
 * @author 刘淳
 */
public class IDUtil {
    public static String getId(){
        return UUID.randomUUID().toString().replaceAll("-","");
    }
}

4.Blog实体类

/**
 * Blog表实体类
 * @author 刘淳
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Blog {
    private String id;
    private String title;
    private String author;
    private Date createTime;
    private int views;
}

5.Mapper接口

/**
 * Blog实体类Mapper接口
 * @author 刘淳
 */
public interface BlogMapper {
}

6.Mapper.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="ltd.lccyj.mapper.BlogMapper">

< /mapper>

7.mybatis核心配置文件

< ?xml version="1.0" encoding="UTF-8" ?>
< !DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
< configuration>
    < !--属性引入及配置-->
    < properties resource="jdbc.properties"/>
    
    < settings>
        < !--设置日志实现-->
        < setting name="logImpl" value="LOG4J"/>
        < !--开启下划线命名与驼峰命名自动转换-->
        < setting name="mapUnderscoreToCamelCase" value="true"/>
    < /settings>

    < typeAliases>
        < typeAlias type="ltd.lccyj.domain.Blog" alias="Blog"/>
    < /typeAliases>

    < environments default="development">
        < environment id="development">
            < transactionManager type="JDBC"/>
            < dataSource type="POOLED">
                < property name="driver" value="${driver}"/>
                < property name="url" value="${url}"/>
                < property name="username" value="${username}"/>
                < property name="password" value="${password}"/>
            < /dataSource>
        < /environment>
    < /environments>

    < mappers>
        < package name="ltd.lccyj.mapper"/>
    < /mappers>
< /configuration>

8.准备初始数据

  • 编写接口

    int addBlog(Blog blog);
    
  • mapper.xml

    < insert id="addBlog" parameterType="Blog">
        insert into blog (id, title, author, create_time, views)
        VALUES (#{id},#{title},#{author},#{createTime},#{views})
    < /insert>
    
  • 测试类中初始化博客数据

    @Test
    public void addBlog(){
        SqlSession session = MybatisUtils.getSqlSession();
        BlogMapper mapper = session.getMapper(BlogMapper.class);
        
        Blog blog = new Blog();
        blog.setId(IDUtil.getId());
        blog.setTitle("阿巴阿巴阿巴阿巴");
        blog.setAuthor("刘淳");
        blog.setCreateTime(new Date());
        blog.setViews(9999);
        
        mapper.addBlog(blog);
        
        blog.setId(IDUtil.getId());
        blog.setTitle("阿巴");
        mapper.addBlog(blog);
        
        blog.setId(IDUtil.getId());
        blog.setTitle("阿巴阿巴");
        mapper.addBlog(blog);
        
        blog.setId(IDUtil.getId());
        blog.setTitle("阿巴阿巴阿巴");
        mapper.addBlog(blog);
        
        session.commit();
        session.close();
    }
    

if语句

**需求:**根据作者名字和博客名字来查询博客,如果作者为空,根据博客名查询,反之根据作者名查询

**if:**如果test中条件为true,则会向sql中插入标签中的语句

1.Mapper接口

List< Blog> selectBlogIf(Map< String,String> map);

2.Mapper.xml

< select id="selectBlogIf" parameterType="map" resultType="Blog">
    select * from blog where
    < if test="title!=null">
        title=#{title}
    < /if>
    < if test="author!=null">
        and author=#{author}
    < /if>
< /select>

3.测试

@Test
public void selectBlogIf(){
    SqlSession sqlSession = MybatisUtils.getSqlSession();
    BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);
    Map< String,String> map=new HashMap< >();
    map.put("title","阿巴");
    map.put("author","刘淳");
    List< Blog> blogs = mapper.selectBlogIf(map);
    for (Blog blog : blogs) {
        System.out.println(blog);
    }
    sqlSession.close();
}

where语句

上面的实现存在一个问题,当title为空,但存在where时会出现sql语句错误

image-20211126153501853

可使用where解决

  • 如果where标签包含的标签中有返回值,它会向sql中插入一个where
  • 如果包含的标签返回内容是and或or开头,会将其去除

修改Mapper.xml

< select id="selectBlogIf" parameterType="map" resultType="Blog">
    select * from blog
    < where>
        < if test="title!=null">
            title=#{title}
        < /if>
        < if test="author!=null">
            and author=#{author}
        < /if>
    < /where>
< /select>

set语句

**set:**用于更新语句,能自动去除语句中多余的逗号

1.Mapepr接口

void updateBlog(Map< String,String> map);

2.Mapper.xml

< update id="updateBlog" parameterType="map">
    update blog
    < set>
        < if test="title!=null">
            title=#{title},
        < /if>
        < if test="author!=null">
            author=#{author}
        < /if>
    < /set>
    where id=#{id}
< /update>

3.测试

@Test
public void updateBlog(){
    SqlSession session = MybatisUtils.getSqlSession();
    BlogMapper mapper = session.getMapper(BlogMapper.class);

    HashMap< String, String> map = new HashMap< >();
    map.put("title","阿巴");
    map.put("author","小学生");
    map.put("id","c66a359f11964fc19fda3113606eace2");

    mapper.updateBlog(map);

    session.commit();
    session.close();
}

choose语句

**choose:**相当于java中的switch when相当于case otherwise等于default

1.Mapper接口

List< Blog> selectBlogChoose(Map< String,Object> map);

2.Mapper.xml

< select id="selectBlogChoose" parameterType="map" resultType="Blog">
    select * from blog
    < where>
        < choose>
            < when test="title!=null">
                title=#{title}
            < /when>
            < when test="author!=null">
                author=#{author}
            < /when>
            < otherwise>
                views=#{views}
            < /otherwise>
        < /choose>
    < /where>
< /select>

3.测试

@Test
public void selectBlogChoose(){
    SqlSession session = MybatisUtils.getSqlSession();
    BlogMapper mapper = session.getMapper(BlogMapper.class);

    HashMap< String, Object> map = new HashMap< String, Object>();
    map.put("title","阿巴");
    map.put("author","刘淳");
    map.put("views",9999);
    List< Blog> blogs = mapper.selectBlogChoose(map);

    System.out.println(blogs);

    session.close();
}

SQL片段

重复使用的sql语句可以抽取出来,使用时直接调用

  • 建议基于单表定义sql,提高sql片段复用性
  • sql片段中不要包括where

示例:

< sql id="if-title-author">
    < if test="title!=null">
        title=#{title}
    < /if>
    < if test="author!=null">
        and author=#{author}
    < /if>
< /sql>

< select id="selectBlogIf" parameterType="map" resultType="Blog">
    select * from blog
    < where>
        < include refid="if-title-author"/>
    < /where>
< /select>

foreach语句

**环境准备:**将数据库表的前三数据id改为1,2,3

**需求:**查询表中blog表中id分别为1,2,3的博客信息

foreach:

  • collection:指定参数中的集合
  • item:每次遍历生成的对象
  • open:开始遍历时拼接的字符串
  • close:结束时拼接的字符串
  • separator:遍历对象之间拼接的字符串

1.Mapper接口

List< Blog> selectBlogForeach(List< Integer> list);

2.Mapper.xml

< select id="selectBlogForeach" parameterType="int" resultType="Blog">
    select * from blog
    < where>
        < foreach collection="list" item="id" separator="or">
            id=#{id}
        < /foreach>
    < /where>
< /select>

3.测试

@Test
public void selectBlogForeach(){
    SqlSession session = MybatisUtils.getSqlSession();
    BlogMapper mapper = session.getMapper(BlogMapper.class);

    List< Integer> list = new ArrayList< >();
    list.add(1);
    list.add(2);
    list.add(3);

    List< Blog> blogs = mapper.selectBlogForeach(list);
    System.out.println(blogs);

    session.close();
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

@未安

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值