3.1MyBatis的动态代理
在调用MyBatis的类中的代码是重复性的(见上篇MyBatis学习笔记),即不管是执行其他数据库操作或执行多次相同操作还是要把这些代码写一遍,所以我们可以写一个工具类,把重复性的代码都放在这里,需要时调用即可
创建utils包和MyBatisUtils工具类
public class MyBatisUtils {
private static SqlSessionFactory factory=null;
static{
String con="mybatis.xml";
try {
InputStream in = Resources.getResourceAsStream(con);
factory= new SqlSessionFactoryBuilder().build(in);
} catch (IOException e) {
e.printStackTrace();
}
}
public static SqlSession getSqlSession(){//获取SqlSession方法
SqlSession sqlSession=null;
if(factory!=null){
//非自动提交事务
sqlSession=factory.openSession();
}
return sqlSession;
}
}
则调用MyBatis类如下:
public class MyApp2 {//查询数据库的调用类
public static void main(String[] args){
SqlSession sqlSession = MyBatisUtils.getSqlSession();
String sqlId="com.mybatis.dao.StudentDao.selectStudents";
List<Student> studentList = sqlSession.selectList(sqlId);
for (Student student : studentList){
System.out.println(student);
}
sqlSession.close();
}
}
但是如此,我们的调用类和dao类却没有什么关联,所以我们要把一些操作写入dao类中
public class StudentDaoImpl implements StudentDao {
@Override
public List<Student> selectStudents() {
//获取SqlSession对象
SqlSession sqlSession= MyBatisUtils.getSqlSession();
String sqlId="com.mybatis.dao.StudentDao.selectStudents";
List<Student> students=sqlSession.selectList(sqlId);
sqlSession.close();
return students;
}
@Override
public int insertStudent(Student student) {
//获取SqlSession对象
SqlSession sqlSession= MyBatisUtils.getSqlSession();
String sqlId="com.mybatis.dao.StudentDao.insertStudent";
int num = sqlSession.insert(sqlId, student);
//提交事务
sqlSession.commit();
sqlSession.close();
return num;
}
}
则调用类如下:
public class TestMyBatis {
@Test
public void test01(){
StudentDao studentDao=new StudentDaoImpl();
List<Student> l=studentDao.selectStudents();
for (Student s:l){
System.out.println(s);
}
}
@Test
public void testinsert(){
StudentDao dao=new StudentDaoImpl();
Student student=new Student();
student.setId(1008);
student.setName("新添加");
student.setEmail("insert@qq.com");
student.setAge(16);
int i = dao.insertStudent(student);
System.out.println(i);
}
}
我们看上面可以发现:
- dao对象的类型是
StudentDao
,全限定名称:com.mybatis.dao.StudentDao
和namespace
一致 - 方法名称:
selectStudent
和mapper文件中的id值一致 - 通过dao中方法的返回值可以确定MyBatis需要调用什么SqlSession方法,返回值=list==>调用
selectList()
,返回值=int/非int==>看mapper文件中标签是<insert>
还是<update>
再调用相应方法
为此,我们可以通过mybatis的动态代理:mybatis根据dao的方法调用,获取执行sql语句的信息
mybatis会根据你的dao接口,创建出一个dao接口的实现类并创建这个类的对象
完成SqlSession调用方法,访问数据库
调用类如下:
public class TestMyBatis {
@Test
public void test01(){
SqlSession sqlSession= MyBatisUtils.getSqlSession();
StudentDao dao=sqlSession.getMapper(StudentDao.class);
List<Student> list = dao.selectStudents();
System.out.println("原理=="+dao.getClass().getName());
for (Student s: list
) {
System.out.println(s);
}
}
@Test
public void testinsert(){
SqlSession sqlSession=MyBatisUtils.getSqlSession();
StudentDao dao=sqlSession.getMapper(StudentDao.class);
Student student=new Student();
student.setId(1009);
student.setName("mybatis动态代理");
student.setEmail("ddd111@qq.com");
student.setAge(22);
int i = dao.insertStudent(student);
System.out.println(i);
sqlSession.commit();
sqlSession.close();
}
}
运行
通过System.out.println("原理=="+dao.getClass().getName());
我们可以看到dao是一个Proxy动态代理