【MyBatis】| Tips for using MyBatis

Table of contents

One: MyBatis using tips

1. #{} and ${}

2. typeAliases

3. mappers

4. IDEA configuration file template

5. Get the auto-generated primary key when inserting data


One: MyBatis using tips

1. #{} and ${}

#{}: Compile the sql statement first, and then pass the value to the placeholder. The bottom layer is the PreparedStatement implementation. It can prevent sql injection and is more commonly used!

${}: Concatenate sql statements first, and then compile sql statements. The bottom layer is Statement implementation. There is sql injection phenomenon. It will only be used when splicing sql statement keywords is required!

(1) Define the interface CarMapper, interface-oriented programming

package com.bjpowernode.mybatis.mapper;

import com.bjpowernode.mybatis.pojo.Car;

import java.util.*;

public interface CarMapper {
    // 根据汽车类型查询
    List<Car>  selectByCarType(String carType);
}

(2) Write sql statements in the CarMapper.xml file

Note: namespace is the full class name of the interface CarMapper, and id is the method name corresponding to the interface!

<?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.bjpowernode.mybatis.mapper.CarMapper">
    <select id="selectByCarType" resultType="com.bjpowernode.mybatis.pojo.Car">
      select
            id,
            car_num as carNum,
            brand,
            guide_price as guidePrice,
            produce_time as produceTime,
            car_type as carType
        from t_car
        where car_type = #{carType}
    </select>
</mapper>

(3) Write test classes and see the comparison of execution results

package com.bjpowernode.mybatis.test;

import com.bjpowernode.mybatis.mapper.CarMapper;
import com.bjpowernode.mybatis.pojo.Car;
import com.bjpowernode.mybatis.utils.SqlSessionUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;

import java.util.List;

public class CarMapperTest {
    @Test
    public void testSelectByCarType(){
        SqlSession sqlSession = SqlSessionUtils.openSession();
        CarMapper mapper = sqlSession.getMapper(CarMapper.class);
        List<Car> cars = mapper.selectByCarType("燃油车");
        for (Car car :cars){
            // 会调toString方法
            System.out.println(car);
        }
        sqlSession.close();
    }
}

① Use #{} to execute the result, and the result can be executed normally

Features: First execute the compilation of the SQL statement, and then pass the value to the placeholder question mark? of the SQL statement

② Use ${} to execute the result, an exception will be thrown, and the string will be spliced ​​directly without quotation marks

Features: First execute the splicing of SQL statements, and then compile the SQL statements

(4) Selection of #{} and ${}

Note: If you need to put the keywords of the SQL statement in the SQL statement, you can only use ${} , because #{} is put in the SQL statement in the form of a value; for example: asc or desc needs to be passed for ascending or descending order , here When you want to pass this keyword in, you need ${}

①Methods in the interface class

package com.bjpowernode.mybatis.mapper;
import com.bjpowernode.mybatis.pojo.Car;
import java.util.*;

public interface CarMapper {
    // 根据汽车类型查询
    List<Car>  selectByCarType(String carType);

    // 查询所有的汽车信息,然后通过asc升序,desc降序
    List<Car> selectByAscOrDesc(String ascOrDesc);
}

②Write sql statements, according to the parameters passed in ascending or descending order according to produce_time

<?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.bjpowernode.mybatis.mapper.CarMapper">
    <select id="selectByCarType" resultType="com.bjpowernode.mybatis.pojo.Car">
      select
            id,
            car_num as carNum,
            brand,
            guide_price as guidePrice,
            produce_time as produceTime,
            car_type as carType
        from t_car
        where car_type = #{carType}
    </select>

    <select id="selectByAscOrDesc" resultType="com.bjpowernode.mybatis.pojo.Car">
        select
            id,
            car_num as carNum,
            brand,
            guide_price as guidePrice,
            produce_time as produceTime,
            car_type as carType
        from
            t_car
        order by
            produce_time #{ascOrDesc}
    </select>
</mapper>


③ Write test program

package com.bjpowernode.mybatis.test;

import com.bjpowernode.mybatis.mapper.CarMapper;
import com.bjpowernode.mybatis.pojo.Car;
import com.bjpowernode.mybatis.utils.SqlSessionUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;

import java.util.List;

public class CarMapperTest {
    @Test
    public void selectByAscOrDesc(){
        SqlSession sqlSession = SqlSessionUtils.openSession();
        CarMapper mapper = sqlSession.getMapper(CarMapper.class);
        List<Car> cars = mapper.selectByAscOrDesc("asc");
        for (Car car :cars){
            // 会调toString方法
            System.out.println(car);
        }
        sqlSession.close();
    }
}

Use #{}, first compile and pass the value, the passed is a string, there will be quotation marks, which obviously does not conform to the grammar!

 Use ${}, first string together the keywords, and then compile it, which conforms to the grammatical rules!

(5) Use ${} to complete the splicing of table names

Note: Here you need to query the new table name, so you need to write a new PoJo class Log, create a new configuration file LogMapper.xml, create a new interface LogInterface, create a new test class LogMapperTest class for testing, and introduce it in the core configuration file mybatis-config.xml LogMapper.xml

① In actual business, there may be situations where data is stored in separate tables , because if one table stores data, the amount of data is too large and the query efficiency is relatively low.
② These data can be regularly stored in separate tables, so that the amount of scanned data is reduced, and the efficiency of query is relatively high. For example, a log table: for storing log information, a new table can be generated every day, and each table is named with the date of the day, for example: t_log_20220901, t_log_20220902... ③If you want to know the log information of a certain day, suppose today is 20230103
, Then pass in the date directly to complete the splicing of "t_log_date table".

<?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.powernode.mybatis.mapper.LogMapper">

    <select id="selectAllByTable" resultType="com.bjpowernode.mybatis.pojo.Log">
        <!--select * from t_log_#{date}-->
        select * from t_log_${date}
    </select>

</mapper>

(6) Use ${} to complete batch deletion

Note: There are two ways to write the sql statement corresponding to batch deletion

The first one: use the form of or, delete from t_user where id = 1 or id = 2 or id = 3;

The second: use the form of in, delete from t_user where id in(1, 2, 3);

①The parameter in the defined method is actually a string of String type. When we pass the parameter, it is also a string, for example: mapper.deleteBatch("1,2,3").

②The key is whether we assemble strings first and then compile, or compile and pass values ​​first; the former is a perfect splicing of strings, and the latter is to pass a string directly, with quotation marks!

<delete id="deleteBatch">
     delete from t_car where id in(${ids})
</delete>

(7) Use ${} to complete fuzzy query

Requirement: Carry out fuzzy query based on car brand
For example: select * from t_car where brand like '%Benz%';

<select id="selectByBrandLike" resultType="CAR">
        select
            id,
            car_num as carNum,
            brand,
            guide_price as guidePrice,
            produce_time as produceTime,
            car_type as carType
        from
            t_car
        where
            <!--brand like '%#{brand}%'-->
            brand like '%${brand}%'
            brand like concat('%',#{brand},'%')
            brand like concat('%','${brand}','%')
            brand like "%"#{brand}"%"
</select>

If "%#{brand}%" is used, the bottom layer of #{} must be transformed into ?, but what is more embarrassing is that the ? placed in double quotes or single quotes "?" is unrecognizable, so the value cannot be passed!

①Solution 1: Use "%${brand}%", the string will be assembled first, and then compiled!

②Solution 2: The concat function, which is a function in the mysql database, is specially used for string splicing, concat('%',#{brand},'%'); here you can also use ${band}, add A single quote is rather useless,
concat('%','${brand}','%').

③Solution 3: "%"#{brand}"%", enclose the two % in quotation marks, and then the ? in the middle can be recognized, and the value can be passed normally.

2. typeAliases

Use the typeAliases tag to complete the alias mechanism!

(1) We opened the CarMapper.xml file and found that the fully qualified name of the resultType tag is very long, including the class name with the package when we write other types of query statements in the future; so we use the alias mechanism to define the alias first.

 <select id="selectByCarLike" resultType="com.bjpowernode.mybatis.pojo.Car">
 </select>

(2) The first method: use the sub-tag typeAlias ​​tag under the typeAliases tag in the core configuration file mybatis-config.xml to create an alias.

Note: The namespace tag must write a fully qualified name, it cannot be aliased!

①type attribute: assign an alias to that type

②alias: Specify an alias

    <typeAliases>
        <typeAlias type="com.bjpowernode.mybatis.pojo.Car" alias="car" />
    </typeAliases>

③ In this way, the alias can be used in the CarMapper.xml file, and it is not case-sensitive!

 <select id="selectByCarLike" resultType="car">
 </select>

④In fact, the alias attribute can be omitted, and there is a default alias, which is the abbreviation of the class; for example: com.bjpowernode.mybatis.pojo.Car corresponds to Car, car, cAr, etc., and is not case-sensitive.

(3) The second method: In the core configuration file mybatis-config.xml, use the subtag package under the typeAliases tag to specify the package name. (commonly used)

We use the package tag to specify a package name, then all the classes under this package will be automatically aliased, and the alias is the short name of the class, which is not case-sensitive

    <typeAliases>
        <package name="com.bjpowernode.mybatis.pojo" />
    </typeAliases>

 (4) Summary

All aliases are case-insensitive; namespaces cannot use the alias mechanism!

    <typeAliases>
        <!--别名自己指定的-->
        <typeAlias type="com.powernode.mybatis.pojo.Car" alias="aaa"/>
        <typeAlias type="com.powernode.mybatis.pojo.Log" alias="bbb"/>

        <!--采用默认的别名机制-->
        <typeAlias type="com.powernode.mybatis.pojo.Car"/>
        <typeAlias type="com.powernode.mybatis.pojo.Log"/>

        <!--包下所有的类自动起别名。使用简名作为别名。-->
        <package name="com.powernode.mybatis.pojo"/>
    </typeAliases>

3. mappers

(1) There can be three attributes of the mapper tag:

①resource: This method starts to search for resources from the root path of the class; in this method, the configuration file needs to be placed in the class path.
②url: This method is an absolute path method. This method does not require that the configuration file must be placed in the class path. It can be used anywhere, as long as an absolute path is provided; this method is rarely used because the portability is too poor .
③class: This location provides the fully qualified interface name of the mapper interface, which must have a package name!
For example: <mapper class="com.powernode.mybatis.mapper.CarMapper"/>,

The class specified is: com.powernode.mybatis.mapper.CarMapper, then the mybatis framework will automatically search for the CarMapper.xml file in the com/powernode/mybatis/mapper directory .

Note: That is to say, if this method is used, it must be ensured that the CarMapper.xml file and the CarMapper interface must be in the same directory and have the same name . Such as: CarMapper interface -> CarMapper.xml.

Explanation: The so-called same directory is to create a package name under the resource directory, and this package name must be consistent with the CarMapper interface package name under java, and then throw the configuration file CarMapper.xml into the package name; in fact, java and resource Both are root directories, but there are only two presentation forms!

Explanation: Creating a package under resource is actually creating a directory, because only creating a package under java is in the form of a "dot", for example: com.bjpowernode means the bjpowernode directory under the com directory; creating a package under resource is directly Create a directory, for example: com/bjpowernode also means the bjpowernode directory under the com directory, if com.bjpowernode is used, it means a directory named com.bjpowernode.

 <mappers>
    <mapper resource="CarMapper.xml"/> 要求类的根路径下必须有:CarMapper.xml
    <mapper url="file:///d:/CarMapper.xml"/> 要求在d:/下有CarMapper.xml文件
    <mapper class="com.powernode.mybatis.mapper.CarMapper"/> 全限定接口名,带有包名
 </mappers>

(2) If there are many interface names, it is troublesome to write many fully qualified interface names; in fact, there is a package attribute under the mappers tag to specify the package name. This method is more commonly used in development .

Premise: The XML file must be put together with the interface and have the same name!

Explanation: Specifying registration is actually specifying this path, and searching for configuration files under this path.

<mappers>
    <package name="com.bjpowernode.mybatis.mapper" />
</mappers>

4. IDEA configuration file template

The mybatis-config.xml and SqlMapper.xml files can create templates in advance in IDEA, and then create configuration files through templates

(1) The template of the prepared mybatis-config.xml core configuration file

<?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=""/>
    <typeAliases>
        <package name=""/>
    </typeAliases>
    <environments default="dev">
        <environment id="dev">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="${jdbc.driver}"/>
                <property name="url" value="${jdbc.url}"/>
                <property name="username" value="${jdbc.username}"/>
                <property name="password" value="${jdbc.password}"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <package name=""/>
    </mappers>
</configuration>

(2) The template of the prepared SqlMapper.xml configuration file

<?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="">
</mapper>

(3)步骤:File--->Settings--->Editor--->File and Code Templates

(4) Use: You can find this template directly by alt+insert in the future

 (5) After selecting this template, you will be asked to output the name of the file, for example: mybatis-config 

(6) Click ok, and the core configuration file mybatis-config.xml of our custom template will be automatically generated

5. Get the auto-generated primary key when inserting data

(1) The primary key used above has been automatically generated, so we don’t know how much the primary key is. For the following business, a user has multiple roles, one-to-many, two tables, and multiple tables plus foreign key

 (2) After inserting a new record, the primary key is automatically generated, and this primary key needs to be used in other tables; when inserting a user data, the user needs to be assigned a role: required Insert the generated user id into the user_id field of the role table.

① The first method: You can insert user data first, then write a query statement to obtain the id, and then insert the user_id field. 【Troubleshooting】

②The second way: mybatis provides a more convenient way.

(3) Mainly when inserting data, use two attributes

useGeneratedKeys="true" means to use the automatically generated primary key value.
keyProperty="id" specifies which attribute the primary key value is assigned to the object, which means assigning the primary key value to the id attribute of the Car object.

<insert id="insertCarUseGeneratedKeys" useGeneratedKeys="true" keyProperty="id">
        insert into t_car values(null,#{carNum},#{brand},#{guidePrice},#{produceTime},#{carType})
</insert>

(4) Test results

①If these two parameters are not added, the primary key of the printed result will display null

 ②If these two parameters are added, the print result will display the automatically generated primary key

Guess you like

Origin blog.csdn.net/m0_61933976/article/details/128531269