Mapper的动态代理
1 普通的mybatis使用
通过实现mapper接口 通过sqlSessionFactory生产SqlSession对象映射配置文件中id属性对应的sql语句
mapper.java
package org.lanqiao.mapper;
import org.lanqiao.pojo.Emp;
import java.io.IOException;
import java.util.List;
public interface EmpMapper {
List<Emp> findAll() throws IOException;
Emp selectEmpByNo(Integer empno) throws IOException;
void insertEmp(Emp emp) throws IOException;
void deleteEmpByNo(Integer empno) throws IOException;
void updateEmpByNo(Emp emp) throws IOException;
}
mapperImpl.java
public class EmoDaoImpl implements EmpMapper {
@Override
public List<Emp> findAll() throws IOException {
//获得SqlSession
SqlSession sqlSession = MybatisUtils.getSession();
//执行sql
List<Emp> emps = sqlSession.selectList("org.lanqiao.mapper.EmpMapper.findAll");//解决多映射文件下有同名id需要加上命名空间
//释放资源
MybatisUtils.closeSession();
return emps;
}
@Override
public Emp selectEmpByNo(Integer empno) throws IOException {
//获得SqlSession
SqlSession sqlSession = MybatisUtils.getSession();
//执行sql
Emp emp = sqlSession.selectOne("org.lanqiao.mapper.EmpMapper.selectEmpByNo",empno);
//释放资源
MybatisUtils.closeSession();
return emp;
}
@Override
public void insertEmp(Emp emp) throws IOException {
//获得SqlSession
SqlSession sqlSession = MybatisUtils.getSession();
//执行sql
sqlSession.insert("org.lanqiao.mapper.EmpMapper.insertEmp",emp);
sqlSession.commit();
//释放资源
MybatisUtils.closeSession();
}
@Override
public void deleteEmpByNo(Integer empno) throws IOException {
//获得SqlSession
SqlSession sqlSession = MybatisUtils.getSession();
//执行sql
sqlSession.delete("org.lanqiao.mapper.EmpMapper.deleteEmpByNo",empno);
sqlSession.commit();
//释放资源
MybatisUtils.closeSession();
}
@Override
public void updateEmpByNo(Emp emp) throws IOException {
//获得SqlSession
SqlSession sqlSession = MybatisUtils.getSession();
//执行sql
sqlSession.update("org.lanqiao.mapper.EmpMapper.updateEmpByNo",emp);
sqlSession.commit();
//释放资源
MybatisUtils.closeSession();
}
}
mapper.xml
<?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="org.lanqiao.mapper.EmpMapper">
<insert id="insertEmp" parameterType="org.lanqiao.pojo.Emp">
insert into emp (empno, ename, job, hiredate, sal)
value (#{empno},#{ename},#{job},#{hiredate},#{sal});
</insert>
<update id="updateEmpByNo" parameterType="org.lanqiao.pojo.Emp">
update emp set ename=#{ename} where empno=#{empno}
</update>
<delete id="deleteEmpByNo" parameterType="integer">
delete from emp where empno = #{empno}
</delete>
<select id="findAll" resultType="org.lanqiao.pojo.Emp">
select * from `emp`
</select>
<select id="selectEmpByNo" parameterType="integer" resultType="org.lanqiao.pojo.Emp">
select * from `emp` where empno = #{empno}
</select>
</mapper>
测试
@Test
public void deleteTest() throws IOException {
EmpMapper empMapper = new EmoDaoImpl();
empMapper.deleteEmpByNo(8888);
}
@Test
public void updateTest() throws IOException {
Emp emp = new Emp(8888,"赵虎","程序员",new Date(),10000.00);
EmpMapper empMapper = new EmoDaoImpl();
empMapper.updateEmpByNo(emp);
}
@Test
public void insertTest() throws IOException {
Emp emp = new Emp(8888,"张龙","程序员",new Date(),10000.00);
EmpMapper empMapper = new EmoDaoImpl();
empMapper.insertEmp(emp);
}
@Test
public void findAllTest() throws IOException {
EmpMapper empMapper = new EmoDaoImpl();
List<Emp> emps = empMapper.findAll();
for (Emp e : emps) {
System.out.println(e);
}
}
@Test
//通过session获得mapper映射
public void selectEmpByNoTest() throws IOException {
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
//通过主配置文件创建SqlSessionFactory对象
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//通过sqlSessionFactory对象打开一个session
SqlSession sqlSession = sqlSessionFactory.openSession();
//通过sqlSession使用动态代理来实现dao接口
EmpMapper empMapper = sqlSession.getMapper(EmpMapper.class);
//执行sql
Emp emp = empMapper.selectEmpByNo(1001);
System.out.println(emp);
}
2、动态代理
通过之前的操作,我们发现dao的实现类其实并没有做什么实质性的工作,仅仅是通过sqlSession的相关API定位到StudentMapper映射文件中的ID中的sql语句,其实真正操作DB的是mapper中的sql。所以mybatis就抛开了dao层的实现类,可以直接定位到mapper中的sql!然后执行sql对DB进行操作!这种对dao的实现方式我们称为Mapper的动态代理方式!
Mapper接口开发需要遵循以下规范:
1、 Mapper.xml文件中的namespace与mapper接口的类路径相同。
2、 Mapper接口方法名和Mapper.xml中定义的每个statement的id相同
3、 Mapper接口方法的输入参数类型和mapper.xml中定义的每个sql 的parameterType的类型相同
4、 Mapper接口方法的输出参数类型和mapper.xml中定义的每个sql的resultType的类型相同
5 、注册映射文件 使用class的方式 注册接口
实现
删除mapper的实现类
直接调用mapper中的方法
@Test
public void insertTest() throws IOException {
// 通过session的getMapper方法 来获取Mapper的对象
SqlSession session = MBUtils.getSession();
EmpMapper mapper = session.getMapper(EmpMapper.class);
Emp emp = new Emp();
emp.setEname("李四");
emp.setJob("架构师");
emp.setSal(25000.00);
mapper.insertEmp(emp);
// 此时该对象的主键就有值了
session.commit();
System.out.println(emp.getEmpno());
}