Mybatis学习(6)单表的CURD操作-使用mapper动态代理

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/SDDDLLL/article/details/84573892

在前面的例子中自定义Dao接口实现类的时候发现这样一个问题:Dao接口的实现类其实并没用干什么实质性的工作,它仅仅就是通过SqlSession的相关API定位到映射文件mapper中  相应的id的sql语句中,真正对DB进行操作的是由框架通过mapper中的SQL完成的。

所以,Mybatis框架就抛开了Dao的实现类,直接定位到映射文件mapper中的相应SQL语句,对DB进行操作。这种对Dao的实现方式称为Mapper的动态代理方式。

mapper动态代理不需要程序员实现Dao接口。接口是由Mybatis结合映射文件自动生成的动态代理实现的。

接下来,我们在实现基本的增删改查的操作的项目的基础之上进行修改。

1、映射文件mapper的namespace属性值

一般情况下,一个Dao接口的实现类方法使用的是同一个SQL映射文件中的SQL映射id,所以,Mybatis框架要求,将映射文件中<mapper/>标签的namespace属性舌吻DAO接口的全类名,则系统会根据方法所属Dao接口,自动到相应的namespace的映射文件中查找相应的SQL映射。

也就是说,当我们设置了namespace之后,可以通过接口名就可以定位到mapper中的方法

2、修改日志输出控制文件

##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

3、Dao接口方法名字

public interface IStudentDao {
	//对一个表的基本操作
	void deleteStuById(int id);

	void insertStudent(Student student);
	//插入之后,这个插入的对象就能得到id。
	void insertStuCacheId(Student student);
	
	void updateStu(Student student);
	
	List<Student> selectAllStudent();
	//map使用很少
	Map<String, Object> selectAllStudentMap();
	
	Student selectStudentById(int id);
	
	List<Student> selectStuByName(String name);
}

4、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.test.dao.IStudentDao">
	<!-- parameterType已经定义了别名 -->
	<insert id="insertStudent" >
		insert into student(name,age,score) values(#{name},#{age},#{score})
	</insert>
	
	<insert id="insertStuCacheId" >
		insert into student(name,age,score) values(#{name},#{age},#{score})
		<!-- order:指定id的生成与插入语句的顺序关系 -->
		<selectKey resultType="int" keyProperty="id" order="AFTER">
		<!-- 这里有两种方式可以选择 -->
		<!-- 1、select last_insert_id() -->
		<!-- 2、select @@identity -->
		select @@identity
		</selectKey>
	</insert>
	
	<!-- id里面的内容是接口里面的方法名 ,提供给别人使用-->
	<delete id="deleteStuById">
		delete from student where id=#{xxx}  
	</delete>
	
	<update id="updateStu">
		update student set name=#{name},age=#{age},score=#{score} where id=#{id}
	</update>
	
	<select id="selectAllStudents" resultType="com.test.beans.Student">
		select * from student
	</select>
	
	<select id="selectStudentById" resultType="com.test.beans.Student">
		select * from student where id=#{id}
	</select>

	<select id="selectStuByName" resultType="com.test.beans.Student">
		<!-- 这种查询方式表示只要含有xxx都会被查询到 -->
		<!-- 下面这种方式推荐使用,可以方式sql注入。动态参数 -->
		select * from student where name like '%' #{xxx} '%'
		<!--  select * from student where name like concat('%',#{xxx},'%')-->
		<!-- 下面这种情况表示纯粹的字符串拼接,在输出结果里面没有参数显示:这种情况不建议使用 -->
		<!--  select * from student where name like '%${value}%'-->
	</select>
</mapper>

5、Dao对象的获取

使用时候,只需调用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<Student> 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<Student> students = dao.selectStuByName("冯");
		for (Student student : students) {
			System.out.println(student);
		}
	}
//   需要删除掉这个测试2	
//	@Test
//	public void testselectAllStudentMap() {
//		Map<String, Object> map=dao.selectAllStudentMap();	
//		System.out.println(map.get("冯冬冬"));
//	}
}

6、删除Dao的实现类

因为在这里到dao获取了IStudentDao的代理,Mybatis会自动映射接口和mapper,所以接口的实现类不再需要。

dao = sqlSession.getMapper(IStudentDao.class);

下面我们可以看到,Dao实现对象是由JDK的Proxy动态代理自动生成的

注意:我们在测试时候需要删除selectAllStudentMap,因为在这个测试条件下面会出错,也就是下面的代码。

	@Test
	public void testselectAllStudentMap() {
		Map<String, Object> map=dao.selectAllStudentMap();	
		System.out.println(map.get("冯冬冬"));
	}

猜你喜欢

转载自blog.csdn.net/SDDDLLL/article/details/84573892