深入MyBatis:CRUD操作与高级查询实战

引言

在上一篇文章中,我们介绍了Mybatis的基础使用。

如有需要请移步查看:

MyBatis入门:快速掌握用户查询实战https://blog.csdn.net/qq_52331401/article/details/149270402?spm=1001.2014.3001.5502

今天,我将通过一个完整的用户管理系统示例,深入讲解Mybatis的CRUD操作、参数传递、模糊查询以及聚合函数等高级功能。

项目升级概览

相比基础版本,本次项目增加了以下功能:

  1. 完整的CRUD操作(增删改查)
  2. 多种查询方式(ID查询、模糊查询)
  3. 聚合函数使用
  4. 数据库连接信息外部化配置
  5. 更规范的测试类结构

核心代码解析

实体类(User.java)

实体类保持不变,作为数据载体:

java 复制代码
public class User implements Serializable {
    private Integer id;
    private String username;
    private Date birthday;
    private String sex;
    private String address;
    // 省略getter/setter和toString方法
}

Mapper接口(UserMapper.java)

接口中定义了完整的CRUD操作方法:

java 复制代码
public interface UserMapper {
    List<User> findAll();          // 查询所有用户
    User findById(Integer userId); // 根据ID查询
    void insert(User user);        // 新增用户
    void update(User user);        // 修改用户
    void delete(Integer userId);   // 删除用户
    List<User> findByName(String username); // 模糊查询
    Integer findByCount();         // 查询总数
}

Mapper XML配置(UserMapper.xml)

对应接口的SQL实现:

XML 复制代码
<mapper namespace="cn.tx.mapper.UserMapper">
    <!-- 查询所有 -->
    <select id="findAll" resultType="cn.tx.domain.User">
        select * from user
    </select>

    <!-- ID查询 -->
    <select id="findById" resultType="cn.tx.domain.User" parameterType="int">
        select * from user where id = #{id}
    </select>

    <!-- 新增用户(返回自增ID) -->
    <insert id="insert" parameterType="cn.tx.domain.User">
        <selectKey keyProperty="id" order="AFTER" resultType="java.lang.Integer">
            select last_insert_id()
        </selectKey>
        insert into user(username,birthday,sex,address) 
        values(#{username},#{birthday},#{sex},#{address})
    </insert>

    <!-- 更新用户 -->
    <update id="update" parameterType="cn.tx.domain.User">
        update user set username=#{username},birthday=#{birthday},
        sex=#{sex},address=#{address} where id=#{id}
    </update>

    <!-- 删除用户 -->
    <delete id="delete" parameterType="Integer">
        delete from user where id=#{id}
    </delete>

    <!-- 模糊查询(两种方式) -->
    <select id="findByName" resultType="cn.tx.domain.User" parameterType="string">
        <!-- select * from user where username like #{username} -->
        select * from user where username like '%${value}%'
    </select>

    <!-- 查询总数 -->
    <select id="findByCount" resultType="int">
        select count(*) from user
    </select>
</mapper>

配置文件优化

数据库连接信息向上提取到jdbc.properties:

bash 复制代码
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql:///mybatis_db
jdbc.username=root
jdbc.password=123456

SqlMapConfig.xml引用外部配置:

XML 复制代码
<configuration>
    <properties resource="jdbc.properties"/>
    <!-- 其他配置 -->
    <dataSource type="POOLED">
        <property name="driver" value="${jdbc.driver}"/>
        <property name="url" value="${jdbc.url}"/>
        <property name="username" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
    </dataSource>
</configuration>

测试类详解

测试类采用JUnit4,使用@Before和@After优化:

java 复制代码
public class UserTest {
    private InputStream in;
    private SqlSession session;
    private UserMapper mapper;

    @Before
    public void init() throws Exception {
        in = Resources.getResourceAsStream("SqlMapConfig.xml");
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
        session = factory.openSession();
        mapper = session.getMapper(UserMapper.class);
    }

    @After
    public void destory() throws IOException {
        session.close();
        in.close();
    }

    // 测试方法...
}

查询测试

java 复制代码
@Test
public void testFindAll() {
    List<User> list = mapper.findAll();
    list.forEach(System.out::println);
}

@Test
public void testFindById() {
    User user = mapper.findById(1);
    System.out.println(user);
}

增删改测试

java 复制代码
@Test
public void testInsert() {
    User user = new User();
    user.setUsername("测试用户");
    user.setBirthday(new Date());
    user.setSex("男");
    user.setAddress("北京");
    mapper.insert(user);
    session.commit(); // 增删改需要提交事务
    System.out.println("新增ID:" + user.getId());
}

@Test
public void testUpdate() {
    User user = mapper.findById(41);
    user.setUsername("修改后的名字");
    mapper.update(user);
    session.commit();
}

@Test
public void testDelete() {
    mapper.delete(48);
    session.commit();
}

高级查询测试

java 复制代码
// 模糊查询方式一:参数中带%
@Test
public void testFindByName() {
    List<User> list = mapper.findByName("%王%");
    list.forEach(System.out::println);
}

// 模糊查询方式二:SQL中使用${value}
// 注意:这种方式有SQL注入风险,不推荐

@Test
public void testFindByCount() {
    Integer count = mapper.findByCount();
    System.out.println("用户总数:" + count);
}

关键技术点解析

参数传递

  • 简单类型:#{参数名}
  • 对象类型:#{属性名}

模糊查询两种方式

  • 安全方式:like #{参数}(需要在参数中包含%)
  • 拼接方式:like '%${value}%'(有SQL注入风险)

返回自增ID

XML 复制代码
<selectKey keyProperty="id" order="AFTER" resultType="int">
    select last_insert_id()
</selectKey>

事务控制

  • 增删改操作需要手动commit()
  • 可以再openSession时设置自动提交:openSession(true)

总结

MyBatis的灵活性和强大功能使其成为Java持久层开发的优秀选择。希望这篇博客能帮助你深入理解MyBatis的核心用法!

完整代码已提供,建议读者实际运行测试类体会不同操作的效果。如有任何问题,欢迎留言讨论。

相关推荐
vivi_and_qiao1 小时前
HTML的form表单
java·前端·html
Slaughter信仰1 小时前
深入理解Java虚拟机:JVM高级特性与最佳实践(第3版)第四章知识点问答补充及重新排版
java·开发语言·jvm
心灵宝贝1 小时前
Mac用户安装JDK 22完整流程(Intel版dmg文件安装指南附安装包下载)
java·开发语言·macos
ta是个码农1 小时前
Mysql——日志
java·数据库·mysql·日志
今***b2 小时前
Python 操作 PPT 文件:从新手到高手的实战指南
java·python·powerpoint
David爱编程2 小时前
volatile 关键字详解:轻量级同步工具的边界与误区
java·后端
hhzz2 小时前
SQL 窗口函数(Window Function)终极指南
数据库·sql
fatfishccc4 小时前
Spring MVC 全解析:从核心原理到 SSM 整合实战 (附完整源码)
java·spring·ajax·mvc·ssm·过滤器·拦截器interceptor
没有bug.的程序员4 小时前
MyBatis 初识:框架定位与核心原理——SQL 自由掌控的艺术
java·数据库·sql·mybatis
Databend4 小时前
Databend 亮相 DTCC 2025:存算分离架构引领湖仓一体化
数据库