欢迎光临
我们一直在努力

MyBatis

MyBatis

1️⃣ 什么是 MyBatis?——JDBC 的“救世主”!

还记得写 JDBC 时那堆 Class.forName()、Connection、PreparedStatement、ResultSet 吗?
每次都要手动开关连接、拼 SQL、解析结果……简直像在搬砖!🧱

MyBatis 就是来解放你的双手的!

✅ 它是一个优秀的持久层框架,帮你自动处理:

  • 数据库连接
  • SQL 参数设置
  • 结果集映射成 Java 对象(ORM)

👉 你只需要专注写 SQL 和 Java 接口,剩下的交给 MyBatis!

💡 小知识:MyBatis 原名 iBatis,2010 年从 Apache 迁移到 Google Code 后改名。名字 = Internet + abatis(一种鱼),寓意“灵活如鱼”🐟。


2️⃣ Hello MyBatis!入门案例走起 🚀

步骤一:建表 & 准备数据

CREATE DATABASE mybatis;
USE mybatis;

CREATE TABLE user (
id INT PRIMARY KEY AUTO_INCREMENT,
username VARCHAR(50),
birthday DATE,
sex VARCHAR(10),
address VARCHAR(100)
);

INSERT INTO user VALUES
(41, '张三丰', '1980-01-01', '男', '武当山'),
(42, '马德华', '1975-05-05', '男', '高老庄');

步骤二:Maven 依赖(pom.xml)

<dependencies>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.11</version> <!– 推荐用新版本 –>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.28</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
</dependencies>

<build>
<resources>
<!– 包含 src/main/java 下的 Mapper XML 文件 –>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
</resource>
<!– 包含 src/main/resources 下的所有配置文件 –>
<resource>
<directory>src/main/resources</directory>
</resource>
</resources>
</build>

⚠️ 别忘了 <build> 里加 resources,否则 XML 文件打包会丢失!

步骤三:实体类 User.java

public class User {
private Integer id;
private String username;
private Date birthday;
private String sex;
private String address;

// getter / setter / toString()
}

步骤四:DAO 接口 UserDao.java

public interface UserDao {
List<User> findAll();
}

步骤五:映射文件 UserDao.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="com.hg.dao.UserDao">
<select id="findAll" resultType="com.hg.pojo.User">
SELECT * FROM user
</select>
</mapper>

🔑 namespace 必须和接口全路径一致!
🔑 id 必须和方法名一致!
🔑 resultType 是返回对象的全类名!

步骤六:核心配置 mybatis-config.xml

<?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 default="dev">
<environment id="dev">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/mybatis?useSSL=false&amp;serverTimezone=Asia/Shanghai"/>
<property name="username" value="root"/>
<property name="password" value="1111"/>
</dataSource>
</environment>
</environments>

<!– 加载映射文件 –>
<mappers>
<mapper resource="com/hg/dao/UserDao.xml"/>
</mappers>
</configuration>

步骤七:测试 Test

public class MyBatisTest {
private SqlSession sqlSession;

@Before
public void init() throws IOException {
InputStream in = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
sqlSession = factory.openSession();
}

@Test
public void testFindAll() {
UserDao dao = sqlSession.getMapper(UserDao.class);
List<User> users = dao.findAll();
users.forEach(System.out::println);
}

@After
public void destroy() {
sqlSession.close();
}
}

🎉 成功输出用户信息!恭喜你迈出了第一步!


3️⃣ CRUD 操作大全 —— 增删改查 So Easy!

✅ 查询(单参数)

User findUserById(Integer id);

<select id="findUserById" parameterType="int" resultType="User">
SELECT * FROM user WHERE id = #{id}
</select>

💡 #{} 是安全的占位符,防 SQL 注入!


✅ 多参数传递(三种方式)

方式1:按位置(不推荐)

User findUserByIdAndName(Integer id, String name);

<!– arg0, arg1… 或 param1, param2… –>
SELECT * FROM user WHERE id = #{arg0} AND username = #{arg1}

方式2:@Param 注解(推荐!)

User findUserByIdAndName(@Param("id") Integer id, @Param("name") String name);

SELECT * FROM user WHERE id = #{id} AND username = #{name}

方式3:封装成对象 or Map

User findByUser(User user);
// 或
User findByMap(Map<String, Object> map);


🔍 模糊查询(小心 SQL 注入!)

List<User> findByName(String name);

<!– 安全写法(推荐) –>
<select id="findByName" parameterType="string" resultType="User">
SELECT * FROM user WHERE username LIKE CONCAT('%', #{name}, '%')
</select>

<!– 危险写法(慎用!) –>
SELECT * FROM user WHERE username LIKE '%${value}%'

❗ ${} 是直接拼接字符串,有注入风险!只在动态表名/列名时使用。


➕ 插入 & 主键回显(重点!🌟)

需求:插入用户后,自动获取数据库生成的自增 ID,并赋值给 Java 对象的 id 字段。

方法一:使用 <selectKey>

<insert id="insertUser" parameterType="User">
<selectKey keyProperty="id" resultType="int" order="AFTER">
SELECT LAST_INSERT_ID()
</selectKey>
INSERT INTO user(username, birthday, sex, address)
VALUES (#{username}, #{birthday}, #{sex}, #{address})
</insert>

方法二:使用 useGeneratedKeys(更简洁!)

<insert id="insertUser"
parameterType="User"
useGeneratedKeys="true"
keyProperty="id">

INSERT INTO user(username, birthday, sex, address)
VALUES (#{username}, #{birthday}, #{sex}, #{address})
</insert>

✅ 测试时你会发现:user.getId() 有值了!这就是主键回显!

User user = new User();
user.setUsername("刘德华");
user.setAddress("香港");
userDao.insertUser(user);
System.out.println("新用户ID:" + user.getId()); // 输出:68


✏️ 更新 & 删除

<update id="updateUser" parameterType="User">
UPDATE user SET username=#{username}, address=#{address}
WHERE id = #{id}
</update>

<delete id="deleteUser" parameterType="int">
DELETE FROM user WHERE id = #{id}
</delete>

⚠️ 记得 sqlSession.commit()!否则事务不会提交!


4️⃣ 关联查询 —— 一对多、多对多也不怕!

🔗 一对一(Account → User)

public class Account {
private Integer id;
private Integer uid;
private Double money;
private User user; // 关联用户
}

<resultMap id="accountWithUser" type="Account">
<id property="id" column="aid"/>
<result property="uid" column="uid"/>
<result property="money" column="money"/>
<association property="user" javaType="User">
<id property="id" column="id"/>
<result property="username" column="username"/>
</association>
</resultMap>

<select id="findAll" resultMap="accountWithUser">
SELECT a.id AS aid, a.uid, a.money, u.*
FROM account a
JOIN user u ON a.uid = u.id
</select>


🔗 一对多(User → List)

public class User {
// … 其他字段
private List<Account> accounts;
}

<resultMap id="userWithAccounts" type="User">
<id property="id" column="id"/>
<result property="username" column="username"/>
<collection property="accounts" ofType="Account">
<id property="id" column="aid"/>
<result property="money" column="money"/>
</collection>
</resultMap>

<select id="findAll" resultMap="userWithAccounts">
SELECT u.*, a.id AS aid, a.money
FROM user u
LEFT JOIN account a ON u.id = a.uid
</select>


🔗 多对多(Role ↔ User)

通过中间表 user_role(uid, rid) 实现。

<resultMap id="roleWithUsers" type="Role">
<id property="id" column="rid"/>
<result property="roleName" column="role_name"/>
<collection property="users" ofType="User">
<id property="id" column="id"/>
<result property="username" column="username"/>
</collection>
</resultMap>

<select id="findAll" resultMap="roleWithUsers">
SELECT r.id AS rid, r.role_name, u.*
FROM role r
LEFT JOIN user_role ur ON r.id = ur.rid
LEFT JOIN user u ON ur.uid = u.id
</select>


5️⃣ 动态 SQL —— 让 SQL “活”起来!

🧪 if + where(条件查询)

<select id="findByUser" resultType="User">
SELECT * FROM user
<where>
<if test="username != null and username != ''">
AND username = #{username}
</if>
<if test="sex != null">
AND sex = #{sex}
</if>
</where>
</select>

✅ <where> 会自动去掉开头的 AND!


✏️ set(动态更新)

<update id="updateUser">
UPDATE user
<set>
<if test="username != null">username = #{username},</if>
<if test="address != null">address = #{address},</if>
</set>
WHERE id = #{id}
</update>

✅ <set> 自动去掉末尾的逗号!


🔁 foreach(批量操作)

<!– 批量删除 –>
<delete id="deleteByIds">
DELETE FROM user WHERE id IN
<foreach collection="ids" item="id" open="(" close=")" separator=",">
#{id}
</foreach>
</delete>

<!– 批量插入 –>
<insert id="insertUsers">
INSERT INTO user(username, address) VALUES
<foreach collection="userList" item="user" separator=",">
(#{user.username}, #{user.address})
</foreach>
</insert>


6️⃣ 缓存机制 —— 飞一般的速度!

🥇 一级缓存(SqlSession 级别)

  • 默认开启!
  • 同一个 SqlSession 中,相同查询只查一次数据库。
  • 执行增删改 or commit() or close() 会清空缓存。

🥈 二级缓存(Mapper 级别)

  • 多个 SqlSession 共享!
  • 需要手动开启:

<!– mybatis-config.xml –>
<settings>
<setting name="cacheEnabled" value="true"/>
</settings>

<!– UserDao.xml –>
<mapper namespace="…">
<cache/> <!– 开启二级缓存 –>
…
</mapper>

⚠️ 实体类必须实现 Serializable!


7️⃣ 注解开发(了解即可)

@Select("SELECT * FROM user WHERE id = #{id}")
User findById(Integer id);

@Insert("INSERT INTO user(username) VALUES(#{username})")
@Options(useGeneratedKeys = true, keyProperty = "id")
void insertUser(User user);

💬 优点:代码简洁
💬 缺点:SQL 写死在 Java 里,难维护!
👉 复杂项目建议用 XML!


✅ 总结

功能关键点
入门 配置文件 + Mapper + SqlSession
CRUD #{} 安全,${} 危险
主键回显 useGeneratedKeys="true" + keyProperty
关联查询 <association> / <collection>
动态 SQL if, where, set, foreach
缓存 一级(默认),二级(需配置)
  • 简化 JDBC:告别繁琐的模板代码。
  • SQL 灵活:SQL 写在 XML 里,方便管理和优化。
  • 解耦:业务代码与 SQL 完全分离。
  • 强大映射:自动完成对象与数据库记录的映射。
  • 生态丰富:与 Spring 等框架无缝集成。

  • 赞(0)
    未经允许不得转载:171主机测评 » MyBatis
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址