Common Annotations
MyBatis is an excellent persistence layer framework that supports development through annotations without the need for traditional XML configuration files. This approach is more concise and intuitive, suitable for simple application scenarios or lightweight development projects.
Common Annotations:
- Insert - Insert
- Update - Update
- Delete - Delete
- Select - Query
- Result - Result set encapsulation
- Results - Used together with Result to encapsulate multiple result sets
- One - Implements one-to-one result encapsulation
- Many - Implements one-to-many result encapsulation
Select
Purpose: Used to execute query operations. Location: Placed on Mapper interface methods. Supported Features: Can write simple query statements directly, supports dynamic parameters.
Insert
Purpose: Used to execute insert operations. Location: Placed on Mapper interface methods. Supported Features: Supports inserting single or batch records, supports auto-generating primary keys.
Update
Purpose: Used to execute update operations. Location: Placed on Mapper interface methods. Supported Features: Supports updating records based on conditions.
Delete
Purpose: Used to execute delete operations. Location: Placed on Mapper interface methods. Supported Features: Supports deleting records based on conditions.
Results and Result
Purpose: Used for manual mapping of result sets, mapping queried fields to object properties one-to-one. Location: Placed on Mapper interface methods. Supported Features: Used when field names and object property names are inconsistent.
Param
Purpose: Used to name parameters in SQL, binding method parameters to placeholders in SQL statements. Location: Placed on Mapper method parameters. Supported Features: Solves the problem where method parameters cannot be directly referenced or multi-parameter binding issues.
Options
Purpose: Used to set additional options for methods, such as primary key generation, query caching, etc. Location: Placed on annotations like @Insert, @Update.
ResultMap
Purpose: References result mappings defined in XML or annotations. Location: Placed on Mapper interface methods. Supported Features: Simplifies complex result mappings.
ConstructorArgs and Arg
Purpose: Used in constructor mapping scenarios to map query results to constructor parameters. Location: Placed on Mapper interface methods.
Annotation Advantages
- Concise: Define SQL directly in code without additional XML files.
- Strong Type Support: Tightly integrated with Java code, facilitating refactoring and code checking.
- Easy Maintenance: SQL is close to business logic, making it easy to locate issues.
Annotation Disadvantages
- Not Suitable for Complex SQL: For dynamic SQL and large queries, annotation approach is less flexible.
- Code Verbosity: Complex queries may result in excessive annotation content, affecting readability.
- Poor SQL Reusability: SQL in annotations cannot be reused like XML.
Common Usage
- Use annotations for simple SQL, use XML configuration files for complex SQL.
- Use @Param to name parameters to avoid ambiguity.
- Prefer XML
<if>and<where>tags for large complex SQL to improve reusability. - When combined with SpringBoot, use @MapperScan annotation for unified Mapper management.
Annotation Mapping
Before implementing complex relationship mapping, we can implement it through configuration in mapping files. After using annotation development, we can use the Results annotation, Result annotation, One annotation, and Many annotation together to complete complex functionality development.
One-to-One
Query Model
The relationship between user table and order table: one user has multiple orders, one order belongs to only one user. The one-to-one query requirement is to query an order and simultaneously query the user to which that order belongs.
Write Code
OrderMapper
A new method findAllWithAnnotation was added, developed using annotation approach:
@Select("select * from wzk_orders")
@Results({
@Result(id = true, property = "id", column = "id"),
@Result(property = "ordertime", column = "ordertime"),
@Result(property = "total", column = "total"),
@Result(
property = "user", column = "uid",
javaType = WzkUser.class,
one = @One(select = "icu.wzk.mapper.UserMapper.findByIdWithAnnotation")
),
})
List<WzkOrder> findAllWithAnnotation();
UserMapper
A new method is added to this class, also using annotation approach, because it will be used in OrderMapper:
@Select("select * from wzk_user where id = #{id}")
WzkUser findByIdWithAnnotation(int id);
Call Code
package icu.wzk;
import icu.wzk.mapper.OrderMapper;
import icu.wzk.mapper.UserMapper;
import icu.wzk.model.WzkOrder;
import icu.wzk.model.WzkUser;
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;
import java.util.List;
public class WzkIcu11 {
public static void main(String[] args) throws IOException {
InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder()
.build(resourceAsStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
OrderMapper orderMapper = sqlSession.getMapper(OrderMapper.class);
List<WzkOrder> dataList = orderMapper.findAllWithAnnotation();
dataList.forEach(System.out::println);
sqlSession.close();
}
}
Test Results
After executing the code, the corresponding console output is as follows:
WzkOrder(id=1, ordertime=Mon Nov 11 00:00:00 CST 2024, total=100.0, user=WzkUser(id=1, username=wzk, password=icu, birthday=Mon Nov 11 00:00:00 CST 2024, orderList=null, roleList=null))
WzkOrder(id=2, ordertime=Mon Nov 11 00:00:00 CST 2024, total=200.0, user=WzkUser(id=1, username=wzk, password=icu, birthday=Mon Nov 11 00:00:00 CST 2024, orderList=null, roleList=null))
WzkOrder(id=3, ordertime=Sun Nov 10 00:00:00 CST 2024, total=150.0, user=WzkUser(id=2, username=wzk2, password=icu2, birthday=Mon Nov 11 00:00:00 CST 2024, orderList=null, roleList=null))