Basic usage of Mybatis entry learning

Table of contents

Chapter 1 Preface

1. Overall technical system

①Single architecture

②Distributed architecture

2. The concept of framework

3. Mybatis history

4. Mybatis download address

5. Mybatis features

6. Comparison with other persistence layer technologies

Chapter 2 Basic usage of Mybatis 

Section 1 HelloWorld

1. Physical modeling

2. Logic modeling

①Create Maven module

②Create Java entity class

3. Build a framework development environment

①Import dependencies

②Prepare configuration file

4. junit test code

5. Correct a misunderstanding

①Misunderstanding

②Illustration

③Source code

Section 2 HelloWorld Enhancement

1. Add log

①Purpose

②Operation

③Log level

④STDOUT

⑤Print effect

2. Associate external property files

①Demand

②How to do

3. Use the Mapper interface

①Thinking

②Adjust junit code

③ Complete the Mapper interface

④Final junit testing method

4. Add, delete, and modify operations

①insert

②delete

③update

Section 3 Passing parameters to SQL statements

1. #{}method

2. ${} method

①SQL statement

②Mapper interface

③junit test

④The actual printed SQL

⑤Examples of application scenarios

Section 4 Data Input

1. Summary of the overall mechanism of Mybatis

2. Concept description

3. A single simple type parameter

①Declaration of abstract methods in Mapper interface

②SQL statement

4. Entity class type parameters

①Declaration of abstract methods in Mapper interface

②SQL statement

③Correspondence

④Conclusion

5. Scattered simple type data

①Declaration of abstract methods in Mapper interface

②SQL statement

③Correspondence

6. Map type parameters

①Declaration of abstract methods in Mapper interface

②SQL statement

③junit test

④Correspondence

⑤Usage scenarios

Section 5 Data Output

1. Return a single simple type data

①Abstract methods in Mapper interface

②SQL statement

③junit test

2. Return entity class object

①Abstract method of Mapper interface

②SQL statement

③Add global configuration to automatically identify corresponding relationships

3. Return Map type

①Abstract method of Mapper interface

②SQL statement

③junit test

4. Return List type

①Abstract methods in Mapper interface

②SQL statement

③junit test

5. Return to the auto-increment primary key

①Usage scenario

②Set the method in the Mapper configuration file

④Attention

⑤Databases that do not support auto-incrementing primary keys

6. Correspondence between database table fields and entity class attributes

①Alias

②Global configuration automatically recognizes camel case naming rules

③Use resultMap


Chapter 1 Preface

1. Overall technical system

①Single architecture

A project, a project, is exported as a war package and run on a Tomcat. Also called all in one.

②Distributed architecture

A project (corresponding to a project in IDEA) is divided into many modules, each module is a module in IDEA. Each project runs on its own Tomcat. Modules can call each other. Each module can be viewed internally as a single-architecture application.

2. The concept of framework

Framework = jar package + configuration file

3. Mybatis history

MyBatis was originally iBatis, an open source project of Apache. In June 2010, this project was migrated to Google Code by the Apache Software Foundation. As the development team moved to Google Code, iBatis3.x was officially renamed MyBatis. The code was migrated to Github in November 2013.

The word iBatis comes from the combination of "internet" and "abatis" and is a persistence layer framework based on Java. The persistence layer framework provided by iBatis includes SQL Maps and Data Access Objects (DAO).

4. Mybatis download address

https://github.com/mybatis/mybatis-3

5. Mybatis features

  • MyBatis supports customized SQL, stored procedures and advanced mapping
  • MyBatis avoids almost all JDBC code and manual parameter setting and result set parsing operations
  • MyBatis can use simple XML or annotations to implement configuration and original mapping; map interfaces and Java POJO (Plain Ordinary Java Object, ordinary Java objects) into records in the database
  • Mybatis is a semi-automatic ORM (Object Relation Mapping) framework

6. Comparison with other persistence layer technologies

  • JDBC
    • SQL is mixed in Java code with a high degree of coupling, causing internal damage to hard coding.
    • Maintenance is difficult and SQL changes in actual development requirements, and frequent modifications are common.
    • Long code and low development efficiency
  • Hibernate and JPA
    • Easy to operate and high development efficiency
    • Long and complex SQL in the program needs to bypass the framework
    • The SQL automatically generated internally is not easy to perform special optimization.
    • Based on the fully automatic framework of full mapping, it is difficult to partially map POJOs with a large number of fields.
    • Too many reflection operations cause database performance to degrade
  • MyBatis
    • Lightweight, great performance
    • SQL and Java coding are separated and functional boundaries are clear. Java code focuses on business, SQL statements focus on data
    • The development efficiency is slightly lower than HIbernate, but it is completely acceptable.

Chapter 2 Basic usage of Mybatis 

Section 1 HelloWorld

1. Physical modeling

CREATE DATABASE `mybatis-example`;

USE `mybatis-example`;

CREATE TABLE `t_emp`(
emp_id INT AUTO_INCREMENT,
emp_name CHAR(100),
emp_salary DOUBLE(10,5),
PRIMARY KEY(emp_id)
);

INSERT INTO `t_emp`(emp_name,emp_salary) VALUES("tom",200.33);
INSERT INTO `t_emp`(emp_name,emp_salary) VALUES("jerry",666.66);
INSERT INTO `t_emp`(emp_name,emp_salary) VALUES("andy",777.77);

2. Logic modeling

①Create Maven module

②Create Java entity class

Entity classes correspond to a specific or abstract concept in the real world. They are models designed to manage data in the real world during the software development process.

Several different names for entity classes:

domain: domain model

entity: entity

POJO:Plain Old Java Object

Java bean: a Java class

/**
 * 和数据库表 t_emp 对应的实体类
 * emp_id INT AUTO_INCREMENT
 * emp_name CHAR(100)
 * emp_salary DOUBLE(10,5)
 *
 * Java 的实体类中,属性的类型不要使用基本数据类型,要使用包装类型。因为包装类型可以赋值为null,表示空,而基本数据类型不可以。
 */
public class Employee {
    
    private Integer empId;
    
    private String empName;
    
    private Double empSalary;
    
    public Employee() {
    
    }
    
    public Integer getEmpId() {
        return empId;
    }
    
    public void setEmpId(Integer empId) {
        this.empId = empId;
    }
    
    public String getEmpName() {
        return empName;
    }
    
    public void setEmpName(String empName) {
        this.empName = empName;
    }
    
    public Double getEmpSalary() {
        return empSalary;
    }
    
    public void setEmpSalary(Double empSalary) {
        this.empSalary = empSalary;
    }
    
    @Override
    public String toString() {
        return "Employee{" +
                "empId=" + empId +
                ", empName='" + empName + '\'' +
                ", empSalary=" + empSalary +
                '}';
    }
    
    public Employee(Integer empId, String empName, Double empSalary) {
        this.empId = empId;
        this.empName = empName;
        this.empSalary = empSalary;
    }
}

3. Build a framework development environment

①Import dependencies

<dependencies>
    <!-- Mybatis核心 -->
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis</artifactId>
        <version>3.5.7</version>
    </dependency>
    
    <!-- junit测试 -->
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
        <scope>test</scope>
    </dependency>
    
    <!-- MySQL驱动 -->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.3</version>
    </dependency>
</dependencies>

②Prepare configuration file

[1]Mybatis global configuration file

It is customary to name it mybatis-config.xml. This file name is only a suggestion and not a requirement. After Spring is integrated in the future, this configuration file can be omitted, so you can copy and paste it directly during operation.

<?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>
    
    <!-- environments表示配置Mybatis的开发环境,可以配置多个环境,在众多具体环境中,使用default属性指定实际运行时使用的环境。default属性的取值是environment标签的id属性的值。 -->
    <environments default="development">
        <!-- environment表示配置Mybatis的一个具体的环境 -->
        <environment id="development">
    
            <!-- Mybatis的内置的事务管理器 -->
            <transactionManager type="JDBC"/>
    
            <!-- 配置数据源 -->
            <dataSource type="POOLED">
    
                <!-- 建立数据库连接的具体信息 -->
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/mybatis-example"/>
                <property name="username" value="root"/>
                <property name="password" value="atguigu"/>
            </dataSource>
        </environment>
    </environments>
    
    <mappers>
        <!-- Mapper注册:指定Mybatis映射文件的具体位置 -->
        <!-- mapper标签:配置一个具体的Mapper映射文件 -->
        <!-- resource属性:指定Mapper映射文件的实际存储位置,这里需要使用一个以类路径根目录为基准的相对路径 -->
        <!--    对Maven工程的目录结构来说,resources目录下的内容会直接放入类路径,所以这里我们可以以resources目录为基准 -->
        <mapper resource="mappers/EmployeeMapper.xml"/>
    </mappers>
</configuration>

Note: The configuration file is stored in the src/main/resources directory.

[2]Mybatis mapping file

Related concepts: ORM (Object Relationship Mapping) object relationship mapping.

  • Object: Java entity class object
  • Relational: relational database
  • Mapping: the correspondence between the two

The following table lists the simplest single table mapping (one table and one class):

Java concepts Database concepts
kind surface
Attributes Field/Column
object record/row

<?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属性:在Mybatis全局范围内找到一个具体的Mapper配置 -->
<!-- 引入接口后,为了方便通过接口全类名来找到Mapper配置文件,所以通常将namespace属性设置为接口全类名 -->
<mapper namespace="com.atguigu.mybatis.dao.EmployeeMapper">

    <!-- 编写具体的SQL语句,使用id属性唯一的标记一条SQL语句 -->
    <!-- resultType属性:指定封装查询结果的Java实体类的全类名 -->
    <select id="selectEmployee" resultType="com.atguigu.mybatis.entity.Employee">
        <!-- Mybatis负责把SQL语句中的#{}部分替换成“?”占位符,在#{}内部还是要声明一个见名知意的名称 -->
        select emp_id empId,emp_name empName,emp_salary empSalary from t_emp where emp_id=#{empId}
    </select>
</mapper>

Note: The directory where EmployeeMapper.xml is located must be consistent with the one configured using the mapper tag in mybatis-config.xml.

4. junit test code

@Test
public void testSelectEmployee() throws IOException {
    
    // 1.创建SqlSessionFactory对象
    // ①声明Mybatis全局配置文件的路径
    String mybatisConfigFilePath = "mybatis-config.xml";
    
    // ②以输入流的形式加载Mybatis配置文件
    InputStream inputStream = Resources.getResourceAsStream(mybatisConfigFilePath);
    
    // ③基于读取Mybatis配置文件的输入流创建SqlSessionFactory对象
    SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
    
    // 2.使用SqlSessionFactory对象开启一个会话
    SqlSession session = sessionFactory.openSession();
    
    // 3.根据Mapper配置文件的名称空间+SQL语句的id找到具体的SQL语句
    // 格式是:名称空间.SQL语句的id
    String statement = "com.atguigu.mybatis.dao.EmployeeMapper.selectEmployee";
    
    // 要传入SQL语句的参数
    Integer empId = 1;
    
    // 执行SQL语句
    Object result = session.selectOne(statement, empId);
    
    System.out.println("o = " + result);
    
    // 4.关闭SqlSession
    session.close();
}

illustrate:

  • SqlSession: Represents the session between the Java program and the database. (HttpSession is the session between the Java program and the browser)
  • SqlSessionFactory: It is the "factory" that "produces" SqlSession.
  • Factory pattern: If the process used to create an object is basically fixed, then we can encapsulate the relevant code for creating this object into a "factory class", and use this factory class to "produce" the objects we need in the future.

5. Correct a misunderstanding

①Misunderstanding

When we first come into contact with the framework, we will think that the Java program will be transferred to the XML configuration file for execution, but in fact the framework will read the XML file during initialization, encapsulate it into an object, and then all Java code will be executed, XML The configuration in cannot be executed.

②Illustration

③Source code

[1] Encapsulate Configuration object

Class: org.apache.ibatis.session.defaults.DefaultSqlSessionFactory

[2] Prepare to obtain mapped instructions

Class: org.apache.ibatis.session.defaults.DefaultSqlSession

[3] Officially obtain the mapped instructions

Class: org.apache.ibatis.session.Configuration

[4]mappedStatements object structure

Type of mappedStatements object: A static inner class in the Configuration class: StrictMap

Section 2 HelloWorld Enhancement

1. Add log

①Purpose

During the working process of Mybatis, the SQL statements to be executed are printed out by printing logs.

②Operation

[1]Add dependencies

<!-- log4j日志 -->
<dependency>
    <groupId>log4j</groupId>
    <artifactId>log4j</artifactId>
    <version>1.2.17</version>
</dependency>

[2] Add log4j configuration file

Supports both XML and properties files. Regardless of which form is used, the filename is fixed:

  • log4j.xml
  • log4j.properties
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
    
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
    
    <appender name="STDOUT" class="org.apache.log4j.ConsoleAppender">
        <param name="Encoding" value="UTF-8" />
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern" value="%-5p %d{MM-dd HH:mm:ss,SSS} %m  (%F:%L) \n" />
        </layout>
    </appender>
    <logger name="java.sql">
        <level value="debug" />
    </logger>
    <logger name="org.apache.ibatis">
        <level value="info" />
    </logger>
    <root>
        <level value="debug" />
        <appender-ref ref="STDOUT" />
    </root>
</log4j:configuration>

③Log level

FATAL(fatal)>ERROR(error)>WARN(warning)>INFO(information)>DEBUG(debug)

Content printed from left to right becomes increasingly detailed

④STDOUT

It is the abbreviation of standard output, which means standard output. For Java programs, printing to standard output means printing to the console.

⑤Print effect

DEBUG 05-24 18:51:13,331 ==> Preparing: select emp_id empId,emp_name empName,emp_salary empSalary from t_emp where emp_id=? (BaseJdbcLogger.java:137) DEBUG 05-24 18:51:13,371 ==> Parameters: 1(Integer) (BaseJdbcLogger.java:137) DEBUG 05-24 18:51:13,391 <== Total: 1 (BaseJdbcLogger.java:137) o = Employee{empId=1, empName='tom', empSalary=200.33}

2. Associate external property files

①Demand

In actual development, the same set of code often corresponds to multiple different specific server environments. The database connection parameters used are also different. In order to better maintain this information, we recommend extracting the database connection information outside the Mybatis global configuration file.

②How to do

Create jdbc.properties configuration file

wechat.dev.driver=com.mysql.jdbc.Driver
wechat.dev.url=jdbc:mysql://192.168.198.100:3306/mybatis-example
wechat.dev.username=root
wechat.dev.password=atguigu
    
wechat.test.driver=com.mysql.jdbc.Driver
wechat.test.url=jdbc:mysql://192.168.198.150:3306/mybatis-example
wechat.test.username=root
wechat.test.password=atguigu
    
wechat.product.driver=com.mysql.jdbc.Driver
wechat.product.url=jdbc:mysql://192.168.198.200:3306/mybatis-example
wechat.product.username=root
wechat.product.password=atguigu

Specify the location of the external jdbc.properties file in the Mybatis global configuration file

<properties resource="jdbc.properties"/>

When specific attribute values ​​are needed, use the ${key} format to reference the keys in the attribute file.

<dataSource type="POOLED">
    
    <!-- 建立数据库连接的具体信息(引用了外部属性文件中的数据) -->
    <property name="driver" value="${wechat.dev.driver}"/>
    <property name="url" value="${wechat.dev.url}"/>
    <property name="username" value="${wechat.dev.username}"/>
    <property name="password" value="${wechat.dev.password}"/>
    
</dataSource>

3. Use the Mapper interface

The Mapper interface in Mybatis is equivalent to the previous Dao. But the difference is that Mapper just builds an interface, and we don't need to provide an implementation class.

①Thinking

②Adjust junit code

public class ImprovedMybatisTest {
    
    private SqlSession session;
    
    // junit会在每一个@Test方法前执行@Before方法
    @Before
    public void init() throws IOException {
         session = new SqlSessionFactoryBuilder()
                 .build(
                         Resources.getResourceAsStream("mybatis-config.xml"))
                 .openSession();
    }
    
    // junit会在每一个@Test方法后执行@After方法
    @After
    public void clear() {
        session.commit();
        session.close();
    }
    
}

③ Complete the Mapper interface

public interface EmployeeMapper {
    
    Employee selectEmployee(Integer empId);
        
}
  • The method name is consistent with the SQL ID
  • The method return value is consistent with resultType
  • The parameters of the method are consistent with the parameters of SQL
  • The full class name of the interface is consistent with the name space of the mapping configuration file.

④Final junit testing method

@Test
public void testUsrMapperInterface() {
    
    // 1.根据EmployeeMapper接口的Class对象获取Mapper接口类型的对象
    EmployeeMapper employeeMapper = session.getMapper(EmployeeMapper.class);
        
    // 2.调用EmployeeMapper接口的方法完成对数据库的操作
    Emp emp = employeeMapper.selectEmployee(1L);
    
    // 3.打印查询结果
    System.out.println("emp = " + emp);
}

4. Add, delete, and modify operations

①insert

SQL statement

<insert id="insertEmployee">
    <!-- 现在在这条SQL语句中,#{}中的表达式需要被用来从Emp emp实体类中获取emp_name的值、emp_salary的值 -->
    <!-- 而我们从实体类中获取值通常都是调用getXxx()方法 -->
    <!-- 而getXxx()方法、setXxx()方法定义了实体类的属性 -->
    <!-- 定义属性的规则是:把get、set去掉,剩下部分首字母小写 -->
    <!-- 所以我们在#{}中使用getXxx()方法、setXxx()方法定义的属性名即可 -->
    insert into t_emp(emp_name,emp_salary) values(#{empName},#{empSalary})
</insert>

Mapper interface in Java code:

public interface EmployeeMapper {
    
    Employee selectEmployee(Integer empId);
    
    int insertEmployee(Employee employee);
}

junit test in java code:

@Test
public void testSaveEmployee() {
    
    EmployeeMapper employeeMapper = session.getMapper(EmployeeMapper.class);
    
    // 创建要保存到数据库的对象
    Employee employee = new Employee();
    
    // 给实体类对象设置具体属性值
    employee.setEmpName("jerry");
    employee.setEmpSalary(5000.33);
    
    // 执行保存操作
    int result = employeeMapper.insertEmployee(employee);
    
    // 打印受影响的行数
    System.out.println("result = " + result);
}

②delete

SQL statement

    <delete id="deleteEmployee">
        delete from t_emp where emp_id=#{empId}
    </delete>

Mapper interface in Java code:

public interface EmployeeMapper {
    
    Employee selectEmployee(Integer empId);
    
    int insertEmployee(Employee employee);
    
    int deleteEmployee(Integer empId);
}

junit test in java code:

@Test
public void testRemoveEmployee() {
    
    EmployeeMapper employeeMapper = session.getMapper(EmployeeMapper.class);
    
    int result = employeeMapper.deleteEmployee(1);
    
    System.out.println("result = " + result);
}

③update

SQL statement:

<update id="updateEmployee">
    update t_emp set emp_name=#{empName},emp_salary=#{empSalary} where emp_id=#{empId}
</update>

Mapper interface in Java code:

public interface EmployeeMapper {
    
    Employee selectEmployee(Integer empId);
    
    int insertEmployee(Employee employee);
    
    int deleteEmployee(Integer empId);
    
    int updateEmployee(Employee employee);
}

junit test in java code:

@Test
public void testUpdateEmployee() {
    
    EmployeeMapper employeeMapper = session.getMapper(EmployeeMapper.class);
    
    Employee employee = new Employee(2, "AAAAAA", 6666.66);
    
    int result = employeeMapper.updateEmployee(employee);
    
    System.out.println("result = " + result);
}

Section 3 Passing parameters to SQL statements

1. #{}method

During the running process, Mybatis will convert the #{} in the SQL statement in the configuration file into a "?" placeholder and send it to the database for execution.

SQL in configuration file:

<delete id="deleteEmployeeById">
    delete from t_emp where emp_id=#{empId}
</delete>

Actual executed SQL:

delete from t_emp where emp_id=?

2. ${} method

In the future, strings will be spelled based on ${}

①SQL statement

<select id="selectEmployeeByName" resultType="com.atguigu.mybatis.entity.Employee">
    select emp_id empId,emp_name empName,emp_salary empSalary from t_emp where emp_name like '%${empName}%'
</select>

②Mapper interface

Note: Since the method name in the Mapper interface is the id of the SQL statement label and cannot be repeated, methods with the same name cannot appear in the Mapper interface, and overloading is not allowed!

public interface EmployeeMapper {
    
    Employee selectEmployee(Integer empId);
    
    Employee selectEmployeeByName(@Param("empName") String empName);
    
    int insertEmployee(Employee employee);
    
    int deleteEmployee(Integer empId);
    
    int updateEmployee(Employee employee);
}

③junit test

@Test
public void testDollar() {
    
    EmployeeMapper employeeMapper = session.getMapper(EmployeeMapper.class);
    
    Employee employee = employeeMapper.selectEmployeeByName("r");
    
    System.out.println("employee = " + employee);
}

④The actual printed SQL

select emp_id empId,emp_name empName,emp_salary empSalary from t_emp where emp_name like '%r%'

⑤Examples of application scenarios

In the SQL statement, the table name of the database table is uncertain and needs to be dynamically passed in externally. At this time, #{} cannot be used because SQL syntax does not allow the use of question mark placeholders in the table name position. At this time, only ${} can be used.

In other cases, as long as #{} can be used, ${} must not be used to avoid SQL injection.

Section 4 Data Input

1. Summary of the overall mechanism of Mybatis

2. Concept description

Data input here specifically refers to the form in which data is passed in when the upper-layer method (such as the Service method) calls the Mapper interface.

  • Simple type: a data type that contains only one value
    • Basic data types: int, byte, short, double,…
    • Packaging types of basic data types: Integer, Character, Double,…
    • String type: String
  • Complex type: a data type that contains multiple values
    • Entity class types: Employee, Department,…
    • Collection types: List, Set, Map,…
    • Array type: int[], String[],…
    • Composite type: List<Employee>, entity class contains collection...

3. A single simple type parameter

①Declaration of abstract methods in Mapper interface

Employee selectEmployee(Integer empId);

②SQL statement

<select id="selectEmployee" resultType="com.atguigu.mybatis.entity.Employee">
    select emp_id empId,emp_name empName,emp_salary empSalary from t_emp where emp_id=#{empId}
</select>

4. Entity class type parameters

①Declaration of abstract methods in Mapper interface

int insertEmployee(Employee employee);

②SQL statement

<insert id="insertEmployee">
    insert into t_emp(emp_name,emp_salary) values(#{empName},#{empSalary})
</insert>

③Correspondence

④Conclusion

Mybatis will process the getXxx() method based on the data passed in #{}, and call this method in the entity class object through reflection to obtain the corresponding data. Fill in the #{} position.

5. Scattered simple type data

①Declaration of abstract methods in Mapper interface

int updateEmployee(@Param("empId") Integer empId,@Param("empSalary") Double empSalary);

②SQL statement

    <update id="updateEmployee">
        update t_emp set emp_salary=#{empSalary} where emp_id=#{empId}
    </update>

③Correspondence

6. Map type parameters

①Declaration of abstract methods in Mapper interface

int updateEmployeeByMap(Map<String, Object> paramMap);

②SQL statement

    <update id="updateEmployeeByMap">
        update t_emp set emp_salary=#{empSalaryKey} where emp_id=#{empIdKey}
    </update>

③junit test

@Test
public void testUpdateEmpNameByMap() {
    
    EmployeeMapper mapper = session.getMapper(EmployeeMapper.class);
    
    Map<String, Object> paramMap = new HashMap<>();
    
    paramMap.put("empSalaryKey", 999.99);
    paramMap.put("empIdKey", 5);
    
    int result = mapper.updateEmployeeByMap(paramMap);
    
    System.out.println("result = " + result);
}

④Correspondence

Write the key in the Map in {}

⑤Usage scenarios

There are many scattered parameters that need to be passed, but no corresponding entity class types can be used. Using @Param annotations to pass them in one by one is too cumbersome. So they are all encapsulated into Map.

Section 5 Data Output

TIP

Data output generally comes in two forms:

  • The number of affected rows returned by the addition, deletion and modification operations: just use the int or long type to receive it directly
  • Query results of query operations

1. Return a single simple type data

①Abstract methods in Mapper interface

int selectEmpCount();

②SQL statement

    <select id="selectEmpCount" resultType="int">
        select count(*) from t_emp
    </select>

③junit test

    @Test
    public void testEmpCount() {
    
        EmployeeMapper employeeMapper = session.getMapper(EmployeeMapper.class);
    
        int count = employeeMapper.selectEmpCount();
    
        System.out.println("count = " + count);
    }

TIP

Mybatis internally sets many aliases for commonly used data types. Taking the int type as an example, the names that can be written are: int, integer, Integer, java.lang.Integer, Int, INT, INTEGER, etc.

2. Return entity class object

①Abstract method of Mapper interface

Employee selectEmployee(Integer empId);

②SQL statement

<!-- 编写具体的SQL语句,使用id属性唯一的标记一条SQL语句 -->
<!-- resultType属性:指定封装查询结果的Java实体类的全类名 -->
<select id="selectEmployee" resultType="com.atguigu.mybatis.entity.Employee">
    <!-- Mybatis负责把SQL语句中的#{}部分替换成“?”占位符 -->
    <!-- 给每一个字段设置一个别名,让别名和Java实体类中属性名一致 -->
    select emp_id empId,emp_name empName,emp_salary empSalary from t_emp where emp_id=#{maomi}
</select>

By adding aliases to the database table fields, each column of the query result corresponds to the attributes in the Java entity class.

③Add global configuration to automatically identify corresponding relationships

In the Mybatis global configuration file, the following configuration is made. You do not need to set aliases for fields in the select statement.

<!-- 在全局范围内对Mybatis进行配置 -->
<settings>
    <!-- 具体配置 -->
    <!-- 从org.apache.ibatis.session.Configuration类中可以查看能使用的配置项 -->
    <!-- 将mapUnderscoreToCamelCase属性配置为true,表示开启自动映射驼峰式命名规则 -->
    <!-- 规则要求数据库表字段命名方式:单词_单词 -->
    <!-- 规则要求Java实体类属性名命名方式:首字母小写的驼峰式命名 -->
    <setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>

3. Return Map type

The fields returned by SQL queries do not correspond to any existing entity class and cannot be encapsulated into entity class objects. If it can be encapsulated into an entity class type, the Map type is not used.

①Abstract method of Mapper interface

Map<String,Object> selectEmpNameAndMaxSalary();

②SQL statement

<!-- Map<String,Object> selectEmpNameAndMaxSalary(); -->
<!-- 返回工资最高的员工的姓名和他的工资 -->
<select id="selectEmpNameAndMaxSalary" resultType="map">
        SELECT
            emp_name 员工姓名,
            emp_salary 员工工资,
            (SELECT AVG(emp_salary) FROM t_emp) 部门平均工资
        FROM t_emp WHERE emp_salary=(
            SELECT MAX(emp_salary) FROM t_emp
        )
</select>

③junit test

    @Test
    public void testQueryEmpNameAndSalary() {
    
        EmployeeMapper employeeMapper = session.getMapper(EmployeeMapper.class);
    
        Map<String, Object> resultMap = employeeMapper.selectEmpNameAndMaxSalary();
    
        Set<Map.Entry<String, Object>> entrySet = resultMap.entrySet();
    
        for (Map.Entry<String, Object> entry : entrySet) {
            String key = entry.getKey();
            Object value = entry.getValue();
            System.out.println(key + "=" + value);
        }
    }

4. Return List type

The query results return multiple entity class objects, and I hope to put multiple entity class objects in a List collection and return them. No special processing is required at this time, just set the entity class type in the resultType attribute.

①Abstract methods in Mapper interface

List<Employee> selectAll();

②SQL statement

    <!-- List<Employee> selectAll(); -->
    <select id="selectAll" resultType="com.atguigu.mybatis.entity.Employee">
        select emp_id empId,emp_name empName,emp_salary empSalary
        from t_emp
    </select>

③junit test

    @Test
    public void testSelectAll() {
    
        EmployeeMapper employeeMapper = session.getMapper(EmployeeMapper.class);
    
        List<Employee> employeeList = employeeMapper.selectAll();
    
        for (Employee employee : employeeList) {
            System.out.println("employee = " + employee);
        }
    
    }

5. Return to the auto-increment primary key

①Usage scenario

For example: save order information. The Order object and List<OrderItem> need to be saved. Among them, the database table corresponding to OrderItem contains a foreign key pointing to the primary key of the table corresponding to Order.

When saving List<OrderItem>, you need to use the following SQL:

insert into t_order_item(item_name,item_price,item_count,order_id) values(...)

The order_id that needs to be used here is generated by the database table in an auto-incrementing manner when saving the Order object. A special method is required to obtain this auto-incrementing primary key value. As for why this problem cannot be solved by querying the largest primary key, refer to the figure below:

②Set the method in the Mapper configuration file

[1]Abstract methods in Mapper interface

int insertEmployee(Employee employee);

[2]SQL statement

<!-- int insertEmployee(Employee employee); -->
<!-- useGeneratedKeys属性字面意思就是“使用生成的主键” -->
<!-- keyProperty属性可以指定主键在实体类对象中对应的属性名,Mybatis会将拿到的主键值存入这个属性 -->
<insert id="insertEmployee" useGeneratedKeys="true" keyProperty="empId">
    insert into t_emp(emp_name,emp_salary)
    values(#{empName},#{empSalary})
</insert>

[3]junit test

@Test
public void testSaveEmp() {
    
    EmployeeMapper employeeMapper = session.getMapper(EmployeeMapper.class);
    
    Employee employee = new Employee();
        
    employee.setEmpName("john");
    employee.setEmpSalary(666.66);
    
    employeeMapper.insertEmployee(employee);
    
    System.out.println("employee.getEmpId() = " + employee.getEmpId());
    
}

④Attention

Mybatis sets the value of the auto-incrementing primary key into the entity class object instead of returning it in the form of the return value of the Mapper interface method.

⑤Databases that do not support auto-incrementing primary keys

For databases that do not support auto-incrementing primary keys (such as Oracle), you can use the selectKey sub-element: the selectKey element will be run first, the id will be set, and then the insert statement will be called

<insert id="insertEmployee" 
		parameterType="com.atguigu.mybatis.beans.Employee"  
			databaseId="oracle">
		<selectKey order="BEFORE" keyProperty="id" 
                                       resultType="integer">
			select employee_seq.nextval from dual 
		</selectKey>	
		insert into orcl_employee(id,last_name,email,gender) values(#{id},#{lastName},#{email},#{gender})
</insert>

or

<insert id="insertEmployee" 
		parameterType="com.atguigu.mybatis.beans.Employee"  
			databaseId="oracle">
		<selectKey order="AFTER" keyProperty="id" 
                                         resultType="integer">
			select employee_seq.currval from dual 
		</selectKey>	
	insert into orcl_employee(id,last_name,email,gender) values(employee_seq.nextval,#{lastName},#{email},#{gender})
</insert>

6. Correspondence between database table fields and entity class attributes

①Alias

Set the field alias to be consistent with the entity class attribute.

<!-- 编写具体的SQL语句,使用id属性唯一的标记一条SQL语句 -->
<!-- resultType属性:指定封装查询结果的Java实体类的全类名 -->
<select id="selectEmployee" resultType="com.atguigu.mybatis.entity.Employee">
    <!-- Mybatis负责把SQL语句中的#{}部分替换成“?”占位符 -->
    <!-- 给每一个字段设置一个别名,让别名和Java实体类中属性名一致 -->
    select emp_id empId,emp_name empName,emp_salary empSalary from t_emp where emp_id=#{maomi}
</select>

Conventions about entity class attributes:

For the getXxx() method and setXxx() method, remove get or set from the method name, and lowercase the first letter.

②Global configuration automatically recognizes camel case naming rules

Add the following configuration to the Mybatis global configuration file:

<!-- 使用settings对Mybatis全局进行设置 -->
<settings>
    <!-- 将xxx_xxx这样的列名自动映射到xxXxx这样驼峰式命名的属性名 -->
    <setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>

Aliases do not need to be used in SQL statements

<!-- Employee selectEmployee(Integer empId); -->
<select id="selectEmployee" resultType="com.atguigu.mybatis.entity.Employee">
    select emp_id,emp_name,emp_salary from t_emp where emp_id=#{empId}
</select>

③Use resultMap

Use the resultMap tag to define the corresponding relationship, and then reference this corresponding relationship in subsequent SQL statements.

<!-- 专门声明一个resultMap设定column到property之间的对应关系 -->
<resultMap id="selectEmployeeByRMResultMap" type="com.atguigu.mybatis.entity.Employee">
    
    <!-- 使用id标签设置主键列和主键属性之间的对应关系 -->
    <!-- column属性用于指定字段名;property属性用于指定Java实体类属性名 -->
    <id column="emp_id" property="empId"/>
    
    <!-- 使用result标签设置普通字段和Java实体类属性之间的关系 -->
    <result column="emp_name" property="empName"/>
    <result column="emp_salary" property="empSalary"/>
</resultMap>
    
<!-- Employee selectEmployeeByRM(Integer empId); -->
<select id="selectEmployeeByRM" resultMap="selectEmployeeByRMResultMap">
    select emp_id,emp_name,emp_salary from t_emp where emp_id=#{empId}
</select>

Guess you like

Origin blog.csdn.net/weixin_52733693/article/details/127498693