原生DAO实现
接口和实现类
public interface UserDao {
public User findUserById(Integer id);
}
/*******************************************/
public class UserDaoImpl implements UserDao {
private SqlSessionFactory sqlSessionFactory;
//构造器注入
public UserDaoImpl(SqlSessionFactory sqlSessionFactory) {
this.sqlSessionFactory = sqlSessionFactory;
}
@Override
public User findUserById(Integer id) {
//sqlSession是线程不安全的,所以它的最佳使用范围在方法体内
SqlSession openSession = sqlSessionFactory.openSession();
User user = openSession.selectOne("test.findUserById", id);
return user;
}
}
测试
public class UserDaoTest {
private SqlSessionFactory factory;
//在测试方法前执行这个方法
@Before
public void setUp() throws Exception{
String resource = "SqlMapConfig.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
factory = new SqlSessionFactoryBuilder().build(inputStream);
}
@Test
public void testFindUserById() throws Exception{
//将初始化好的工厂注入到实现类中
UserDao userDao = new UserDaoImpl(factory);
User user = userDao.findUserById(1);
System.out.println(user);
}
}
存在的问题
- DAO方法体中存在重复代码:通过
SqlSessionFactory
创建SqlSession
,调用SqlSession
的数据库操作方法 - 调用
SqlSession
的数据库操作方法需要指定statement
的id,这里存在硬编码,不利于开发维护
Mapper 动态代理方式
开发规范
Mapper接口开发方法只需要程序员编写Mapper接口(相当于DAO接口),由MyBatis框架根据接口定义创建接口的动态代理对象,代理对象的方法体同上边DAO接口实现类方法。
Mapper.xml
文件中的namespace
与mapper
接口的类路径相同Mapper
接口方法名和Mapper.xml
中定义的每个statement
的id相同Mapper
接口方法的输入参数类型和Mapper.xml
中定义的每个SQL的parameterType
的类型相同Mapper
接口方法的输出参数类型和Mapper.xml
中定义的每个SQL的resultType的类型相同
接口
public interface UserMapper {
//动态代理形式中,如果返回的结果集为List,那么MyBatis会在生成实现类的时候自动调用selectList方法
public List<User> findUserByUsername(String username);
}
映射文件
<select id="findUserByUsername" parameterType="java.lang.String" resultType="Demo01.pojo.User">
select * from `user` where username like '%${value}%'
</select>
配置接口和映射文件
Class
属性引入接口的全路径名称
- 接口文件和映射文件要放在同一个目录下
- 接口名称和映射文件名称除扩展名外要完全相同
在SqlMapConfig.xml
文件中配置映射文件
<mappers>
<mapper class="Demo02.mapper.UserMapper"/>
</mappers>
或者使用直接配置映射文件
<mappers>
<mapper resource="Demo02/mapper/UserMapper.xml"/>
</mappers>
测试
private SqlSessionFactory factory;
//在测试方法前执行这个方法
@Before
public void setUp() throws Exception{
String resource = "SqlMapConfig.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
factory = new SqlSessionFactoryBuilder().build(inputStream);
}
@Test
public void testFindUserByUsername() throws Exception{
SqlSession openSession = factory.openSession();
//通过getMapper方法来实例化接口
UserMapper mapper = openSession.getMapper(UserMapper.class);
List<User> list = mapper.findUserByUsername("王");
System.out.println(list);
}
输入映射
开发时通过pojo传递查询条件,查询条件是综合的查询条件,不仅包括用户查询条件还包括其他的查询条件,这时候可以使用包装对象传递输入参数。
在这个基础上添加QueryVo
import java.util.List;
public class QuerVo {
private User user;
private List<Integer> ids;
public List<Integer> getIds() {
return ids;
}
public void setIds(List<Integer> ids) {
this.ids = ids;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
}
接口和映射文件
public interface UserMapper {
public List<User> findUserByVo(QueryVo vo);
}
<!-- 由于传入参数是 QueryVo 类,所以名称为 xxx.xxx -->
<select id="findUserByVo" parameterType="Demo01.pojo.QueryVo" resultType="Demo01.pojo.User">
select * from `user` where username like '%${user.username}%' and sex=#{user.sex}
</select>
测试
@Test
public void testFindUserByVo() throws Exception {
SqlSession openSession = factory.openSession();
//通过getMapper方法来实例化接口
UserMapper mapper = openSession.getMapper(UserMapper.class);
QuerVo vo = new QuerVo();
User user = new User();
user.setUsername("王");
user.setSex("1");
vo.setUser(user);
List<User> list = mapper.findUserByVo(vo);
System.out.println(list);
}
下一篇:Mybatis学习笔记[5] 之动态SQL https://blog.csdn.net/Rabbit_Judy/article/details/80849362