mybatis的作用
MyBatis 帮我们省去了 DAO 实现类
省去了重复、繁琐的 JDBC 模板代码
我们只需要定义接口方法 + 写 SQL 就行
不用手动处理连接、Statement、ResultSet、关闭资源
1)现在有 MyBatis 的写法(你现在看到的)
只写一个 接口,不用写实现:
java
@Mapper
public interface UserMapper {
User selectById(int id);
}
实现类 MyBatis 自动帮你生成,你不用管。
2)如果没有 MyBatis,你必须自己写实现类
你要:
- 先写接口
UserDao - 再写实现类
UserDaoImpl - 里面手写 JDBC:加载驱动、获取连接、创建 Statement、执行 SQL、封装结果集......
大概长这样:
java
// 实现类,必须自己写!
public class UserDaoImpl implements UserDao {
@Override
public User selectById(int id) {
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
User user = null;
try {
// 1. 获取连接
conn = JdbcUtil.getConnection();
// 2. 写SQL
String sql = "select * from user where id=?";
pstmt = conn.prepareStatement(sql);
pstmt.setInt(1, id);
// 3. 执行
rs = pstmt.executeQuery();
// 4. 遍历结果集,手动封装成User对象
if (rs.next()) {
user = new User();
user.setId(rs.getInt("id"));
user.setUsername(rs.getString("username"));
// ... 所有字段都要自己 set
}
} catch (Exception e) {
e.printStackTrace();
} finally {
// 5. 关连接
JdbcUtil.close(rs, pstmt, conn);
}
return user;
}
}
结论(面试这么说)
- MyBatis 帮我们省去了 DAO 实现类
- 省去了重复、繁琐的 JDBC 模板代码
- 我们只需要定义接口方法 + 写 SQL 就行
- 不用手动处理连接、Statement、ResultSet、关闭资源
再给你一句最精髓的总结
没有 MyBatis:接口 + 实现类 + 手写 JDBC
有了 MyBatis:只写接口 + SQL,实现类框架自动生成
MyBatis 写 SQL
MyBatis 写 SQL 有两种方式:
- 注解版(简单,直接写在接口上)
- XML 版(复杂 SQL 用,企业主流)
你现在这个接口:
java
User selectById(int id);
必须配一个 SQL,不然 MyBatis 不知道干啥。
一、最简单:注解版 SQL(你现在就能学会)
直接在方法上加注解:
java
@Mapper
public interface UserMapper {
// 根据 id 查询用户
@Select("select * from user where id = #{id}")
User selectById(int id);
// 根据用户名查询
@Select("select * from user where username = #{username}")
User selectByName(String username);
// 插入用户
@Insert("insert into user(username,password,salt,email,type,status,activation_code,header_url,create_time) " +
"values(#{username},#{password},#{salt},#{email},#{type},#{status},#{activationCode},#{headerUrl},#{createTime})")
int insertUser(User user);
// 修改状态
@Update("update user set status = #{status} where id = #{id}")
int updateStatus(int id, int status);
}
关键点你记这一个:
#{id}对应方法里的参数名- 自动赋值,自动执行
- 返回值自动封装成 User 对象
就这么简单!
二、企业常用:XML 版 SQL
牛客网那个项目就是用 XML。
1. 建一个 XML 文件
路径固定:
resources/mapper/UserMapper.xml
在写这个xml的时候得有一个映射语句的配置可以从官网上找到然后粘贴
官网网址 https://mybatis.org/mybatis-3/zh_CN/getting-started.html
cpp
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.mybatis.example.BlogMapper">
<select id="selectBlog" resultType="Blog">
select * from Blog where id = #{id}
</select>
</mapper>

2. 里面写 SQL
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">
<!-- namespace 对应你的接口全类名 -->
<mapper namespace="com.nowcoder.community.dao.UserMapper">
<!-- 根据 id 查询 -->
<select id="selectById" resultType="User">
select * from user where id = #{id}
</select>
<!-- 根据用户名查询 -->
<select id="selectByName" resultType="User">
select * from user where username = #{username}
</select>
<!-- 插入用户 -->
<insert id="insertUser">
insert into user(username,password,email,create_time)
values(#{username},#{password},#{email},#{createTime})
</insert>
</mapper>
对应关系:
namespace= 你的 Mapper 接口全类名id= 接口里的方法名resultType= 返回的实体类
三、你最关心的一句话
SQL 是我们自己写的!
方法名是我们自己定的!
MyBatis 只负责把它们绑定起来!
四、我给你出一道超简单练习
把这个方法配上 SQL:
java
User selectByEmail(String email);
cpp
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!-- 1. namespace 必须是你的 Mapper 接口全类名 -->
<mapper namespace="com.nowcoder.community.dao.UserMapper">
<!-- 2. id 必须等于方法名:selectByEmail -->
<select id="selectByEmail" resultType="User">
select * from user where email = #{email}
</select>
</mapper>
如果范围比较多的话 可以用mybatis里的复用原则
这是 MyBatis 里超级实用、必学的复用技巧
核心一句话
<sql id="xxx">:定义一段可复用的 SQL 代码片段(相当于做一个「模板」)<include refid="xxx">:引用/插入这个模板(相当于把模板里的代码,复制粘贴到这里)
结合你的代码逐行拆解
xml
<!-- 1. 定义SQL片段:给一堆查询字段起个名字叫 selectFields -->
<sql id="selectFields">
id, username, password, salt, email, type, status, activation_code, header_url, create_time
</sql>
<!-- 2. 查询用户的SQL -->
<select id="selectById" resultType="User">
select
<!-- 3. 引用上面的片段:直接把那一串字段插在这里! -->
<include refid="selectFields"></include>
from user
where id = #{id}
</select>
最终执行的效果(MyBatis 自动帮你拼接)
MyBatis 看到 <include>,会直接把片段里的内容替换过来,实际运行的 SQL 是:
sql
select id, username, password, salt, email, type, status, activation_code, header_url, create_time
from user
where id = ?
为什么要用这个?(3个核心好处)
1. 不用重复写代码(偷懒神器)
你这个项目里,查用户的SQL肯定不止这一个,比如:
selectByUsernameselectByEmailselectList
如果不用 <include>,每个查询都要手写一长串字段,又累又容易写错。
用了之后,所有查询都可以直接引用:
xml
<select id="selectByUsername" resultType="User">
select <include refid="selectFields"/>
from user
where username = #{username}
</select>
2. 改字段只改一处(维护神器)
假如以后要给用户表加个 phone 字段,只需要修改 片段里的内容:
xml
<sql id="selectFields">
id, username, password, ..., create_time, phone <!-- 只加这里 -->
</sql>
所有引用它的 SQL,自动生效,不用一个个去改!
3. 代码整洁,可读性极高
一眼就能看懂:查询的是哪些字段,逻辑清晰。
超简单规则(记住就会用)
<sql>必须加 唯一id (比如selectFields)<include>的refid必须和 的id完全一致- 片段可以是:查询字段、where条件、join语句......任何重复的SQL都能抽出来
总结
<sql id="名字">= 做一个可复用的SQL模板<include refid="名字">= 把模板粘贴到这里- 作用:少写重复代码、改一处全生效、代码更整洁
cpp
<include> 是 MyBatis 的功能(XML 里的标签)
原生 SQL 语言里根本没有这个东西