Mybatis framework technology summary, how to write efficient SQL

3.3,SqlSessionFactory

SqlSessionFactory has multiple methods to create SqlSession instances, including the following two:

  • SqlSessionFactory.openSession: a transaction will be started by default, but the transaction will not be submitted automatically, which means that the transaction needs to be submitted manually before the update operation data can be persisted in the database

  • SqlSessionFactory.openSession(boolean autoCommit): the parameter is whether to commit automatically. If it is set to true, the transaction does not need to be submitted manually

|Return value | method name | description|

| — | — | — |

|SqlSession | openSession() | use the SqlSession builder object and enable manual transaction submission|

|SqlSession | openSession(boolean autoCommit) | through the SqlSession builder object, if the parameter is true, the automatic transaction submission is enabled|

3.4,SqlSession

SqlSession provides all the methods required to execute SQL commands in the database. It also provides operations related to transactions.

The membership method is as follows:

  • sqlSession.commit(): commit a transaction

  • sqlSession.rollback(): rollback transaction

  • sqlSession.close(): release resources

3.5 mybatis tools

We usually encapsulate the SqlSession instance obtained by mybatis into a tool class

public class MybatisUtils {

    private static SqlSessionFactory sqlSessionFactory;

    static{

        try {

            // Using Mybatis

            // Step 1: get sqlSessionFactory object

            String resource = "mybatis-config.xml";

            InputStream inputStream = Resources.getResourceAsStream(resource);

            sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

        } catch (IOException e) {

            e.printStackTrace();

        }

    }



    //Now that we have SqlSessionFactory, as the name suggests, we can get an instance of SqlSession from it.

    public static SqlSession getSqlSession(){

//        SqlSession sqlSession = sqlSessionFactory.openSession();

//        return sqlSession;

        return sqlSessionFactory.openSession();

    }

}



4. Mybatis development method

===============================================================================

4.0. Traditional development of Mybatis

4.0 traditional implementation of Dao layer

  • Layered idea: controller, service and Dao.

  • Call process

4.1 agent development mode of Dao layer

  • Mapper interface development method only requires programmers to write mapper interface (equivalent to Dao interface)

  • Our previous development specification is to write Dao interface, and then write the implementation class DaoImpl

  • Agent development specification is to write Dao interface, and then write xml configuration file

Mapper interface development needs to follow the following specifications:

  1. Mapper. The namespace in the XML file is the same as the fully qualified name of the mapper interface

  2. Mapper interface method name and mapper The id of each statement defined in the XML is the same

  3. Mapper interface method input parameter type and mapper The parameterType of each sql defined in XML is the same

  4. Mapper interface method output parameter type and mapper The resultType of each sql defined in XML is the same

4.2 acquisition of parameters

4.2. 1. One parameter

4.2. 1.1 basic parameters

We can use #{} direct to get values. We can get parameters by writing any name. However, it is generally taken by the parameter name of the method.

For example:

  • Methods in the interface are defined as follows
public interface UserDao {

    

    User findUser(Integer id);

    

}



  • The contents in the xml are as follows
<select id="findUser" parameterType="int" resultType="com.sangeng.pojo.User">

    select * from user where id = #{id}

</select>



  • test
@Test

public void findUser() throws IOException {

   //Defines the path to the mybatis configuration file

   String resource = "mybatis-config.xml";

   InputStream inputStream = Resources.getResourceAsStream(resource);

   SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);



   //Get Sqlsession object

   SqlSession sqlSession = sqlSessionFactory.openSession();

   //Get UserDao implementation class object

   UserDao userDao = sqlSession.getMapper(UserDao.class);

   //Call method test

   User user = userDao.findUser(2);

   System.out.println(user);

   //Release resources

   sqlSession.close();

}



4.2.1.2,POJO

We can use the property name in the POJO to get the corresponding value.

For example:

  • Methods in the interface are defined as follows
public interface UserDao {

    

    User findByUser(User user);

    

}



  • The contents in the xml are as follows
<select id="findByUser" resultType="com.sangeng.pojo.User">

    select * from user where id = #{id} and username = #{username} and age = #{age} and address = #{address}

</select>



  • test
@Test

public void findByUser() throws IOException {

    //Defines the path to the mybatis configuration file

    String resource = "mybatis-config.xml";

    InputStream inputStream = Resources.getResourceAsStream(resource);

    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);



    //Get Sqlsession object

    SqlSession sqlSession = sqlSessionFactory.openSession();

    //Get UserDao implementation class object

    UserDao userDao = sqlSession.getMapper(UserDao.class);

    //Call method test

    User byUser = userDao.findByUser(new User(2, "PDD", 25, "Shanghai"));

    System.out.println(byUser);

    //Release resources

    sqlSession.close();

}



4.2.1.3,Map

We can use the key in the map to get the corresponding value.

For example:

  • Methods in the interface are defined as follows
public interface UserDao {

    

    User findByMap(Map map);

    

}



  • The contents in the xml are as follows
<select id="findByMap" resultType="com.sangeng.pojo.User">

    select * from user where id = #{id} and username = #{username} and age = #{age} and address = #{address}

</select>



  • test
@Test

public void findByMap() throws IOException {

    //Defines the path to the mybatis configuration file

    String resource = "mybatis-config.xml";

    InputStream inputStream = Resources.getResourceAsStream(resource);

    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);



    //Get Sqlsession object

    SqlSession sqlSession = sqlSessionFactory.openSession();

    //Get UserDao implementation class object

    UserDao userDao = sqlSession.getMapper(UserDao.class);

    //Call method test

    Map map = new HashMap();

    map.put("id",2);

    map.put("username","PDD");

    map.put("age",25);

    map.put("address","Shanghai");

    User byMap = userDao.findByMap(map);

    System.out.println(byMap);

    //Release resources

    sqlSession.close();

}



4.2. 2. Multiple parameters

Mybatis will put multiple parameters into a Map set. The default key is argx and paramx.

For example:

  • Methods in the interface are defined as follows

    • We usually use @ Param to set the parameter name before the method parameter.
public interface UserDao {

    

    User findByCondition(@Param("tid") Integer id,@Param("username")String username);

    

}



  • The contents in the xml are as follows
<select id="findByCondition" resultType="com.sangeng.pojo.User">

     select * from user where id = #{tid} and username = #{username}

</select>



  • test
@Test

public void findByCondition() throws IOException {

    //Defines the path to the mybatis configuration file

    String resource = "mybatis-config.xml";

    InputStream inputStream = Resources.getResourceAsStream(resource);

    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);



    //Get Sqlsession object

    SqlSession sqlSession = sqlSessionFactory.openSession();

    //Get UserDao implementation class object

    UserDao userDao = sqlSession.getMapper(UserDao.class);

    //Call method test

    User pdd = userDao.findByCondition(2, "PDD");

    System.out.println(pdd);

    //Release resources

    sqlSession.close();

}



4.2. 3. Summary

  • It is suggested that if there is only one parameter, no special processing should be done.

  • If there are multiple parameters, you must add @ Param to set the parameter name.

4.2. 4. Difference between #{} and ${} when getting parameters

  • If #{} It is precompiled SQL, which can prevent SQL injection attacks

  • If ${} is used, the parameter values are directly spliced, which will be in danger of SQL injection

5. CRUD operation

==========================================================================

5.1,select

The select statement has many properties, and each SQL statement can be configured in detail

  • id: is the method name in the corresponding namespace

  • Resulttype: return value of SQL statement execution [complete class name or alias]

  • parameterType: parameter type passed in SQL statement

Example:

  1. Add corresponding method in UserMapper
public interface UserMapper {

    // Query all users

    List<User> getUserList();

}    



  1. In usermapper Add Select statement to XML
<mapper namespace="com.kuang.dao.UserMapper">

    <select id="getUserList" resultType="com.kuang.pojo.User">

        select * from mybatis.user;

    </select>

</mapper>



  1. Test in test class
public void test(){

   //Step 1: get SqlSession object

   SqlSession sqlSession = MybatisUtils.getSqlSession();

	//Method 1: execute SQL

    UserMapper userDao = sqlSession.getMapper(UserMapper.class);

    

    List<User> userList = userDao.getUserList();

    for (User user : userList) {

            System.out.println(user);

        }

        // Close SqlSession

        sqlSession.close();    

}



Example 2: query user by id

  1. Add corresponding method in UserMapper
public interface UserMapper {

    // Query user by ID

    User getUserById(int id);

}  



  1. In usermapper Add Select statement to XML
<select id="getUserById" parameterType="int" resultType="com.kuang.pojo.User">

    select * from mybatis.user where id = #{id}

</select>



  1. Test in test class
@Test

public void getUserById(){

    SqlSession sqlSession = MybatisUtils.getSqlSession();

    UserMapper mapper = sqlSession.getMapper(UserMapper.class);

    

    

    User user = mapper.getUserById(1);

    System.out.println(user);



    sqlSession.close();

}



5.2,insert

Requirement: add a user to the database

  1. Add the corresponding method in the UserMapper interface
public interface UserMapper{

    // insert

    int addUser(User user);

}



  1. In usermapper Add insert statement to XML
<insert id="addUser" parameterType="com.kuang.pojo.User">

        insert into mybatis.user(id, name, pwd) VALUES (#{id},#{name},#{pwd})

</insert>



  1. Test in test class
// Add, delete and modify transactions that need to be committed

@Test

public void addUser(){

    SqlSession sqlSession = MybatisUtils.getSqlSession();

    UserMapper mapper = sqlSession.getMapper(UserMapper.class);



    int res = mapper.addUser(new User(5, "Ha ha 2", "1234"));

    if(res > 0) {

        System.out.println("Insert successful");

    }

    // Commit transaction

    sqlSession.commit();

    sqlSession.close();

}



  • In the insert operation, use the parameterType property to specify the type of data to insert

  • Use #{entity attribute name} in Sql statement to refer to attribute value in entity

  • Adding, deleting and modifying operations involve changes in database data, so you should use sqlSession object to explicitly commit transactions, that is, sqlSession commit()

5.3,update

Requirement: modify user information

  1. Add the corresponding method in the UserMapper interface
public interface UserMapper{

    // Modify user

    int updateUser(User user);

}



  1. In usermapper Add update statement to XML
<update id="updateUser" parameterType="com.kuang.pojo.User">

        update mybatis.user set name=#{name},pwd=#{pwd} where id = #{id};

</update>



  1. Test in test class
@Test

    public void updateUser(){

        SqlSession sqlSession = MybatisUtils.getSqlSession();

        UserMapper mapper = sqlSession.getMapper(UserMapper.class);

        

        

        int res = mapper.updateUser(new User(4, "ha-ha", "123123"));

        if(res > 0){

            System.out.println("Modified successfully");

        }



        sqlSession.commit();

        sqlSession.close();

    }



5.4,delete

Requirement: delete a user according to id

  1. Add the corresponding method in the UserMapper interface
public interface UserMapper{

    // Delete a user

    int deleteUser(int id);

}



  1. In usermapper Add update statement to XML
<delete id="deleteUser" parameterType="int">

        delete from mybatis.user where id = #{id}

</delete>



  1. Test in test class
@Test

public void deleteUser(){

    SqlSession sqlSession = MybatisUtils.getSqlSession();

    UserMapper mapper = sqlSession.getMapper(UserMapper.class);

    int res = mapper.deleteUser(4);

    if(res > 0){

        System.out.println("Delete succeeded");

    }



    sqlSession.commit();

    sqlSession.close();

}



5.5 universal Map

Assuming that there are too many entity classes or tables, fields or parameters in the database, we should consider using Map!

5.5.1,select

  1. Add corresponding method in UserMapper
public interface UserMapper{

    // Omnipotent map

    User getUserById2(Map<String,Object> map);

}



  1. In usermapper Add insert statement to XML
<select id="getUserById2" parameterType="map" resultType="com.kuang.pojo.User">

        select * from mybatis.user where id = #{helloid} and name = #{name};

</select>



  1. Test in test class
@Test

public void getUserById2(){

    SqlSession sqlSession = MybatisUtils.getSqlSession();

    UserMapper mapper = sqlSession.getMapper(UserMapper.class);

    

    Map<String, Object> map = new HashMap<>();

    map.put("helloId",1);

    sqlSession.close();

}



  • Pass parameters from Map and directly get the key from sql!

5.5.2,insert

  1. Add corresponding method in UserMapper
public interface UserMapper{

    // Omnipotent map

    int addUser2(Map<String, Object> map);

}



  1. In usermapper Add insert statement to XML
<insert id="addUser2" parameterType="map">

        insert into mybatis.user(id, name, pwd) VALUES (#{id},#{name},#{pwd})

</insert>



  1. Test in test class
// Pass key of map

@Test

public void addUser2(){

    SqlSession sqlSession = MybatisUtils.getSqlSession();

    UserMapper mapper = sqlSession.getMapper(UserMapper.class);

    

    HashMap<String, Object> map = new HashMap<>();

    map.put("id",5);

    map.put("name","La La La");

    map.put("pwd","123456");

    

    sqlSession.close();

}



  • Object transfer parameters, you can directly get the attribute of the object in sql!

6. Dynamic SQL

=========================================================================

In the actual development, the SQL statement is not as simple as before, and it is often necessary to dynamically generate SQL statements according to the incoming parameters. Mybatis provides dynamic SQL related tags for us to use.

6.1 if label

You can use the if tag to judge the condition. Only when the condition is established will the content in the if tag be spliced into the sql statement.

For example:

<select id="findByCondition" resultType="com.sangeng.pojo.User">

     select * from user 

     where  id = #{id}

    <if test="username!=null">

       and username = #{username}

    </if>

</select>



  • If the parameter username is null, the executed sql is: select * from user where id =?

  • If the parameter username is not null, the executed sql is: select * from user where id =? and username = ?

  • Note: you do not need to write #{} the parameter in the test attribute. If you write it, there will be problems.

6.2 trim label

You can use the label to dynamically add prefixes or suffixes, or you can use the label to dynamically eliminate prefixes.

Note: in fact, the trim tag will not be used in real development. It is mainly to understand the following where tag, so it can be understood here

6.2. 1. Prefixoverride property

It is used to set the prefix to be cleared. Multiple values can be separated by |. Note that there should be no spaces before and after |. For example: and|or

For example:

<select id="findByCondition" resultType="com.sangeng.pojo.User">

    select * from user

    <trim prefixOverrides="and|or" >

        and

    </trim>

</select>



The final sql executed is: select * from user

6.2. 2. suffixOverrides property

It is used to set the suffix to be cleared. Multiple values can be separated by |. Note that there should be no spaces before and after |. For example: and|or

<select id="findByCondition" resultType="com.sangeng.pojo.User">

    select * from user

    <trim suffixOverrides="like|and" >

        where 1=1 like

    </trim>

</select>



The final sql executed is: select * from user without the suffix like

6.2. 3. prefix attribute

It is used to set the prefix added dynamically. If there is content in the label, the prefix set on it will be added

<select id="findByCondition" resultType="com.sangeng.pojo.User">

    select * from user

    <trim prefix="where" >

       1=1

    </trim>

</select>



The final sql executed is: select * from user where 1=1, and the prefix where is dynamically added

6.2. 4. suffix attribute

It is used to set the dynamically added suffix. If there is content in the label, the set suffix will be added

<select id="findByCondition" resultType="com.sangeng.pojo.User">

    select * from user

    <trim suffix="1=1" >

       where

    </trim>

</select>



The final sql executed is: select * from user where 1=1, and the suffix 1 = 1 is dynamically added

6.2. 5. trim comprehensive use

Dynamically add the prefix where and eliminate the prefix and or

<select id="findByCondition" resultType="com.sangeng.pojo.User">

    select * from user

    <trim prefix="where" prefixOverrides="and|or" >

        <if test="id!=null">

            id = #{id}

        </if>

        <if test="username!=null">

            and username = #{username}

        </if>

    </trim>

</select>



  • When calling the method, if the passed in id and username are null, the executed SQL is: select * from user

  • When calling the method, if the id passed in is null and the username is not null, the SQL executed is: select * from user where username =?

6.3,where

The where tag is equivalent to dynamically adding the prefix where and eliminating the prefix and or

<trim prefix="where" prefixOverrides="and|or" ></trim>



You can use the where tag to dynamically splice where and remove the prefix and or.

For example:

<select id="findByCondition" resultType="com.sangeng.pojo.User">

    select * from user

    <where>

        <if test="id!=null">

            id = #{id}

        </if>

        <if test="username!=null">

            and username = #{username}

        </if>

    </where>

</select>



  • If both id and username are null, the executed sql is: * * select * from user**

  • If the id is null and the username is not null, the executed sql is: * * select * from user where username =**

6.4,set

The set tag is equivalent to dynamically adding the prefix set and clearing the suffix comma

<trim prefix="set" suffixOverrides="," ></trim>



You can use the set tag to dynamically splice the set and remove the comma of the suffix.

For example:

<update id="updateUser">

    UPDATE USER

    <set>

        <if test="username!=null">

            username = #{username},

        </if>

        <if test="age!=null">

            age = #{age},

        </if>

        <if test="address!=null">

            address = #{address},

        </if>

    </set>

    where id = #{id}

</update>



If the ID of the User object passed in when calling the method is 2, the username is not null, and other properties are null, the final sql executed is: update User set username =? where id = ?

6.5,foreach

You can use the foreach tag to traverse the parameters of a collection or array type, obtain the elements therein, and use them to dynamically splice SQL statements.

For example:

  1. Define methods in interfaces
public interface UserDao{

    

    List<User> findByIds(@Param("ids") Integer[] ids);

    

}



If you want to dynamically splice SQL statements according to the length of the actually passed in array. For example, an array with a length of 4 is passed in, and the final executed SQL is:

select * from User WHERE id in( ? , ? , ? , ?, ? ) 



The following writing method can be used in the xml Mapping file

<select id="findByIds" resultType="com.sangeng.pojo.User">

    select * from User

    <where>

        <foreach collection="ids" open="id in(" close=")" item="id" separator=",">

            #{id}

        </foreach>

    </where>

</select>



collection: indicates the parameters to traverse.

open: indicates the statement spliced at the beginning of traversal

item: indicates the name of the currently traversed element

Separator: a separator that indicates splicing after each traversal

close: indicates the statement that traverses the splicing for the last time

Note: if the method parameter is an array type, the default parameter name is array. If the method parameter is a list set, the default parameter name is list. It is recommended that parameters of array or collection types be named with the @ Param annotation.

6.6,choose,when,otherwise

When we don't want to use all the conditions, but just want to choose one from multiple conditions. You can use the choose series label. Similar to switch in java.

For example:

  1. Methods in the interface are defined as follows
public interface UserDao{

    

    List<User> selectChose(User user);

    

}



expect:

If the id of the user object is not empty, query through the id.

If id is null and username is not null, query through username.

If both id and username are null, query the user with id 3

  1. The xml Mapping file is as follows
<select id="selectChose" resultType="com.sangeng.pojo.User">

    select * from user

    <where>

        <choose>

            <when test="id!=null">

                id = #{id}

            </when>

            <when test="username!=null">

                username = #{username}

            </when>

            <otherwise>

                id = 3

            </otherwise>

        </choose>

    </where>

</select>



last

Authoritative guide - the first Docker book

Lead the installation, deployment, management and expansion of Docker, let it go through the whole development life cycle from test to production, and deeply understand what scenarios Docker is suitable for. In addition, this authoritative guide to Docker introduces the basic knowledge of its components, and then uses Docker to build containers and services to complete various tasks: use Docker to establish a test environment for new projects, demonstrate how to integrate Docker using continuously integrated workflow, how to build application services and platforms, how to use Docker's API, and how to extend Docker.

It includes nine chapters: introduction, installing Docker, getting started with Docker, using Docker image and warehouse, using Docker in testing, using Docker to build services, using Fig to configure Docker, using Docker API, getting help and improving Docker.

The "K8S+Docker learning guide" strongly recommended by Ali - Kubernetes in simple terms: Theory + practice and authoritative guide - the first Docker book are described in two words after reading. I love it!

CodeChina open source project: [analysis of Java interview questions of front-line large manufacturers + core summary learning notes + latest explanation Video]

Separator**

close: indicates the statement that traverses the splicing for the last time

Note: if the method parameter is an array type, the default parameter name is array. If the method parameter is a list set, the default parameter name is list. It is recommended that parameters of array or collection types be named with the @ Param annotation.

6.6,choose,when,otherwise

When we don't want to use all the conditions, but just want to choose one from multiple conditions. You can use the choose series label. Similar to switch in java.

For example:

  1. Methods in the interface are defined as follows
public interface UserDao{

    

    List<User> selectChose(User user);

    

}



expect:

If the id of the user object is not empty, query through the id.

If id is null and username is not null, query through username.

If both id and username are null, query the user with id 3

  1. The xml Mapping file is as follows
<select id="selectChose" resultType="com.sangeng.pojo.User">

    select * from user

    <where>

        <choose>

            <when test="id!=null">

                id = #{id}

            </when>

            <when test="username!=null">

                username = #{username}

            </when>

            <otherwise>

                id = 3

            </otherwise>

        </choose>

    </where>

</select>



last

Authoritative guide - the first Docker book

Lead the installation, deployment, management and expansion of Docker, let it go through the whole development life cycle from test to production, and deeply understand what scenarios Docker is suitable for. In addition, this authoritative guide to Docker introduces the basic knowledge of its components, and then uses Docker to build containers and services to complete various tasks: use Docker to establish a test environment for new projects, demonstrate how to integrate Docker using continuously integrated workflow, how to build application services and platforms, how to use Docker's API, and how to extend Docker.

It includes nine chapters: introduction, installing Docker, getting started with Docker, using Docker image and warehouse, using Docker in testing, using Docker to build services, using Fig to configure Docker, using Docker API, getting help and improving Docker.

[external chain picture transferring... (img-7fzhTzhN-1630834319416)]

[external chain picture transferring... (img-T2BCV3gd-1630834319418)]

[external chain picture transferring... (img-Sja8iB5U-1630834319419)]

[external chain picture transferring... (img-XEGc6dON-1630834319421)]

The "K8S+Docker learning guide" strongly recommended by Ali - Kubernetes in simple terms: Theory + practice and authoritative guide - the first Docker book are described in two words after reading. I love it!

CodeChina open source project: [analysis of Java interview questions of front-line large manufacturers + core summary learning notes + latest explanation Video]

Keywords: Java Database SQL Back-end Programmer

Added by chodges on Wed, 15 Dec 2021 08:33:06 +0200