Getting started with MyBatis for Java

First, you know what a framework is:

         Framework is the reusable design of the whole or part of the system, which is expressed as a group of abstract components and the method of interaction between component instances; Another definition holds that a framework is an application skeleton that can be customized by application developers. The former is defined from the aspect of application, while the latter is defined from the aspect of purpose. In short, the framework is a semi-finished product of software. Our developers use the framework to develop, which is simpler and improves the development efficiency.

Learn what MyBatis is:

        The official introduction is: MyBatis is an excellent persistence layer framework, which supports custom SQL, stored procedures and advanced mapping. MyBatis eliminates almost all JDBC code and the work of setting parameters and obtaining result sets. MyBatis can configure and map primitive types, interfaces and Java POJO s (Plain Old Java Objects) to records in the database through simple XML or annotations. In short, it is a framework of persistence layer, which encapsulates JDBC. Operation database. Official website: mybatis – MyBatis 3 | Introduction

Preparation environment:

Database:

CREATE TABLE user(
		uid int PRIMARY KEY auto_increment,
		username varchar(40),
	 	sex varchar(10),
		birthday date,
		address varchar(40)
);

INSERT INTO `user` VALUES (null, 'zs', 'male', '2021-09-08', 'Beijing');
INSERT INTO `user` VALUES (null, 'ls', 'female', '2021-09-30', 'Shenzhen');
INSERT INTO `user` VALUES (null, 'ww', 'male', '2021-09-08', 'Shanghai');

Maven for creation

tomcat:tomcat7

Idea: version 2020.1.3

Version 1.8 for jdk

Simple query cases using mybatis:

  1. Create Maven project (java) and add the dependent coordinates of mybatis

  2. Create pojo (java bean)

  3. Create UserDao interface

  4. Create UserDao mapping file (xml configuration file)

  5. Create MyBatis core configuration file SqlMapConfig.xml (XML configuration file)

  6. Writing java code tests

1. Add dependency

    <!--1. Add dependency-->
    <dependencies>
        <!--unit testing -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
        <!--MyBatis coordinate-->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.4.6</version>
        </dependency>
        <!--mysql drive-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.47</version>
        </dependency>
        <!--lombok rely on-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.18</version>
        </dependency>

2. Create pojo (java bean)

@Data
@NoArgsConstructor
@AllArgsConstructor
public class User implements Serializable {
    private int uid;
    private String username;
    private String sex;
    private Date birthday;
    private String address;
}

3. Create UserDao interface

public interface UserDao {
    /**
     * Query all users
     * @return
     */
    List<User> FindAll();
}

4. Create UserDao mapping file (xml configuration file)

Note: a slash is required here, not like a bag. (DOT).

<?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.demon.dao.UserDao">
<!--Query all users-->
    <select id="FindAll" resultType="com.demon.bean.User" >
            SELECT * FROM user
    </select>
</mapper>

5. Create MyBatis core configuration file SqlMapConfig.xml (XML configuration file)

Don't remember the top part of the code in steps 4 and 5. You can copy it on the official website or elsewhere or below, but it's not the same to distinguish the MyBatis core configuration file from the beginning of Dao's mapping file

Label: environments: used to configure the environment. It can define multiple environments and use   Environment
                Which environment is used depends on which is written in the default attribute   id value of environment
                Environment: used to define the environment,
                        id: declare an id, unique id
                        Transaction manager: transaction administrator
                        dataSource: use or not use connection pool

<?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">
<!--MyBatis Core profile for configuration It's the root tag-->
<configuration>
    <!--Database environment configuration-->
    <environments default="en">
        <environment id="en">
            <!--MyBatis The transaction management of is JDBC Transaction control-->
            <transactionManager type="JDBC"/>
            <!--MyBatis Connection pool configuration usage MyBatis default POOLED-->
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                                                                            <!--Database name-->
                <property name="url" value="jdbc:mysql://localhost:3306/userbe"/>
                                            <!--Database account-->
                <property name="username" value="root"/>
                                            <!--Database password-->
                <property name="password" value="123456"/>
            </dataSource>
        </environment>
    </environments>
    <!--mappers Corresponding dao Interface mapping file-->
    <!--introduce dao Interface mapping file-->
    <mappers>
        <mapper resource="com/demon/dao/UserDao.xml"/>
    </mappers>
</configuration>

Note: the place and name of Dao interface and Dao mapping file should be the same. The core configuration file needs to be placed under resources, and the name should be SqlMapConfig.xml.

  7. Write java code test (the format suggestion can be as simple and clear as the above figure)

It should be noted that the unit test on the figure says that in Maven project or environment, he will think that your test class name should have the word test, so it is generally recommended to use testxxx, which is simple and clear and does not need to write notes. Otherwise, the unit test will not be printed when running. (when importing mybatis package, that is, Resources: org.apache.ibatis.io, because the ibatis name used by Apache Company when creating mybatis in the early days was later changed to mybatis, but the ibatis name used all the time was not changed later)

import com.demon.bean.User;
import com.demon.dao.UserDao;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Test;

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


public class TestUserDao {
    //Query all users
    @Test
    public void testFindAll() throws IOException {
        //1. Read the core configuration file
        InputStream is = Resources.getResourceAsStream("SqlMapConfig.xml");
        //2. Create builder
        SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
        //3. Create SqlSessionFactory factory using builder
        SqlSessionFactory sqlSessionFactory = builder.build(is);
        //4. Ask the factory for the SqlSession object
        SqlSession sqlSession = sqlSessionFactory.openSession();
        //5. Ask the SqlSession object for the proxy object of UserDao
        UserDao userDao = sqlSession.getMapper(UserDao.class);
        //6. Call method directly
        List<User> list = userDao.FindAll();
        for(User user:list){
            System.out.println(user);
        }
        //7. Close sqlSession
        sqlSession.close();
    }
}

Print results:

 

Note: it is normal to print so many red ones because I use the dependency of printing logs.

Database:

 --------------------------------------------------------------------------------------------------------------------------------

It is found that some code can be encapsulated in the unit test class, so the extraction of SqlSessionFactory tool class.

Note: for tool class commit transactions, commit transactions: mybatis does not commit transactions by default. It sets setAutoCommit(false), so remember to commit transactions for addition, deletion and modification operations.

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import java.io.IOException;
import java.io.InputStream;

public class SqlSessionFactoryUtils {
    private static SqlSessionFactory sqlSessionFactory =null;
    //Static code blocks are used so that there is only one factory
    static {
        try {
            //Read core configuration file
            InputStream is = Resources.getResourceAsStream("SqlMapConfig.xml");
            //Create builder
            SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
            //Creating a SqlSessionFactory factory using the builder
            sqlSessionFactory = builder.build(is);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * Get SqlSession object
     * @return
     */
    public static SqlSession getsqlSession(){
        //Ask factory for SqlSession object
        return sqlSessionFactory.openSession();
    }

    /**
     *Close sqlSession commit transaction
     * @param sqlSession
     */
    public static void commit(SqlSession sqlSession){
        sqlSession.commit();
        sqlSession.close();
    }

    /**
     *Close sqlSession
     * @param sqlSession
     */
    public static void close(SqlSession sqlSession){
        sqlSession.close();
    }
}

Complete CRUD using Mybatis:

Add users:

UserDao interface:

/**
     * Add user
     * @param user
     * @return Number of rows affected
     */
    int AddUser(User user);

   Userdao.xml (mapping file of Dao interface):

<insert id="AddUser" parameterType="com.demon.bean.User" keyProperty="uid" >
        INSERT INTO user VALUES(null , #{username} , #{sex} , #{birthday} , #{address})
</insert>

  Unit test:

//Add a user
    @Test
    public void testAddUser() throws IOException {
        SqlSession sqlSession = SqlSessionFactoryUtils.getsqlSession();
        //Ask the SqlSession object for the proxy object of UserDao
        UserDao userDao = sqlSession.getMapper(UserDao.class);
        //Direct call method
        User user = new User();
        user.setUsername("zs1");
        user.setSex("male");
        user.setBirthday(new Date());
        user.setAddress("Shenzhen");
        userDao.AddUser(user);
        //Close sqlsession and commit transaction
        SqlSessionFactoryUtils.commit(sqlSession);
    }

1. To add a user, you should note that there are two ways to return the added id (you can copy the top code without writing the top code, and put the key code in it)

1.1 add with SelectKey tag

<!--Add user-->
    <insert id="AddUser" parameterType="com.demon.bean.User" keyProperty="uid" >
        INSERT INTO t_user VALUES(null , #{username} , #{sex} , #{birthday} , #{address})
          

        <!--
        selectKey: It is mainly used to obtain the primary key id
                    keyProperty : Use parameters user What attribute in it receives the primary key value
                    resultType:  What type of attribute receives the primary key
                    order: Only two values can be written: before | after
                        BEFORE:   Execute acquisition first id And then perform the operation of adding data
                        AFTER : First perform the add operation, and then perform the get operation id Operation of.
        -->
        <selectKey keyProperty="uid" resultType="int" order="AFTER">
            <!--You don't need to know more about the entry stage-->
            SELECT LAST_INSERT_ID()
        </selectKey>
    </insert>

1.2. Configuring with attributes  

 <!--
        Add user, get id Primary key return
            keyProperty : Indicates that parameters are used user What attribute in the object receives the primary key id
            useGeneratedKeys: 
                true: Use the database to create self incrementing generated data id value
                false: Not created with a database id Value, by mybatis Generate it yourself id Value.
     -->
<insert id="AddUser" parameterType="com.demon.bean.User" keyProperty="uid" useGeneratedKeys="true">
        INSERT INTO t_user VALUES(null , #{username} , #{sex} , #{birthday} , #{address})
</insert>

2. The primary key is not necessarily of int type... The primary key can also be of string type. When there are database consolidation and database clustering.

The primary key of string type is usually a string of 32 characters generated by UUID. Database merge!

<!--Add user, get id The primary key returns, but the primary key is a string type primary key-->
    <insert id="AddUser" parameterType="com.demon.bean.User" >
        
    INSERT INTO t_user VALUES(null , #{username} , #{sex} , #{birthday} , #{address})

        <selectKey keyProperty="myId" resultType="String" order="BEFORE">
            select uuid()
        </selectKey>
    </insert>

  Delete user:

UserDao interface:

/**
     * Delete a user
     * @param id
     * @return
     */
    int deleteUser(int id);

  Userdao.xml (mapping file of Dao interface):

<!--delete user-->
    <delete id="deleteUser" parameterType="int">
        delete from user where uid=#{uid}
    </delete>

Unit test:

//Delete a user
    @Test
    public void testdeleteUser() throws IOException {
        SqlSession sqlSession = SqlSessionFactoryUtils.getsqlSession();
        //5. Ask the SqlSession object for the proxy object of UserDao
        UserDao userDao = sqlSession.getMapper(UserDao.class);
        //6. Call method directly
        userDao.deleteUser(4);
        //Close sqlsession and commit transaction
        SqlSessionFactoryUtils.commit(sqlSession);
    }

Modify user: you need to query the user according to the id before modifying

UserDao interface:

public interface UserDao {
/**
     * Query a user
     * @return Number of rows affected
     */
    User FindUser(int uid);
    /**
     * Modify user
     * @param user
     * @return
     */
    int updateUser(User user);
}

  Userdao.xml (mapping file of Dao interface):

<!--Find a user information-->
    <select id="FindUser" resultType="com.demon.bean.User" parameterType="int">
        SELECT * FROM user WHERE uid=#{uid}
    </select>
<!--Modify user-->
    <update id="updateUser" parameterType="com.demon.bean.User">
        update user set username=#{username} , sex=#{sex} , birthday=#{birthday} , address=#{address} where uid=#{uid}
    </update>

Unit test: remember to commit the transaction, otherwise the database will not change the information

public class TestUserDao {
//Modify user
    @Test
    public void testupdateUser() throws IOException {
        SqlSession sqlSession = SqlSessionFactoryUtils.getsqlSession();
        UserDao userDao = sqlSession.getMapper(UserDao.class);
        //Direct call method
        User user = userDao.FindUser(1);
        user.setUsername("Wang Wu");
        int i = userDao.updateUser(user);
        System.out.println(i);
        //Close sqlsession and commit transaction
        SqlSessionFactoryUtils.commit(sqlSession);
    }
}

Query user:

There are the following situations:

1. Query a statement (parameters: id,name...)

        1.1. One parameter (#{} and ${} are different after the query code)

                1.1.1#{} 

                1.1.2${}

        1.2 multiple parameters

        1.3 there are multiple parameters with different types (Note: parameterType can not be assigned)

UserDao interface:

/**
     * Query a user
     * @return Number of rows affected
     */

    //General query a statement
    //id query
    User FindUser(int uid);

    //String query
    User FindUser7(String user)
;
    //Alias with @ Param annotation provided by mybatis
    User FindUser5(@Param("username") String username,@Param("sex") String sex);

Userdao.xml (mapping file of Dao interface):

<!--Find a user information-->
    
    <!--use id query-->
    <select id="FindUser" resultType="com.demon.bean.User" parameterType="int">
        SELECT * FROM user WHERE uid=#{uid}
    </select>
    
    <!--Or use#{} or ${value} query -- >
    <select id="FindUser7" resultType="com.demon.bean.User" parameterType="string">
        SELECT * FROM user WHERE username=#{username}
        <!--Or use ${value}Query note: ${}Internal must be value Otherwise, an error is reported
        SELECT * FROM user WHERE username='${value}'
        -->
    </select>
 
    <!--When using alias to query a piece of data for multiple parameters, if the parameters are of different types, you can not give them directly parameterType assignment>
    <select id="FindUser5" resultType="com.demon.bean.User" parameterType="string"> 
        select * from user where username=#{username} and sex=#{sex}
    </select>
    
    

Unit test:

@Test
    public void testFindUser() throws IOException {
        SqlSession sqlSession = SqlSessionFactoryUtils.getsqlSession();
        //Ask the SqlSession object for the proxy object of UserDao
        UserDao userDao = sqlSession.getMapper(UserDao.class);

        //Direct call method
        //Query with id

        User user= userDao.FindUser(1);
        //Query with string
        //User = userdao. Finduser7 ("Wang Wu");
     
        //When querying multiple parameters of a piece of data
        //User = userdao. Finduser5 ("Wang Wu", "male");

        
        System.out.println(user);
        //7. Close sqlSession
        SqlSessionFactoryUtils.close(sqlSession);
    }

2. Query multiple statements

3. Fuzzy query: 4 types

          3.1 external splicing% method

          3.2 add% method in SQL statement

                 3.2.1"%"#{}"%"

                 3.2.2"%${}%"

                  3.2.3concat("%",#{},"%")   (recommended)

UserDao interface:

/**
     * Fuzzy query
     * @param
     * @return
     */
    List<User> FindUser1(String username);
    List<User> FindUser2(String username);
    List<User> FindUser3(String username);

  Userdao.xml (mapping file of Dao interface):

<!--Fuzzy query-->

    <!--use concat()-->
    <select id="FindUser1" parameterType="string" resultType="com.demon.bean.User">
        select * from t_user where username like concat("%",#{username},"%")
    </select>

    <!--use#{}-->
    <select id="FindUser2" parameterType="string" resultType="com.demon.bean.User">
        select * from user where username like "%"#{username}"%"
    </select>

    <!--use ${}-->
    <select id="FindUser3" resultType="com.demon.bean.User" parameterType="com.demon.bean.User">
        <!--
        It must be written in the following format, otherwise an error will be reported
           That is, single quotation marks or double quotation marks, causing the middle content
           ${}Internal must also be value Otherwise, an error is reported
        -->
        select * from user where username like '%${value}%'
    </select>

Unit test: (it can be verified by changing the method name)

//Fuzzy query
    @Test
    public void testFindUser1() throws IOException {
        SqlSession sqlSession = SqlSessionFactoryUtils.getsqlSession();
        //5. Ask the SqlSession object for the proxy object of UserDao
        UserDao userDao = sqlSession.getMapper(UserDao.class);
        //6. Call method directly
        List<User> list = userDao.FindUser3("a");
        System.out.println(list);
        //7. Close sqlSession
        SqlSessionFactoryUtils.close(sqlSession);
    }

be careful:  # Difference between {} and ${}

  1. #{} represents a placeholder

    • Through #{} this method, you can set the value in the placeholder for the preparedStatement, and automatically convert java type and database type

    • #{} can effectively prevent sql injection

    • #{} can receive simple type values or pojo attribute values

    • If parameterType transfers a single simple type value (String, basic type), #{} value or other name can be in parentheses.

  2. ${} represents a concatenated sql string

    • Through ${}, the content passed in by parameterType can be spliced in sql without jdbc type conversion

    • ${} does not prevent sql injection

    • ${} can receive simple type values or pojo attribute values

    • If parameterType transfers a single simple type value. ${} can only be value in parentheses

=====The above is Xiaobai's understanding of my introduction to mybatis. If there is any mistake, I hope I can point it out for me. QAQ=====

The following is also a mind map I made with xmind:  

 

Keywords: Java Maven Mybatis Tomcat

Added by scross on Wed, 15 Sep 2021 02:23:51 +0300