动态SQL语句

1.主要思想

动态SQL的主要思想是根据不同的需求和条件生成可变的SQL语句,以满足动态性和灵活性的需求。这样可以根据不同的情况生成不同的SQL查询、插入、更新或删除语句。

动态SQL通常使用字符串拼接、字符串格式化或参数绑定等技术来生成SQL语句。它允许在运行时根据特定条件生成不同的查询条件、表名、列名、排序方式等,以满足动态变化的需求。

2.应用场景:

动态SQL是一种在程序运行时根据条件或参数的不同生成和执行SQL语句的方法。它与静态SQL相对,静态SQL是在编译时就确定好的固定SQL语句。

动态SQL的应用场景非常广泛,包括但不限于搜索和过滤功能、数据分页、动态排序、动态表名和列名、动态插入和更新等。

需要注意的是,在使用动态SQL时,应该遵循良好的编程实践,特别是对输入参数进行适当的验证和处理,以防止潜在的安全风险,如SQL注入攻击。

  1. 搜索和过滤:动态SQL可以用于构建灵活的搜索和过滤功能,用户可以根据不同的条件查询数据。例如,一个电子商务网站可以根据用户选择的不同筛选条件生成相应的SQL查询语句来获取符合要求的商品列表。

  2. 数据分页:动态SQL可用于实现数据分页功能。通过动态生成包含LIMIT或OFFSET子句的SQL语句,可以根据用户请求返回指定范围的数据结果,以提高系统性能和用户体验。

  3. 动态排序:使用动态SQL可以根据用户的排序要求生成不同的ORDER BY子句,以实现动态排序功能。用户可以根据需要选择不同的字段和排序方式进行排序操作。

  4. 动态表名和列名:有时需要在查询中根据不同的条件或环境选择不同的表名或列名。动态SQL可以根据条件生成包含动态表名和列名的查询语句,以适应不同的数据结构或数据库设计。

  5. 动态插入和更新:动态SQL还可以用于根据用户输入或系统条件生成插入和更新语句。这在需要根据不同情况动态生成数据操作语句的应用中非常有用。

3.代码实现

数据库:student表

 

实体类:Student.java

(对应数据库表重大字段)

package com.xiaoma.po;

import java.util.Date;

public class Student {

    private int sno;

    private String sname;

    private String sgender;

    private Date sbirthday;

    public Student() {
    }

    public Student(int sno, String sname, String sgender, Date sbirthday) {
        this.sno = sno;
        this.sname = sname;
        this.sgender = sgender;
        this.sbirthday = sbirthday;
    }

    public int getSno() {
        return sno;
    }

    public void setSno(int sno) {
        this.sno = sno;
    }

    public String getSname() {
        return sname;
    }

    public void setSname(String sname) {
        this.sname = sname;
    }

    public String getSgender() {
        return sgender;
    }

    public void setSgender(String sgender) {
        this.sgender = sgender;
    }

    public Date getSbirthday() {
        return sbirthday;
    }

    public void setSbirthday(Date sbirthday) {
        this.sbirthday = sbirthday;
    }

    @Override
    public String toString() {
        return "Student{" +
                "sno=" + sno +
                ", sname='" + sname + '\'' +
                ", sgender='" + sgender + '\'' +
                ", sbirthday=" + sbirthday +
                '}';
    }
}

QueryVO.java

(用户从前端传来的各种各样的参数组合)

package com.xiaoma.vo;

import com.xiaoma.po.Product;
import com.xiaoma.po.Student;

import java.util.List;

public class QueryVO {

    private Product product;

    private Student student;

    private List<Integer> snos;

    public QueryVO() {
    }

    public QueryVO(Product product) {
        this.product = product;
    }

    public Product getProduct() {
        return product;
    }

    public void setProduct(Product product) {
        this.product = product;
    }

    public Student getStudent() {
        return student;
    }

    public void setStudent(Student student) {
        this.student = student;
    }

    public List<Integer> getSnos() {
        return snos;
    }

    public void setSnos(List<Integer> snos) {
        this.snos = snos;
    }

    @Override
    public String toString() {
        return "QueryVO{" +
                "product=" + product +
                ", student=" + student +
                ", snos=" + snos +
                '}';
    }
}

StudentMapper.java

(定义接口和接口中的方法,无需编写具体实现类,实现由Mybatis框架自动完成)

package com.xiaoma.mapper;

import com.xiaoma.po.Student;
import com.xiaoma.vo.QueryVO;

import java.util.List;

public interface StudentMapper {

    /**
     *
     * @param queryVO 封装着学生相关的查询信息
     * @return 根据条件查询到的学生信息
     */
    List<Student> selectByCondition(QueryVO queryVO);

    /**
     * 根据多个学号查询结果
     * @param queryVO 封装着任意多个学号
     * @return 满足任意个学号的结果都返回
     */
    List<Student> selectBySnos(QueryVO queryVO);
}

StudentMapper.xml

(id对应StudentMapper中的方法名)

<?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.xiaoma.mapper.StudentMapper">

    <select id="selectByCondition" parameterType="com.xiaoma.vo.QueryVO" resultType="com.xiaoma.po.Student">
        SELECT * FROM mybatis.student
<!--        WHERE sname LIKE #{student.sname} AND sgender = #{student.sgender}-->
        <where>
            <if test="student != null">
                <!--sname不为空,此时才去拼接到where语句中-->
                <if test="student.sname != null and student.sname != ''">
                    AND sname LIKE #{student.sname}
                </if>
                <if test="student.sgender != null and student.sgender != ''">
                    AND sgender = #{student.sgender}
                </if>
            </if>
        </where>
    </select>

    <select id="selectBySnos" parameterType="com.xiaoma.vo.QueryVO" resultType="com.xiaoma.po.Student">
        SELECT * FROM mybatis.student
        <!--WHERE sno IN (1,2,3)-->
        <where>
            <if test="snos!=null and snos.size()>0">
                sno in
                <foreach collection="snos" item="sno" open="(" close=")" separator=",">
                    #{sno}
                </foreach>
            </if>
        </where>
    </select>
</mapper>

测试类:StudentMapperTest.java

package com.xiaoma.mapper;

import com.xiaoma.po.Student;
import com.xiaoma.vo.QueryVO;
import junit.framework.TestCase;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Test;

import java.io.InputStream;
import java.util.Arrays;
import java.util.List;

public class StudentMapperTest extends TestCase {
    SqlSessionFactory sqlSessionFactory;

    public void setUp() throws Exception {
        //加载全局配置文件
        InputStream is = StudentMapperTest.class.getClassLoader().getResourceAsStream("sqlMapConfig.xml");
        //根据全局配置文件创建sqlSessionFactory工厂
        sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
    }

    public void tearDown() throws Exception {
    }

    @Test
    public void testSelectByCondition() {
        QueryVO queryVO = new QueryVO();
        Student student = new Student();
//        student.setSname("张三");
        student.setSgender("男");
        queryVO.setStudent(student);
        sqlSessionFactory.openSession()
                .getMapper(StudentMapper.class)
                .selectByCondition(queryVO)
                .forEach(System.out::println);
    }

    @Test
    public void testSelectBySnos() {
        QueryVO queryVO = new QueryVO();
        List<Integer> snos = Arrays.asList(1,2,3);
        queryVO.setSnos(snos);
        sqlSessionFactory.openSession()
                .getMapper(StudentMapper.class)
                .selectBySnos(queryVO)
                .forEach(System.out::println);

    }
}

4.运行结果

 

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值