引言
在上一篇文章中,我们介绍了Mybatis的基础使用。
如有需要请移步查看:
今天,我将通过一个完整的用户管理系统示例,深入讲解Mybatis的CRUD操作、参数传递、模糊查询以及聚合函数等高级功能。
项目升级概览
相比基础版本,本次项目增加了以下功能:
- 完整的CRUD操作(增删改查)
- 多种查询方式(ID查询、模糊查询)
- 聚合函数使用
- 数据库连接信息外部化配置
- 更规范的测试类结构
核心代码解析
实体类(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的核心用法!
完整代码已提供,建议读者实际运行测试类体会不同操作的效果。如有任何问题,欢迎留言讨论。