天哪!手动编写mybatis雏形竟然这么简单 (6)

我们先引入我们自定义的框架依赖。以及数据库和单元测试

<dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.11</version> </dependency> <dependency> <groupId>cn.quellanan</groupId> <artifactId>myself-mybatis</artifactId> <version>1.0.0</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.10</version> </dependency>

然后我们写一个测试类
1、获取SqlMapperConfig.xml的文件流
2、获取Sqlsession
3、执行查找操作

@org.junit.Test public void test() throws Exception{ InputStream inputStream= Resources.getResources("SqlMapperConfig.xml"); SqlSession sqlSession = new SqlSessionFactoryBuilder().build(inputStream).openSqlSession(); List<User> list = sqlSession.selectList("cn.quellanan.dao.UserDao.selectAll"); for (User parm : list) { System.out.println(parm.toString()); } System.out.println(); User user=new User(); user.setUsername("张三"); List<User> list1 = sqlSession.selectList("cn.quellanan.dao.UserDao.selectByName", user); for (User user1 : list1) { System.out.println(user1); } }

在这里插入图片描述


可以看到已经可以了,看来我们自定义的持久层框架生效啦。

在这里插入图片描述

优化

但是不要高兴的太早哈哈,我们看上面的测试方法,是不是感觉和平时用的不一样,每次都都写死statementId ,这样不太友好,所以我们接下来来点骚操作,通用mapper 配置。
我们在SqlSession中增加一个getMapper方法,接收的参数是一个类。我们通过这个类就可以知道statementId .

/** * 使用代理模式来创建接口的代理对象 * @param mapperClass * @param <T> * @return */ public <T> T getMapper(Class<T> mapperClass);

具体实现就是利用JDK 的动态代理机制。
1、通过Proxy.newProxyInstance() 获取一个代理对象
2、返回代理对象
那代理对象执行了哪些操作呢?
创建代理对象的时候,会实现一个InvocationHandler接口,重写invoke() 方法,让所有走这个代理的方法都会执行这个invoke() 方法。那这个方法做了什么操作?
这个方法就是通过传入的类对象,获取到对象的类名和方法名。用来生成statementid 。所以我们在mapper.xml 配置文件中的namespace 就需要制定为类路径,以及id 为方法名。
实现方法:

@Override public <T> T getMapper(Class<T> mapperClass) { Object proxyInstance = Proxy.newProxyInstance(DefaultSqlSeeion.class.getClassLoader(), new Class[]{mapperClass}, new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { //获取到方法名 String name = method.getName(); //类型 String className = method.getDeclaringClass().getName(); String statementid=className+"."+name; return selectList(statementid,args); } }); return (T) proxyInstance; }

我们写一个UserDao

public interface UserDao { List<User> selectAll(); List<User> selectByName(User user); }

这个是不是我们熟悉的味道哈哈,就是mapper层的接口。
然后我们在mapper.xml 中指定namespace 和id

在这里插入图片描述


接下来我们在写一个测试方法

@org.junit.Test public void test2() throws Exception{ InputStream inputStream= Resources.getResources("SqlMapperConfig.xml"); SqlSession sqlSession = new SqlSessionFactoryBuilder().build(inputStream).openSqlSession(); UserDao mapper = sqlSession.getMapper(UserDao.class); List<User> users = mapper.selectAll(); for (User user1 : users) { System.out.println(user1); } User user=new User(); user.setUsername("张三"); List<User> users1 = mapper.selectByName(user); for (User user1 : users1) { System.out.println(user1); } }

在这里插入图片描述

番外

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpxyxx.html