Mybatis系列-4-Mapper动态代理
冰冻三尺,非一日之寒。
Mybatis相关源码及文档:
Mybatis官方技术文档 https://mybatis.org/mybatis-3/zh/index.html
Mybatis源码包下载:https://github.com/mybatis/mybatis-3/releases
所有代码及笔记gitee路径:https://gitee.com/simple-coding/all-demo-code.git
一.Mapper动态代理引入
不引入Mapper动态代理时,如下,我们会定义DAO实现类进行Mybatis的相关操作:
@Override
public int save(Student student) throws Exception{
try (SqlSession sqlSession = MyBatisUtils.getSqlSession();){
//mapper.namespace+id
int updateCount = sqlSession.update("test.save", student);
sqlSession.commit();
return updateCount;
} catch (Exception e) {
e.printStackTrace();
throw e;
}
}
@Override
public List findAllStudent() throws Exception{
try ( SqlSession sqlSession = MyBatisUtils.getSqlSession();){
//mapper.namespace+id
return sqlSession.selectList("test.findAllStudent");
}catch (Exception e) {
e.printStackTrace();
throw e;
}
}
上边这段代码也就是仅仅获取SqlSession调用与其相关的API,没有什么实质操作,而且两个方法除了API不同外其它部分几乎一模一样。
什么是Mapper动态代理:Mapper动态代理方式是指程序员在编码过程中只需编写DAO接口而不需要实现Dao接口。接口的实现是由MyBatis结合mapper映射文件自动生成的动态代理实现的。
二、Mapper动态代理演示
1.创建表SQL
create table student(
id int not null PRIMARY key auto_increment comment '主键',
name varchar(20) comment '姓名',
idNum varchar(20) COMMENT '学号'
) comment '学生表';
2.创建实体类(lombok 插件)
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Student {
private Integer id;//主键
private String name;//姓名
private String idNum;//学号
}
3.只定义Dao接口
/**
* 描述:Mapper动态代理
*/
public interface StudentDao {
/**
* 保存学生
* @param student
* @return
*/
int save(Student student) throws Exception;
/**
* 查询所有学生
* @return
*/
List findAllStudent() throws Exception;
/**
* 查询一个学生封装成map
* @return
*/
List<Map> findOneMap(Integer id) throws Exception;
/**
* 查询所有学生封装成map
* @return
*/
List<Map> findListMap() throws Exception;
/**
* 删除所有学生
* @return
*/
int deleteById(Integer id) throws Exception;
/**
* 修改所有学生
* @return
*/
int updateStudent(Student student) throws Exception;
}
4.主配置mapper配置
5.Dao接口同目录下定义mapper.xml
insert into student(name,idNum) values(#{name},#{idNum})
delete from student where id = #{id}
update student set name=#{name},idNum=#{idNum} where id = #{id}
6.测试类
使用getMapper获取代理实例。
/**
* 描述:日志配置及入门案例讲解示例
*/
public class MybatisTest {
private StudentDao studentDao;
private SqlSession sqlSession;
private Logger logger = LoggerFactory.getLogger(MybatisTest.class);
@Before
public void initStudentDao() throws Exception {
sqlSession = MyBatisUtils.getSqlSession();
studentDao = sqlSession.getMapper(StudentDao.class);
}
@After
public void close() throws Exception {
sqlSession.close();
}
/**
* 保存学生
* @return
*/
@Test
public void save() throws Exception{
Student student = new Student("法外狂徒2","002");
logger.info("更新前student:{}",student);
int saveCount = studentDao.save(student);
sqlSession.commit();
logger.info("更新条数:{}",saveCount);
logger.info("更新后student:{}",student);
}
/**
* 查询所有学生
* @return
*/
@Test
public void findAllStudent() throws Exception{
studentDao.findAllStudent().forEach(System.out::println);
}
/**
* 查询一个学生封装成map
* @return
*/
@Test
public void findOneMap() throws Exception{
studentDao.findOneMap(1).forEach(System.out::println);
}
/**
* 查询所有学生封装成map
* @return
*/
@Test
public void findListMap() throws Exception{
studentDao.findListMap().forEach(System.out::println);
}
/**
* 删除所有学生
* @return
*/
@Test
public void deleteById() throws Exception{
int deleteCount = studentDao.deleteById(4);
sqlSession.commit();
logger.info("删除条数:{}",deleteCount);
}
/**
* 修改所有学生
* @return
*/
@Test
public void updateStudent() throws Exception{
Student student = new Student(4,"法外狂徒666","666");
int updateCount = studentDao.updateStudent(student);
sqlSession.commit();
logger.info("修改条数:{}",updateCount);
}
}
框架在更新,技术在进步,之前的Mybatis的动态代理不支持Map查询,现在已经支持了。
三、Mybatis的Maven项目
前面已经说到使用Mapper动态代理,Mapper接口和xml配置文件,文件名一致且要放到同一个目录下。同一个目录说白了classpath相同。
也就是说你可以单独在resource类路径下创建同名包只存放xml。
如果使用maven创建项目,且源文件在同一个目录,这时就需要在pom中添加如下代码:
src/main/java
**/*.xml
true
否则,报错如图
报错图
四、总结
单独使用Mybatis时,使用Mapper动态代理步骤
- 主配置使用
或
- 只定义Dao接口
- mapper的namespace与Dao全限定类名一致,statement的id为dao接口方法名
- mapper与dao接口同名且同包
- 使用SqlSession.getMapper(StudentDao.class);获取代理类
- 操作dao接口方法
小伙伴有啥疑问,可以留言指教!!!