在前面的例子中自定义Dao接口实现类的时候发现这样一个问题:Dao接口的实现类其实并没用干什么实质性的工作,它仅仅就是通过SqlSession的相关API定位到映射文件mapper中 相应的id的sql语句中,真正对DB进行操作的是由框架通过mapper中的SQL完成的。
所以,Mybatis框架就抛开了Dao的实现类,直接定位到映射文件mapper中的相应SQL语句,对DB进行操作。这种对Dao的实现方式称为Mapper的动态代理方式。
mapper动态代理不需要程序员实现Dao接口。接口是由Mybatis结合映射文件自动生成的动态代理实现的。
接下来,我们在实现基本的增删改查的操作的项目的基础之上进行修改。
一般情况下,一个Dao接口的实现类方法使用的是同一个SQL映射文件中的SQL映射id,所以,Mybatis框架要求,将映射文件中
也就是说,当我们设置了namespace之后,可以通过接口名就可以定位到mapper中的方法
##define an appender named console
log4j.appender.console=org.apache.log4j.ConsoleAppender
#The Target value is System.out or System.err
log4j.appender.console.Target=System.out
#set the layout type of the apperder
log4j.appender.console.layout=org.apache.log4j.PatternLayout
#set the layout format pattern
log4j.appender.console.layout.ConversionPattern=[%-5p] %m%n
##define a logger
##.test is mybatis.xml namespace
# 这里修改路径
log4j.logger.com.test.dao.IStudentDao=debug,console
public interface IStudentDao {
//对一个表的基本操作
void deleteStuById(int id);
void insertStudent(Student student);
//插入之后,这个插入的对象就能得到id。
void insertStuCacheId(Student student);
void updateStu(Student student);
List selectAllStudent();
//map使用很少
Map selectAllStudentMap();
Student selectStudentById(int id);
List selectStuByName(String name);
}
insert into student(name,age,score) values(#{name},#{age},#{score})
insert into student(name,age,score) values(#{name},#{age},#{score})
select @@identity
delete from student where id=#{xxx}
update student set name=#{name},age=#{age},score=#{score} where id=#{id}
使用时候,只需调用SqlSession的getMapper()方法,即可获取指定接口的实现类对象。该方法的参数为指定Dao接口类的class值。
下面给出全部的测试类代码:
public class MyTest {
private IStudentDao dao ;
private SqlSession sqlSession;
@Before
public void testBefore(){
sqlSession = MybatisUtil.getSqlSession();
dao = sqlSession.getMapper(IStudentDao.class);
}
@After
public void after(){
if(sqlSession!=null){
sqlSession.close();
}
}
@Test
public void testinsertStu(){
Student student = new Student("张三",23,93.5);
dao.insertStudent(student);
sqlSession.commit();
}
@Test
public void testinsertStuCacheId(){
Student student = new Student("冯冬冬",20,97.5);
System.out.println("插入之前的id:"+student);
dao.insertStuCacheId(student);
sqlSession.commit();
System.out.println("插入之后的id:"+student.getId());
}
@Test
public void testDelete(){
dao.deleteStuById(30);
sqlSession.commit();
}
@Test
public void testUpdate(){
Student student = new Student("王胜男1",19,96.5);
student.setId(22);
dao.updateStu(student);
sqlSession.commit();
}
//选出数据库中所有的对象
@Test
public void testselectAllStudent() {
System.out.println("===========");
List students = dao.selectAllStudent();
for (Student student : students) {
System.out.println(student);
}
}
//根据id号选出学生
@Test
public void testselectStudentById() {
Student student = dao.selectStudentById(24);
System.out.println(student);
}
@Test
public void testselectStuByName() {
List students = dao.selectStuByName("冯");
for (Student student : students) {
System.out.println(student);
}
}
// 需要删除掉这个测试2
// @Test
// public void testselectAllStudentMap() {
// Map map=dao.selectAllStudentMap();
// System.out.println(map.get("冯冬冬"));
// }
}
因为在这里到dao获取了IStudentDao的代理,Mybatis会自动映射接口和mapper,所以接口的实现类不再需要。
dao = sqlSession.getMapper(IStudentDao.class);
下面我们可以看到,Dao实现对象是由JDK的Proxy动态代理自动生成的
注意:我们在测试时候需要删除selectAllStudentMap,因为在这个测试条件下面会出错,也就是下面的代码。
@Test
public void testselectAllStudentMap() {
Map map=dao.selectAllStudentMap();
System.out.println(map.get("冯冬冬"));
}