一、Dao开发
首先创建Dao接口
package com.md.dao;
import com.md.domain.Student;
import java.util.List;
/**
* @author MD
* @create 2020-08-05 14:18
*/
public interface StudentDao {
List<Student> selectStudents();
int insertStudent(Student student);
}
然后创建Dao接口的实现类
public class StudentDaoImpl implements StudentDao
1. 实现接口中的select方法
先在StudentDao.xml中写对应的sql
<?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.md.dao.StudentDao">
<select id="selectStudents" resultType="com.md.domain.Student">
select id , name , eamil ,age from student
</select>
<insert id="insertStudent">
insert into student values(#{id},#{name},#{email},#{age})
</insert>
</mapper>
然后在实现类中写具体的方法
public List<Student> selectStudents() {
// 工具类
SqlSession session = MyBatisUtil.getSqlSession();
List<Student> studentList = session.selectList("com.md.dao.StudentDao.selectStudents");
session.close();
return studentList;
}
在测试类中写
@Test
public void testSelectStudent(){
StudentDao dao = new StudentDaoImpl();
List<Student> studentList = dao.selectStudents();
studentList.forEach(stu -> System.out.println(stu));
}
需要注意:
- dao对象,类型是StudentDao,而这个接口的全限定名称是:com.md.dao.StudentDao正好和类型是StudentDao.xml中的namespace是一样的
- 方法名称,selectStudents,这个方法的名称正是mapper文件中的id值 selectStudents
- 通过dao中方法的返回值也是可以确定MyBatis要调用的SqlSession的方法
- 如果返回的是list,那就说明调用的是selectList()方法
- 如果返回的是int、或是其他,看mapper文件中的标签 <insert> , <update>
- 就会调用SqlSession的insert、update方法
- mybatis的动态代理,mybatis根据dao的方法调用,获取执行sql语句信息,mybatis根据你的dao接口,创建一个到接口的实现类,并创建这个类的对象,完成SqlSession调用方法,访问数据库
2. 实现接口中insert方法
@Override
public int insertStudent(Student student) {
SqlSession sqlSession = MyBatisUtils.getSqlSession();
int nums = sqlSession.insert("com.md.dao.StudentDao.insertStudent",student);
// 注意提交事务
sqlSession.commit();
sqlSession.close();
return nums;
}
测试类
int i = dao.insertStudent(new Student(1005, "李白", "li@qq.com", 30));
System.out.println("成功插入:"+i+" 条数据");
3. 实现接口中 update 方法
public int updateStudent(Student student) {
SqlSession session = MyBatisUtil.getSqlSession();
int nums = session.insert(
"com.md.dao.StudentDao.updateStudent",student);
session.commit();
session.close();
return nums;
}
测试:
public void testUpdate() throws IOException {
Student student = new Student();
student.setId(1006);
student.setAge(28);
int nums = studentDao.updateStudent(student);
System.out.println(" 使用 Dao 修改数据:"+nums);
}
4. 实现接口中 delete 方法
public int deleteStudent(int id) {
SqlSession session = MyBatisUtil.getSqlSession();
int nums = session.insert(
"com.md.dao.StudentDao.deleteStudent",1006);
session.commit();
session.close();
return nums;
}
测试:
@Test
public void testDelete() throws IOException {
int nums = studentDao.deleteStudent(1006);
System.out.println(" 使用 Dao 修改数据:"+nums);
}
![](https://img-blog.csdnimg.cn/img_convert/396e895666d8ce4aba2e535866c89cc5.png)
二、Dao开发分析
在前面例子中自定义 Dao 接口实现类时发现一个问题:
Dao 的实现类其实并没有干什么实质性的工作,而且代码还是千篇一律,它仅仅就是通过 SqlSession 的相关 API 定位到映射文件 mapper 中相应 id 的 SQL 语句,真正对 DB 进行操作的工作其实是由框架通过 mapper 中的 SQL 完成的
所以,MyBatis 框架就抛开了 Dao 的实现类,直接定位到映射文件 mapper 中的相应 SQL 语句,对DB 进行操作。这种对 Dao 的实现方式称为 Mapper 的动态代理方式
Mapper 动态代理方式无需程序员实现 Dao 接口。接口是由 MyBatis 结合映射文件自动生成的动态代
理实现的
三、Dao代理实现CURD
首先就是删除Dao接口的实现类
![](https://img-blog.csdnimg.cn/img_convert/abdd2bf5f2553609402ad77dc5cd22a0.png)
1. 使用getMapper获取代理对象
只需调用 SqlSession 的 getMapper()方法,即可获取指定接口的实现类对象。该方法的参数为指定 Dao接口类的 class 值
还是直接使用工具类获取获取SqlSession
/**
* 使用mybatis的动态代理机制, 使用SqlSession.getMapper(dao接口.class)
* getMapper能获取dao接口对于的实现类对象。
*/
SqlSession sqlSession = MybatisUtils.getSqlSession();
StudentDao dao = sqlSession.getMapper(StudentDao.class);
这样的话就无需再写实现类了,使用dao接口.class就行
上面使用传统Dao的方式就可以修改成这样
select
@Test
public void testSelectStudent(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
StudentDao dao = sqlSession.getMapper(StudentDao.class);
// 调用dao方法,执行数据库操作
List<Student> studentList = dao.selectStudents();
studentList.forEach(stu -> System.out.println(stu));
}
insert
@Test
public void testInsertStudent(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
StudentDao dao = sqlSession.getMapper(StudentDao.class);
int i = dao.insertStudent(new Student(1006, "王昭君", "wzj@qq.com", 30));
// 注意提交事务
sqlSession.commit();
System.out.println("成功插入:"+i+" 条数据");
}
这样就更加的方便了
四、总结
1. 什么是动态代理?
mybatis帮你创建dao接口的实现类,在实现类中调用SqlSession的方法执行sql语句
2. 使用动态代理的方式
- 获取SqlSession对象,SqlSessionFactory.openSession(),只不过我们可以直接使用工具类
- 使用getMapper方法获取某个接口的对象,sqlSession.getMapper(接口.class);
- 调用接口的方法,调用那个方法就执行了mapper文件中的那个sql语句
3. 使用动态代理的要求
- dao接口和mapper文件放在一个目录中
- dao接口和mapper文件名称一致
- mapper文件中的namespace的值是dao接口的全限定名称
- mapper文件中的<select>、<insert>、<update>、<delete>等的id值是接口中的方法名
- dao接口中不要使用重载的方法,不要使用同名的,不同参数的方法
具体的如下:
目录结构
![](https://img-blog.csdnimg.cn/img_convert/abdd2bf5f2553609402ad77dc5cd22a0.png)
dao接口:
package com.md.dao;
public interface StudentDao {
List<Student> selectStudents();
int insertStudent(Student student)
}
mapper文件
<?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.md.dao.StudentDao">
<select id="selectStudents" resultType="com.md.domain.Student">
select id , name , eamil , age from student
</select>
<insert id="insertStudent">
insert into student values(#{id},#{name},#{email},#{age})
</insert>
</mapper>
这样就ok了