一、什么是 ORM 框架?
- ORM(Object Relational Mapping,对象关系映射)是一种将数据库中的表结构映射到程序中的对象的技术。
- ORM 框架通过元数据(通常以 XML 或注解形式)描述对象与数据库表之间的映射关系。
- 常见的 ORM 框架包括 MyBatis、Hibernate 和 JOOQ。
二、什么是 MyBatis?
- MyBatis 是一款优秀的持久层框架,支持自定义 SQL、存储过程以及高级映射。
- 它简化了 JDBC 的使用,免去了繁琐的参数设置和结果集处理。
- MyBatis 通过 XML 或注解将 Java 对象(POJO)与数据库记录进行映射。
三、为什么要学习 MyBatis?
- MyBatis 框架简单易学,应用广泛,适合初学者快速入门。
- 掌握 MyBatis 后,可以轻松学习其他 ORM 框架(如 Hibernate)。
- MyBatis 提供了灵活的 SQL 编写方式,适合需要高性能和复杂查询的场景。
四、MyBatis 入门程序
1. 数据库表结构
CREATE TABLE blog (
blog_id BIGINT AUTO_INCREMENT COMMENT '博客ID',
user_id BIGINT NULL DEFAULT 0 COMMENT '发表用户ID',
blog_title VARCHAR(100) DEFAULT '' NULL COMMENT '博客标题',
blog_content TEXT NULL COMMENT '博客内容',
create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP NULL COMMENT '创建时间',
update_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间'
) CHARSET = utf8;
CREATE INDEX user_id ON blog (user_id);
CREATE TABLE user_info (
user_id BIGINT AUTO_INCREMENT COMMENT '用户ID' PRIMARY KEY,
username VARCHAR(50) NULL DEFAULT '' COMMENT '用户名',
user_password VARCHAR(50) NULL DEFAULT '' COMMENT '用户密码',
create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP NULL COMMENT '创建时间',
update_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间'
) CHARSET = utf8;
2. 使用 IntelliJ IDEA 创建 Maven 项目
引入 MyBatis 的依赖
<dependencies>
<!-- MyBatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.9</version>
</dependency>
<!-- MySQL 驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.27</version>
</dependency>
<!-- Lombok(可选) -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.22</version>
<scope>provided</scope>
</dependency>
</dependencies>
3. 配置 MyBatis 核心文件
<?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>
<settings>
<!-- 开启驼峰命名法 -->
<setting name="mapUnderscoreToCamelCase" value="true"/>
<!-- 打印 SQL 日志 -->
<setting name="logImpl" value="STDOUT_LOGGING" />
</settings>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/mybatis"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="BlogMapper.xml"/>
<mapper resource="UserMapper.xml"/>
</mappers>
</configuration>
4. 编写 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="com.example.mapper.BlogMapper">
<select id="selectBlog" resultType="blog">
SELECT * FROM blog WHERE blog_id = #{id}
</select>
</mapper>
5. 编写 Java 类和查询示例
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;
public class Application {
public static void main(String[] args) {
SqlSession session = null;
try {
session = getSqlSession();
Blog blog = session.selectOne("com.example.mapper.BlogMapper.selectBlog", 1);
System.out.println(blog);
} catch (IOException e) {
e.printStackTrace();
} finally {
if (session != null) {
session.close();
}
}
}
private static SqlSession getSqlSession() throws IOException {
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
return sqlSessionFactory.openSession();
}
}
五、MyBatis 配置优化
1. 驼峰命名法
<setting name="mapUnderscoreToCamelCase" value="true"/>
- 将数据库中的下划线命名(如
user_id)自动映射为 Java 对象的驼峰命名(如userId)。
2. SQL 日志输出
<setting name="logImpl" value="STDOUT_LOGGING" />
- 打印执行的 SQL 语句,方便调试。
3. 配置别名
<typeAliases>
<typeAlias type="com.example.pojo.UserInfo" alias="UserInfo"/>
</typeAliases>
- 简化类名的使用,提高代码可读性。
六、使用 Mapper 接口实现增删改查
1. 定义 Mapper 接口
public interface UserInfoMapper {
UserInfo selectUserInfoById(Long id);
List<UserInfo> selectAllUsers();
Integer insertUserInfo(UserInfo userInfo);
Integer updateUsernameById(@Param("name") String name, @Param("id") Long id);
Integer deleteUserById(Long id);
}
2. 编写对应的 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.example.mapper.UserInfoMapper">
<resultMap id="userInfoResult" type="UserInfo">
<id property="userId" column="user_id"/>
<result property="username" column="username"/>
<result property="userPassword" column="user_password"/>
<result property="createTime" column="create_time"/>
<result property="updateTime" column="update_time"/>
</resultMap>
<select id="selectUserInfoById" resultType="UserInfo">
SELECT * FROM user_info WHERE user_id = #{id}
</select>
<select id="selectAllUsers" resultType="UserInfo">
SELECT * FROM user_info
</select>
<insert id="insertUserInfo" parameterType="UserInfo">
INSERT INTO user_info (username, user_password) VALUES (#{username}, #{userPassword})
</insert>
<update id="updateUsernameById">
UPDATE user_info SET username = #{name} WHERE user_id = #{id}
</update>
<delete id="deleteUserById">
DELETE FROM user_info WHERE user_id = #{id}
</delete>
</mapper>
3. 示例代码
private static void insertUserInfo() throws IOException {
SqlSession sqlSession = getSqlSession();
UserInfoMapper mapper = sqlSession.getMapper(UserInfoMapper.class);
UserInfo userInfo = new UserInfo();
userInfo.setUsername("lsx");
userInfo.setUserPassword("xxx");
mapper.insertUserInfo(userInfo);
sqlSession.commit();
sqlSession.close();
}
七、动态 SQL
1. <if> 标签
<select id="queryUserInfoByParam" resultType="UserInfo" parameterType="UserInfo">
SELECT * FROM user_info
<where>
<if test="username != null and username != ''">
AND username = #{username}
</if>
<if test="userPassword != null and userPassword != ''">
AND user_password = #{userPassword}
</if>
</where>
</select>
2. <foreach> 标签
<select id="selectUserInfoByIds" resultType="UserInfo">
SELECT * FROM user_info
WHERE user_id IN
<foreach item="id" collection="idList" open="(" separator="," close=")">
#{id}
</foreach>
</select>
八、分页查询
1. 普通分页查询
List<Blog> blogs = mapper.findBlogList(7, 2); // 第7页,每页2条
2. PageHelper 插件
PageHelper.startPage(7, 2);
List<Blog> blogList = mapper.findBlogList();
PageInfo<Blog> blogPageInfo = new PageInfo<>(blogList);
System.out.println("总记录数:" + blogPageInfo.getTotal());
System.out.println("当前页数据:" + blogPageInfo.getList());
九、逆向工程生成代码
- 使用 MyBatis Generator 或 EasyCode 插件自动生成 Mapper 文件和 Java 实体类。
- 推荐使用 EasyCode 插件(版本 1.2.3),确保与教程版本一致。
十、多表联合查询
1. 一对一
<resultMap id="blogAndUserResult" type="BlogAndUserPO">
<result property="username" column="username"/>
<association property="blog" javaType="Blog">
<id property="id" column="blog_id"/>
<result property="title" column="blog_title"/>
<result property="content" column="blog_content"/>
</association>
</resultMap>
2. 一对多
<resultMap id="userAndBlogsResult" type="UserAndBlogsPO">
<id property="userId" column="user_id"/>
<result property="username" column="username"/>
<collection property="blogs" ofType="Blog">
<id property="id" column="blog_id"/>
<result property="title" column="blog_title"/>
<result property="content" column="blog_content"/>
</collection>
</resultMap>
十一、补充知识点
1. # 和 $ 的区别
#{}:预编译参数,防止 SQL 注入。${}:直接替换,可能存在 SQL 注入风险。
2. 多个入参的处理
- 使用
@Param注解标注参数名称:Integer updateUsernameById(@Param("name") String name, @Param("id") Long id);
3. 缓存机制
- MyBatis 提供一级缓存(SqlSession 级别)和二级缓存(Mapper 级别)。
- 二级缓存需要在 Mapper 文件中启用:
<cache/>
4. 事务管理
- 默认使用 JDBC 事务管理:
<transactionManager type="JDBC"/> - 可以切换为管理事务(如 Spring 管理)。
十二、总结
- MyBatis 是一款灵活且高效的 ORM 框架,适合需要精细控制 SQL 的场景。
- 掌握 MyBatis 的核心配置、Mapper 文件编写和动态 SQL 的使用是学习的重点。
- 通过逆向工程和插件可以显著提高开发效率。
希望这份学习笔记对你有帮助!如果需要进一步的补充或修改,请随时告诉我。

1237

被折叠的 条评论
为什么被折叠?



