MyBatis implements query operations

MyBatis implements query operations

The Idea plug-in MyBatisX is introduced here to facilitate the jump generation operation

query all data

interface

mapping file

image-20220814143641005

Test Case

]

There is a problem with the query results here.

The result of brandName amount companyName query is NUll. The reason is that the attribute name in the entity class is named hump, and it is underscore in the database.

The solution is:

  1. Aliasing (aliasing different column names, making the aliases the same as the attribute names of the entity class

    <!--    起别名-->
        <select id="selectAll" resultType="org.example.pojo.Brand">
            select id, brand_name as brandName, company_name as companyName, ordered, description, status
            from tb_brand
        </select>
    
  2. sql fragment (define a fragment, which is referenced in each query)

    <!--    sql片段-->
    <sql id="brand_colume">
        id, brand_name as brandName, company_name as companyName, ordered, description, status
    </sql>
    
    <select id="selectAll" resultType="org.example.pojo.Brand">
        select
        <include refid="brand_colume"/>
        from tb_brand
    </select>
    
  3. ResultMap

    <resultMap id="brandResultMap" type="org.example.pojo.Brand">
        <result column="brand_name" property="brandName"/>
        <result column="company_name" property="companyName"/>
    </resultMap>
    
    <select id="selectAll" resultMap="brandResultMap">
        select *
        from tb_brand
    </select>
    

Inquire about the details of a

The overall process is the same as above

interface

/**
 * 通过id查询详情
 */
public Brand selectById(int id);

SQL mapping

<select id="selectById" resultMap="brandResultMap">
    select *
    from tb_brand
    where id = #{id}
</select>

test

]

Notice

parameter placeholder

  1. #{}: will it be replaced with ? , in order to prevent SQL injection

  2. ${}: spell sql. There will be problems with SQL injection

  3. When to use:

    • When passing parameters: #{}
    • When the table name and column name are not fixed: ${} will have SQL injection problems

Special characters

  1. escape character

  2. CDATA area

    <![CDATA[
    
    ]]>
    

conditional query

In order to facilitate the demonstration of the format of the interface receiving parameters, first write the SQL mapping

<select id="selectByCondition" resultMap="brandResultMap">
    select *
    from tb_brand
    where status = #{status}
      and company_name like #{companyName}
      and brand_name like #{brandName}
</select>

conditional query

Parameter reception

  1. Bulk parameters: If there are multiple parameters in the method, you need to use @Param("SQl parameter placeholder name")
  2. object parameter
  3. map collection parameters

Method 1 bulk parameters

/**
 * 条件查询 方式一
 */
List<Brand> selectByCondition(@Param("status") int status, @Param("companyName") String companyName, @Param("brandName") String brandName);

==Note:==The parameter @Param("parameter") here should be consistent with the parameter in the sql mapping file#{parameter}

test

    @Test
    public void testSelectByCondition() throws IOException {
    
    
//        接收参数
        int status = 1;
        String companyName = "华为";
        String brandName = "华为";
//        处理参数
        companyName = "%" + companyName + "%";
        brandName = "%" + brandName + "%";

//    1.获取SQLSessionFactory
        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//        2. 获取SqlSession对象
        SqlSession sqlSession = sqlSessionFactory.openSession();
//        3. 获取Mapper接口的代理对象
        BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class);
//        4. 执行方法
        List<Brand> brands = brandMapper.selectByCondition(status, companyName, brandName);
        System.out.println(brands);
//        5. 释放资源
        sqlSession.close();
    }

The parameters are processed here for fuzzy query, so add "%" before and after the string to perform fuzzy query

]

Method 2 object parameters

NoticeThe attribute name of the object should be consistent with the parameter placeholder name

Only need to modify the interface

interface

/**
 * 条件查询 方式二
 */
List<Brand> selectByCondition(Brand brand);

test

    @Test
    public void testSelectByCondition() throws IOException {
    
    
//        接收参数
        int status = 1;
        String companyName = "华为";
        String brandName = "华为";
//        处理参数
        companyName = "%" + companyName + "%";
        brandName = "%" + brandName + "%";
//        封装对象
        Brand brand=new Brand();
        brand.setStatus(status);
        brand.setCompanyName(companyName);
        brand.setBrandName(brandName);

//    1.获取SQLSessionFactory
        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//        2. 获取SqlSession对象
        SqlSession sqlSession = sqlSessionFactory.openSession();
//        3. 获取Mapper接口的代理对象
        BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class);
//        4. 执行方法
        List<Brand> brands = brandMapper.selectByCondition(brand);
        System.out.println(brands);
//        5. 释放资源
        sqlSession.close();
    }

]

Method 3 map collection parameters

Here the name of the map key should be the same as the parameter in the sql mapping file

Here is still only modifying the interface

interface

/**
 * 条件查询 方式三
 */
List<Brand> selectByCondition(Map map);

test

 @Test
    public void testSelectByCondition() throws IOException {
    
    
//        接收参数
        int status = 1;
        String companyName = "华为";
        String brandName = "华为";
//        处理参数
        companyName = "%" + companyName + "%";
        brandName = "%" + brandName + "%";
//        封装对象
        Map map = new HashMap();
        map.put("status", status);
        map.put("companyName", companyName);
        map.put("brandName", brandName);

//    1.获取SQLSessionFactory
        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//        2. 获取SqlSession对象
        SqlSession sqlSession = sqlSessionFactory.openSession();
//        3. 获取Mapper接口的代理对象
        BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class);
//        4. 执行方法
        List<Brand> brands = brandMapper.selectByCondition(map);
        System.out.println(brands);
//        5. 释放资源
        sqlSession.close();
    }

image-20220815102529341

dynamic query

The SQL statement will change with the user's input or external conditions, calledDynamic SQL

Click to jump to the official document

1 Multi-condition dynamic query

sql statement

Here first use the if tag, which has a test attribute, and write the expression in the test

Because companyName and brandName are string types, in addition to judging whether it is an empty object, it is also necessary to judge whether it is an empty string

<!--    动态条件查询-->
<select id="selectByCondition" resultMap="brandResultMap">
    select *
    from tb_brand where
    <if test="status != null">
        status = #{status}
    </if>
    <if test="companyName != null and companyName != ''">
        and company_name like #{companyName}
    </if>
    <if test="brandName != null and brandName != ''">
        and brand_name like #{brandName}
    </if>
</select>

interface

/**
 * 条件查询 方式三
 */
List<Brand> selectByCondition(Map map);

test

This test case only enters status and companyName.

    @Test
    public void testSelectByCondition() throws IOException {
    
    
//        接收参数
        int status = 1;
        String companyName = "华为";
        String brandName = "华为";
//        处理参数
        companyName = "%" + companyName + "%";
        brandName = "%" + brandName + "%";
//        封装对象
        Map map = new HashMap();
        map.put("status", status);
        map.put("companyName", companyName);
//        map.put("brandName", brandName);

//    1.获取SQLSessionFactory
        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//        2. 获取SqlSession对象
        SqlSession sqlSession = sqlSessionFactory.openSession();
//        3. 获取Mapper接口的代理对象
        BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class);
//        4. 执行方法
        List<Brand> brands = brandMapper.selectByCondition(map);
        System.out.println(brands);
//        5. 释放资源
        sqlSession.close();
    }

successful query

image-20220815110307373

But there is a bug in this method

If you only query companyName, an error will be reported

Because its sql statement will become select * from tb_brand where and company_name like #{companyName}

This SQL has one more and

Solution

Add and to everything in the if tag

Then use an identity 1=1 after where

<select id="selectByCondition" resultMap="brandResultMap">
    select *
    from tb_brand
    where 1 = 1
    <if test="status != null">
        and status = #{status}
    </if>
    <if test="companyName != null and companyName != ''">
        and company_name like #{companyName}
    </if>
    <if test="brandName != null and brandName != ''">
        and brand_name like #{brandName}
    </if>
</select>

But this is still very troublesome, so MyBatis provides a new label (use the more common method

You can omit writing your own identities by using tags

<select id="selectByCondition" resultMap="brandResultMap">
    select *
    from tb_brand
    <where>
        <if test="status != null">
            and status = #{status}
        </if>
        <if test="companyName != null and companyName != ''">
            and company_name like #{companyName}
        </if>
        <if test="brandName != null and brandName != ''">
            and brand_name like #{brandName}
        </if>
    </where>

2 Single-condition dynamic query

interface

/**
 * 单条件动态查询
 */
List<Brand> selectByConditionSingle(Brand brand);

sql mapping

<select id="selectByConditionSingle" resultMap="brandResultMap">
    select *
    from tb_brand
    where
    <choose>
        <when test="status != null">
            status = #{status}
        </when>
        <when test="companyName != null and companyName != ''">
            company_name like #{companyName}
        </when>
        <when test="brandName != null and brandName != ''">
            brand_name like #{brandName}
        </when>
    </choose>
</select>

The choose here is equivalent to Switch

when is equivalent to case

test

    @Test
    public void testSelectByConditionSingle() throws IOException {
    
    
//        接收参数
        int status = 1;
        String companyName = "华为";
        String brandName = "华为";
//        处理参数
        companyName = "%" + companyName + "%";
        brandName = "%" + brandName + "%";
//        封装对象
        Brand brand = new Brand();
        brand.setStatus(status);
//        brand.setCompanyName(companyName);
//        brand.setBrandName(brandName);

//    1.获取SQLSessionFactory
        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//        2. 获取SqlSession对象
        SqlSession sqlSession = sqlSessionFactory.openSession();
//        3. 获取Mapper接口的代理对象
        BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class);
//        4. 执行方法
        List<Brand> brands = brandMapper.selectByConditionSingle(brand);
        System.out.println(brands);
//        5. 释放资源
        sqlSession.close();
    }

]

There is also a bug in this query, that is, if the three conditions are all null, an error will be reported

so add a tag

which uses the identity 1=1

<select id="selectByConditionSingle" resultMap="brandResultMap">
    select *
    from tb_brand
    where
    <choose>
        <when test="status != null">
            status = #{status}
        </when>
        <when test="companyName != null and companyName != ''">
            company_name like #{companyName}
        </when>
        <when test="brandName != null and brandName != ''">
            brand_name like #{brandName}
        </when>
        <otherwise>
            1=1
        </otherwise>
    </choose>
</select>

There is another method, the effect of using tags is the same

<select id="selectByConditionSingle" resultMap="brandResultMap">
    select *
    from tb_brand
    <where>
        <choose>
            <when test="status != null">
                status = #{status}
            </when>
            <when test="companyName != null and companyName != ''">
                company_name like #{companyName}
            </when>
            <when test="brandName != null and brandName != ''">
                brand_name like #{brandName}
            </when>
        </choose>
    </where>
</select>

Guess you like

Origin blog.csdn.net/qq_45842943/article/details/126356794