使用 Mybatis 开发 Dao,通常有两个方法,即原始 Dao开发方式和 Mapper 接口代理开发方式。而现在主流 的开发方式是接口代理开发方式,这种方式总体上更加简便。但是我们还是要学习一下基于传统编写 Dao 实现类的开发方式。
Mybatis 实现 DAO 的传统开发方式
1. 前期准备
我们先创建一个新的工程:
我们把上个工程src下的所有的文件目录全都复制到新的项目中,也把pom文件内的依赖信息复制进来。
其中的QueryVo类可以删除了,我们不再使用它。
而在IUserDao中,我们只留下这几个方法:
相应的,我们在xml中也把其余的配置删除掉。
并且,我们把实体类User中的属性改回来,并且重新生成get/set方法:
我们把IUserDao.xml中的resultMap也删除了,并且把对应的结果类都改成一开始的实体类全限定类名:
<?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.veeja.dao.IUserDao">
<!-- 查询所有的操作 -->
<select id="findAll" resultType="com.veeja.domain.User">
select * from user
</select>
<!-- 保存用户 -->
<!-- values后面的取值,要写 #{内容} 这样的格式,里面的内容注意要和我们的Javabean对象中的属性名称对应-->
<insert id="saveUser" parameterType="com.veeja.domain.User">
<!-- 配置插入操作后,获取插入数据的id-->
<selectKey keyProperty="id" keyColumn="id" resultType="int" order="AFTER">
select last_insert_id();
</selectKey>
insert into user(username,address,sex,birthday)values(#{username},#{address},#{sex},#{birthday})
</insert>
<!--更新用户-->
<update id="updateUser" parameterType="com.veeja.domain.User">
update user set username=#{username},address=#{address},sex=#{sex},birthday=#{birthday} where id=#{id}
</update>
<!--删除用户-->
<delete id="deleteUser" parameterType="java.lang.Integer">
delete from user where id= #{uid}
</delete>
<!--根据id查询用户信息-->
<select id="findById" parameterType="INT" resultType="com.veeja.domain.User">
select * from user where id = #{uid}
</select>
<!--根据用户名称进行模糊查询-->
<select id="findByName" parameterType="String" resultType="com.veeja.domain.User">
select * from user where username like #{uname}
</select>
<!--查询用户的总记录数-->
<select id="findTotal" resultType="int">
select count(id) from user
</select>
</mapper>
2. IUserDao接口
我们再把IUserDao接口的代码贴在下面:
package com.veeja.dao;
import com.veeja.domain.User;
import java.util.List;
/**
* @author veeja
* <p>
* 用户的持久层接口
*/
public interface IUserDao {
/**
* 查询所有的用户
*
* @return
*/
List<User> findAll();
/**
* 保存用户
*
* @return
*/
void saveUser(User user);
/**
* 更新用户
*/
void updateUser(User user);
/**
* 根据id删除用户
*
* @param userId
*/
void deleteUser(Integer userId);
/**
* 根据Id进行查询用户信息
*
* @param userId
* @return
*/
User findById(Integer userId);
/**
* 根据用户名称进行模糊查询
*
* @param username
* @return
*/
List<User> findByName(String username);
/**
* 查询用户的总记录数
*
* @return
*/
int findTotal();
}
3. 查询操作
接下来我们创建一个类,来实现上面的接口,并且实现相对应的方法。
(此处我们先填充上查询所有的方法实现)
package com.veeja.dao.impl;
import ...
public class UserDaoImpl implements IUserDao {
private SqlSessionFactory factory;
public UserDaoImpl(SqlSessionFactory factory) {
this.factory = factory;
}
@Override
public List<User> findAll() {
// 1. 根据factory获取SQLSession对象
SqlSession session = factory.openSession();
// 2. 调用SQLSession中的方法,实现查询列表
// 此处写的参数就是能获取配置信息的key,就是IUserDao.xml文件中的 namespace.方法名称
List<User> users = session.selectList("com.veeja.dao.IUserDao.findAll");
// 3. 释放资源
session.close();
return users;
}
...
}
测试方法类:
public class MybatisTest {
private InputStream in = null;
private IUserDao userDao = null;
@Before //用于在测试方法执行之前执行
public void init() throws IOException {
// 1. 读取配置文件,生成字节输入流
in = Resources.getResourceAsStream("SqlMapConfig.xml");
// 2. 获取SqlSessionFactory
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
// 3. 使用工厂对象,创建dao对象
userDao = new UserDaoImpl(factory);
}
@After //用于在测试方法执行之后执行
public void destory() throws IOException {
in.close();
}
/**
* 测试查询所有
*/
@Test
public void testFindAll() {
// 5. 执行查询所有方法
List<User> users = userDao.findAll();
for (User user : users) {
System.out.println(user);
}
}
}
执行结果:
4. 保存操作
UserDaoImpl:
@Override
public void saveUser(User user) {
// 1. 根据factory获取SQLSession对象
SqlSession session = factory.openSession();
// 2. 调用方法实现保存
session.insert("com.veeja.dao.IUserDao.saveUser", user);
// 3. 提交事务
session.commit();
// 4. 释放资源
session.close();
}
测试类:
/**
* 测试保存操作
*/
@Test
public void testSave() throws IOException {
User user = new User();
user.setUsername("666666");
user.setAddress("6666666666");
user.setSex("6");
user.setBirthday(new Date());
// 执行保存方法
userDao.saveUser(user);
}
执行结果:
5. 更新、删除、根据id查询,根据名称模糊查询、查询总记录数
UserDaoImpl:
@Override
public void updateUser(User user) {
// 1. 根据factory获取SQLSession对象
SqlSession session = factory.openSession();
// 2. 调用方法实现更新
session.insert("com.veeja.dao.IUserDao.updateUser", user);
// 3. 提交事务
session.commit();
// 4. 释放资源
session.close();
}
@Override
public void deleteUser(Integer userId) {
// 1. 根据factory获取SQLSession对象
SqlSession session = factory.openSession();
// 2. 调用方法实现删除
session.insert("com.veeja.dao.IUserDao.deleteUser", userId);
// 3. 提交事务
session.commit();
// 4. 释放资源
session.close();
}
@Override
public User findById(Integer userId) {
// 1. 根据factory获取SQLSession对象
SqlSession session = factory.openSession();
// 2. 调用方法实现根据id查询
User user = session.selectOne("com.veeja.dao.IUserDao.findById", userId);
// 3. 提交事务
session.commit();
// 4. 释放资源
session.close();
return user;
}
@Override
public List<User> findByName(String username) {
// 1. 根据factory获取SQLSession对象
SqlSession session = factory.openSession();
// 2. 调用SQLSession中的方法,实现模糊查询
List<User> users = session.selectList("com.veeja.dao.IUserDao.findByName", username);
// 3. 释放资源
session.close();
return users;
}
@Override
public int findTotal() {
// 1. 根据factory获取SQLSession对象
SqlSession session = factory.openSession();
// 2. 调用SQLSession中的方法,实现查询总记录数
int count = session.selectOne("com.veeja.dao.IUserDao.findTotal");
// 3. 释放资源
session.close();
return count;
}
测试类:
/**
* 测试更新操作
*/
@Test
public void testUpdate() throws IOException {
User user = new User();
user.setId(69);
user.setId(69);
user.setUsername("mybatis");
user.setAddress("hahhahaha");
user.setSex("7");
user.setBirthday(new Date());
// 执行保存方法
userDao.updateUser(user);
}
/**
* 测试删除操作
*/
@Test
public void testDelete() throws IOException {
// 执行删除方法
userDao.deleteUser(69);
}
/**
* 测试根据用户id查询的操作
*/
@Test
public void testFindById() throws IOException {
// 执行删除方法
User user = userDao.findById(42);
System.out.println(user);
}
/**
* 测试根据用户名称进行模糊查询
*/
@Test
public void testFindByName() throws IOException {
// 执行删除方法
List<User> users = userDao.findByName("%刘%");
for (User user : users) {
System.out.println(user);
}
}
/**
* 测试根查询用户的总记录数
*/
@Test
public void testFindTotal() throws IOException {
// 执行删除方法
int total = userDao.findTotal();
System.out.println("用户总数:" + total);
}
执行结果:
上述代码都是符合我们的预期的,运行的结果我就不浪费篇幅了。