这是我参与11月更文挑战的第18天,活动详情查看:2021最后一次更文挑战
ParameterType
-
一个基本类型的参数,可以通过
#{参数名}
获取<?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="mapper.UserMapper"> <delete id="deleteUserById" parameterType="int"> delete from user where id = #{id} </delete> </mapper> 复制代码
-
多个参数时采用Map,通过
#{Key}
获取Map<String, Object> map = new HashMap<>(); map.put("name", "test"); map.put("password", "test"); User user = userMapper.selectUserByNameAndPassword(map); 复制代码
<?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="mapper.UserMapper"> <select id="selectUserByNameAndPassword" parameterType="map" resultType="pojo.User"> select * from user where name = #{name} and password = #{password} </select> </mapper> 复制代码
-
对象传递参数,通过
#{属性名}
获取<?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="mapper.UserMapper"> <insert id="addUser" parameterType="pojo.User"> insert into user(id, name, password) values (#{id}, #{name}, #{password}) </insert> </mapper> 复制代码
-
使用注解,在接口方法的参数前加 @Param() 属性,直接取 @Param() 中设置的值即可,不需要单独设置参数类型
import org.apache.ibatis.annotations.Param; public interface UserMapper { int deleteUserById(@Param("id") int id); } 复制代码
<?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="mapper.UserMapper"> <delete id="deleteUserById"> delete from user where id = #{id} </delete> </mapper> 复制代码
关于@Param
使用 @Param 注解用于给方法参数起一个名字。使用原则:
- 在方法只接受一个参数的情况下,可以不使用 @Param。
- 在方法接受多个参数的情况下,建议一定要使用 @Param 注解给参数命名。
- 如果参数是 JavaBean , 则不能使用@Param。
- 不使用 @Param 注解时,参数只能有一个,并且是Javabean。
#与$的区别
-
#{} 的作用主要是替换预编译语句(PrepareStatement)中的占位符? 【推荐使用】
INSERT INTO user (name) VALUES (#{name}); INSERT INTO user (name) VALUES (?); 复制代码
-
${} 的作用是直接进行字符串替换
INSERT INTO user (name) VALUES ('${name}'); INSERT INTO user (name) VALUES ('zhangsan'); 复制代码
ResultType
自动映射
resultMap
元素是 MyBatis 中最重要最强大的元素。它可以让你从 90% 的 JDBCResultSets
数据提取代码中解放出来。- 实际上,在为一些比如连接的复杂语句编写映射代码的时候,一份
resultMap
能够代替实现同等功能的长达数千行的代码。 - ResultMap 的设计思想是,对于简单的语句根本不需要配置显式的结果映射,而对于复杂一点的语句只需要描述它们的关系就行了
简单映射语句示例,不需要显指定 resultMap
。比如:
<?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="mapper.UserMapper">
<select id="selectUserById" resultType="map">
select id , name , pwd
from user
where id = #{id}
</select>
</mapper>
复制代码
上述语句只是简单地将所有的列映射到 HashMap
的键上,这由 resultType
属性指定。虽然在大部分情况下都够用,但是 HashMap 不是一个很好的模型。你的程序更可能会使用 JavaBean 或 POJO(Plain Old Java Objects,普通老式 Java 对象)作为模型。
手动映射
返回值类型为 resultMap,编写 resultMap,实现手动映射!
<?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="mapper.UserMapper">
<!-- 编写 resultMap -->
<resultMap id="UserMaps" type="pojo.User">
<!-- id为主键 -->
<id column="id" property="id"/>
<!-- column是数据库表的列名 , property是对应实体类的属性名 -->
<result column="name" property="name"/>
<result column="password" property="password"/>
</resultMap>
<!-- 返回值类型为 resultMap ,值为编写的 resultMap 的 id -->
<select id="selectUser" resultMap="UserMaps">
select *
from user
</select>
</mapper>
复制代码
注解开发
适用于简单的 SQL 语句,利用注解开发就不需要 mapper.xml 映射文件
-
在接口中添加注解
package mapper; import org.apache.ibatis.annotations.*; import pojo.User; import java.util.List; public interface UserMapper { @Insert("insert into user(id, name, password) values (#{id}, #{name}, #{password})") int addUser(User user); @Delete("delete from user where id=#{id}") int deleteUserById(@Param("id") int id); @Update("update user set name=#{name},password=#{password} where id = #{id}") int updateUserById(User user); @Select("select id,name,password from user") List<User> selectUser(); } 复制代码
-
在mybatis的核心配置文件中注入
<!--注册 Mapper--> <mappers> <mapper class="mapper.UserMapper"/> </mappers> 复制代码
-
测试 OK 即可
一对多
多个学生对应一个老师
-
创建学生实体类
@Data public class Student { private int id; private String name; //多个学生可以是同一个老师,即多对一 private Teacher teacher; } 复制代码
-
编写 StudentMapper 接口
public interface StudentMapper { //获取所有学生及对应老师的信息 public List<Student> getStudents(); } 复制代码
-
编写 Mapper.xml 文件
<?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="mapper.StudentMapper"> <!--需求:获取所有学生及对应老师的信息--> <!--思路1:嵌套查询 association → 一个复杂类型的关联;使用它来处理关联查询 --> <select id="getStudents" resultMap="StudentTeacher"> select * from student </select> <resultMap id="StudentTeacher" type="Student"> <!--association关联属性 property→属性名 javaType→属性类型 column→关联列名 select→子查询--> <association property="teacher" column="tid" javaType="Teacher" select="getTeacher"/> </resultMap> <!-- 传递一个参数的时候,下面可以写任何值 --> <select id="getTeacher" resultType="teacher"> select * from teacher where id = #{id} </select> <!----------------------------------------------------------------------------------------------------> <!--思路2:结果集的映射--> <select id="getStudents2" resultMap="StudentTeacher2" > select s.id sid, s.name sname , t.name tname from student s,teacher t where s.tid = t.id </select> <resultMap id="StudentTeacher2" type="Student"> <id property="id" column="sid"/> <result property="name" column="sname"/> <!--association关联属性 property→属性名 javaType→属性类型--> <association property="teacher" javaType="Teacher"> <!-- column是数据库表的列名 , property是对应实体类的属性名 --> <result property="name" column="tname"/> </association> </resultMap> </mapper> 复制代码
注:当子查询需要传多个参数时
<?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="mapper.StudentMapper"> <select id="getStudents" resultMap="StudentTeacher"> select * from student </select> <!-- 传递多个参数时 association 中 column 多参数配置:column="{key=value,key=value}" 其实就是键值对的形式,key 是传给下个 sql 的取值名称,value 是片段一中 sql 查询的字段名--> <resultMap id="StudentTeacher" type="Student"> <!--association关联属性 property→属性名 javaType→属性类型 column→关联列名 select→子查询--> <association property="teacher" column="{id=tid,name=tname}" javaType="Teacher" select="getTeacher"/> </resultMap> <select id="getTeacher" resultType="teacher"> select * from teacher where id = #{id} and name = #{name} </select> </mapper> 复制代码
多对一
一个老师对应多个学生
-
创建教师实体类
@Data public class Teacher { private int id; private String name; //一个老师多个学生 private List<Student> students; } 复制代码
-
编写 TeacherMapper 接口
public interface TeacherMapper { //获取指定老师,及老师下的所有学生 public Teacher getTeacher(int id); } 复制代码
-
编写 Mapper.xml 文件
<?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="mapper.TeacherMapper"> <!--需求:获取指定老师,及老师下的所有学生--> <!--思路1:嵌套查询--> <select id="getTeacher" resultMap="TeacherStudent2"> select * from teacher where id = #{id} </select> <resultMap id="TeacherStudent2" type="Teacher"> <!--column是 student 表外键的列名--> <collection property="students" javaType="ArrayList" ofType="Student" column="id" select="getStudentByTeacherId"/> </resultMap> <select id="getStudentByTeacherId" resultType="Student"> select * from student where tid = #{id} </select> <!----------------------------------------------------------------------------------------------------> <!--思路2:结果集映射 集合映射使用 collection! JavaType 和 ofType都是用来指定对象类型的 JavaType是用来指定 pojo 中属性的类型 ofType 指定的是映射到 list集合属性中 pojo的类型。 --> <select id="getTeacher" resultMap="TeacherStudent"> select s.id sid, s.name sname , t.name tname, t.id tid from student s,teacher t where s.tid = t.id and t.id=#{id} </select> <resultMap id="TeacherStudent" type="Teacher"> <result property="name" column="tname"/> <collection property="students" ofType="Student"> <result property="id" column="sid" /> <result property="name" column="sname" /> <result property="tid" column="tid" /> </collection> </resultMap> </mapper> 复制代码