【转】Mybatis DAO传入多个参数 三种方式

本文详细介绍了在MyBatis中使用三种不同方式传递参数到SQL的方法:直接使用位置参数、通过Map传递参数以及使用注解指定参数名称。每种方式都提供了具体的代码示例,帮助开发者更好地理解和应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

转自;https://blog.youkuaiyun.com/master_yao/article/details/78658022

给自己做个笔记,防止自己忘了

1.第一种方式:

DAO函数:

Public User selectUser(String name,String area);

对应的Map.xml:

<select id="selectUser" resultMap="BaseResultMap">
    select  *  from user_user_t   where user_name = #{0} and user_area= #{1}
</select>

#{0}代表接收的是dao层中的第一个参数,#{1}代表dao层中第二参数,更多参数一致往后加即可。

 

2.第二种方式:

DAO函数:

Public User selectUser(Map paramMap);

对应的Mapper.xml:

<select id=" selectUser" resultMap="BaseResultMap">
   select  *  from user_user_t   where user_name = #{userName,jdbcType=VARCHAR} and user_area= #{userArea,jdbcType=VARCHAR}
</select>

对应的Service:

Private User xxxSelectUser(){
      Map paramMap=new hashMap();
      paramMap.put(“userName”,”对应具体的参数值”);
      paramMap.put(“userArea”,”对应具体的参数值”);
      User user=xxx. selectUser(paramMap);}

3.第三种方式:

DAO函数:

Public User selectUser(@param(“userName”) String name, @param(“userArea”) String area);

对应的Mapper.xml:

<select id=" selectUser" resultMap="BaseResultMap">
   select  *  from user_user_t   where user_name = #{userName,jdbcType=VARCHAR} and user_area = #{userArea,jdbcType=VARCHAR}
</select> 

 

<think>我们正在讨论MyBatis中如何传递实体类参数。根据引用[3]和引用[4],MyBatis支持多种传参方式,其中使用实体类对象传递参数是一种常见且推荐的方式,尤其当参数较多时,可以保持代码的清晰和可维护性。 ### 1. **实体类参数传递的基本方法** 当DAO层方法需要传递多个参数时,可以将这些参数封装到一个实体类(Java Bean)中,然后将该实体类对象作为方法参数传入MyBatis会自动识别实体类的属性,并在SQL映射文件中通过属性名引用这些值。 #### 示例代码: **DAO接口方法**: ```java public interface UserDao { // 使用User实体类作为参数 void insertUser(User user); } ``` **SQL映射文件(XML)**: ```xml <insert id="insertUser" parameterType="com.example.User"> INSERT INTO user (username, email, age) VALUES (#{username}, #{email}, #{age}) </insert> ``` - 这里的`parameterType`指定了参数类型为`com.example.User`(实体类的全限定名)。 - `#{username}`、`#{email}`、`#{age}` 分别对应`User`类的属性名(必须一致)。 ### 2. **实体类参数在复杂查询中的应用** 实体类参数同样适用于更新、条件查询等场景。例如,根据多个条件动态查询用户: **DAO接口**: ```java List<User> selectByCondition(UserCondition condition); ``` **SQL映射文件**: ```xml <select id="selectByCondition" resultType="com.example.User" parameterType="com.example.UserCondition"> SELECT * FROM user WHERE <if test="username != null"> username LIKE #{username} </if> <if test="age != null"> AND age = #{age} </if> </select> ``` - `UserCondition`是一个自定义的查询条件实体类,包含`username`、`age`等属性。 - 使用`<if>`标签动态生成SQL,避免空值导致的语法错误。 ### 3. **注意事项** 1. **属性名匹配**: SQL中的`#{}`或`${}`占位符必须与实体类的属性名**严格一致**(包括大小写)。例如,若属性名为`userName`,则占位符应为`#{userName}`而非`#{username}`。 2. **参数类型指定**: 在XML中,`parameterType`可省略(MyBatis通常能自动推断),但显式声明可提高可读性。 3. **嵌套属性支持**: 如果实体类包含其他对象属性(如`User`中包含`Address address`),可通过嵌套属性访问: ```sql INSERT INTO user (..., city) VALUES (..., #{address.city}) ``` 4. **与@Param注解的区别**: 如果方法参数是**多个实体类**,需使用`@Param`注解区分: ```java void updateUser(@Param("old") User oldUser, @Param("new") User newUser); ``` XML中使用`#{old.username}`、`#{new.email}`引用。 ### 4. **与其他传参方式的对比** | 传参方式 | 适用场景 | 示例 | |------------------|-----------------------------------|--------------------------| | **实体类对象** | 参数多且逻辑相关 | `void insert(User user)` | | **@Param注解** | 参数较少(2-4个) | `void update(@Param("id") int id, @Param("name") String name)` | | **Map集合** | 动态参数(属性名不固定) | `void update(Map<String, Object> map)` | | **顺序传参** | 兼容旧代码(不推荐) | `void delete(int id, String name)` → XML用`#{arg0}`, `#{arg1}` | > **建议**:优先使用实体类或`@Param`注解,避免使用Map(降低可读性)和顺序传参(易出错)[^3][^4]。 ### 总结 在MyBatis DAO层使用实体类传参的步骤: 1. **定义实体类**:包含所有需要传递的属性及getter/setter。 2. **DAO方法设计**:将实体类对象作为方法参数。 3. **XML编写SQL**:通过`#{属性名}`引用实体类属性,并确保`parameterType`指向实体类(可选)。 这种方式使代码结构清晰,易于扩展,尤其适合复杂业务场景[^3][^4]。 §§相关问题§§ 1. MyBatis中如何传递多个实体类参数? 2. 实体类属性名和数据库列名不一致时如何处理? 3. 使用实体类传参和Map传参各有什么优缺点? 4. MyBatis的`#{}`和`${}`在引用实体类属性时有何区别?</think>### MyBatis DAO 层实体类参数传递详解 在 MyBatis 中,使用实体类作为 DAO 层方法的参数是最规范且可维护性最高的传参方式,特别适合需要传递多个相关参数的场景。以下是具体实现方法: #### 1. **基本使用方式** **DAO 接口定义**: ```java public interface UserDao { // 使用实体类作为参数 int insertUser(User user); // 使用实体类作为查询条件 List<User> selectByCondition(UserQuery query); } ``` **SQL 映射文件(XML)**: ```xml <!-- 插入操作 --> <insert id="insertUser" parameterType="com.example.User"> INSERT INTO users (username, email, create_time) VALUES (#{username}, #{email}, #{createTime}) </insert> <!-- 条件查询 --> <select id="selectByCondition" resultType="com.example.User" parameterType="com.example.UserQuery"> SELECT * FROM users WHERE 1=1 <if test="username != null"> AND username LIKE CONCAT('%', #{username}, '%') </if> <if test="minCreateTime != null"> AND create_time >= #{minCreateTime} </if> </select> ``` **关键点**: 1. `parameterType` 指定实体类的全限定名(可省略,MyBatis 会自动推断) 2. SQL 中使用 `#{属性名}` 直接访问实体类字段 3. 支持动态 SQL 标签(如 `<if>`)判断属性值是否为空 #### 2. **实体类定义规范** ```java public class User { private String username; private String email; private Date createTime; // 必须有无参构造函数 public User() {} // Getter/Setter 是必须的 public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } // ... 其他属性的getter/setter } // 查询条件专用实体类 public class UserQuery { private String username; private Date minCreateTime; // ... 其他查询条件字段 } ``` #### 3. **嵌套实体属性访问** 如果实体类包含其他对象属性: ```java public class Order { private Long id; private User user; // 嵌套实体 } ``` 在 XML 中通过点号访问: ```xml <select id="selectOrder" resultType="com.example.Order"> SELECT * FROM orders WHERE user_id = #{user.id} <!-- 访问嵌套属性 --> </select> ``` #### 4. **与其它传参方式对比 | **传参方式** | **适用场景** | **示例** | |---------------------|----------------------------------|------------------------------| | **实体类参数** | 多个相关参数 | `insertUser(User user)` | | **@Param 注解** | 2-4个独立参数 | `update(@Param("id")Long id, @Param("name")String name)` | | **Map 参数** | 动态字段名 | `selectByMap(Map<String,Object> params)` | | **顺序传参** | 兼容旧代码(不推荐) | `delete(String name, int age)` → XML 用 `#{arg0}`, `#{arg1}` | #### 5. **最佳实践建议** 1. **专用查询实体**:为复杂查询创建专门的 Query 对象(如 `UserQuery`) 2. **避免暴露持久化细节**:实体类不应包含数据库特有字段(如分页参数) 3. **配合 ResultMap 使用**:当数据库列名与实体字段名不一致时: ```xml <resultMap id="userMap" type="User"> <id property="id" column="user_id"/> <result property="createTime" column="create_date"/> </resultMap> ``` > 实体类传参的优势:提高代码可读性、支持类型检查、便于扩展字段、简化动态 SQL 编写[^3][^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值