java——Mybatis(2)
怎么理解这个语句:
要理解这个需要理解代理模式,下面就先简单介绍动态代理:
静态代理:
静态代理有分为继承和聚合的方式,继承即在子类调用super.方法名调用代理父类的方法,并可在子类对其方法进行重写以实现代理;
聚合是指通过重建构造函数传入对象,再调用传入对象的方法即可实现代理;如:
上例中,m为代理类,被代理类car通过InvocationHandler接口被传入,在通过反射调用car类方法且进行业务处理后形成一个业务处理类TimeHandler;再通过Proxy.newProxyInstance方法形成一个代理类后执行;只要传入的类不同,各个传入类都可以被业务逻辑所包装。
通过cglib来实现动态代理:
1、导入支持cglib的jar包
2、定义好一个类及编写好类中的方法;
3、创建一个继承MethodInterceptor类的方法,重写里面的intercept方法且可在方法里增加业务逻辑:
4、在继承MethodInterceptor类的类中需要提供创建代理类的方法,以供我们在别java文件中使用代理类进行方法调用:
5、使用测试类调用代理类进行测试:
以上就是两种动态代理的方法;回过头来,我们应该怎么理解
这个语句等同于下边的语句:
IMessage为与message配置文件相对应的接口,这个接口就定义原本语句应该规范好的namespace(命名空间).id(与sql关联的id),传入的参数message以及返回值;
为了让Mybatis可以识别对这个接口,需将配置文件里的namespace改为
这样Mybatis就会自动将接口和配置文件进行关联;
而imessage.queryMessageList();没实现类的接口为什么可以执行未定义的方法,这就用到动态代理了;
也就是最后所实行的方法是MapperProxy.invoke(),那这个方法又怎么对应上sqlSession.selectList()方法呢?
也就是最后结论为
尝试做出以下的接口式编程代码:
分页的实现:
1、定义一个page实体类,定义好一页显示的数量
package com.imooc.entity; /** * 分页对应的实体类 */ public class Page { /** * 总条数 */ private int totalNumber; /** * 当前第几页 */ private int currentPage; /** * 总页数 */ private int totalPage; /** * 每页显示条数 */ private int pageNumber = 5; /** * 数据库中limit的参数,从第几条开始取 */ private int dbIndex; /** * 数据库中limit的参数,一共取多少条 */ private int dbNumber; /** * 根据当前对象中属性值计算并设置相关属性值 */ public void count() { // 计算总页数 int totalPageTemp = this.totalNumber / this.pageNumber; int plus = (this.totalNumber % this.pageNumber) == 0 ? 0 : 1; totalPageTemp = totalPageTemp + plus; if(totalPageTemp <= 0) { totalPageTemp = 1; } this.totalPage = totalPageTemp; // 设置当前页数 // 总页数小于当前页数,应将当前页数设置为总页数 if(this.totalPage < this.currentPage) { this.currentPage = this.totalPage; } // 当前页数小于1设置为1 if(this.currentPage < 1) { this.currentPage = 1; } // 设置limit的参数 this.dbIndex = (this.currentPage - 1) * this.pageNumber; this.dbNumber = this.pageNumber; } public int getTotalNumber() { return totalNumber; } public void setTotalNumber(int totalNumber) { this.totalNumber = totalNumber; this.count(); } public int getCurrentPage() { return currentPage; } public void setCurrentPage(int currentPage) { this.currentPage = currentPage; } public int getTotalPage() { return totalPage; } public void setTotalPage(int totalPage) { this.totalPage = totalPage; } public int getPageNumber() { return pageNumber; } public void setPageNumber(int pageNumber) { this.pageNumber = pageNumber; this.count(); } public int getDbIndex() { return dbIndex; } public void setDbIndex(int dbIndex) { this.dbIndex = dbIndex; } public int getDbNumber() { return dbNumber; } public void setDbNumber(int dbNumber) { this.dbNumber = dbNumber; } }
2、在Dao层增加一个返回查询数据总条数的方法:
public int count(Message message) { DBAccess dbAccess = new DBAccess(); SqlSession sqlSession = null; int result = 0; try { sqlSession = dbAccess.getSqlSession(); IMessage imessage = sqlSession.getMapper(IMessage.class); result = imessage.count(message); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } return result;
3、返回的result条数在service层传入到Page对象中:
int totalNumber = messageDao.count(message); page.setTotalNumber(totalNumber);
page在调用setTotalNumber时会执行page里的count()方法,进而赋值好总页数、再根据好jsp页面传进当前页面的值计算出sql语句运行时从第几条开始取;再以Map的形式储存好Page和Message对象,再传入Dao层里的查询方法:
public class MessageDao { public List<Message> queryMessageList(Map<String,Object> parameter){ DBAccess dbAccess = new DBAccess(); List<Message> messageList = new ArrayList<Message>(); SqlSession sqlSession = null; try { sqlSession = dbAccess.getSqlSession(); IMessage imessage = sqlSession.getMapper(IMessage.class); messageList = imessage.queryMessageList(parameter); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); }finally { if(sqlSession!=null) { sqlSession.close(); } } return messageList; }
此时Message.xml里的查询语句为:
<select id="queryMessageList" parameterType="java.util.Map" resultMap="MessageResult"> select ID,COMMAND,DESCRIPTION,CONTENT from message <where> <if test="message.command!=null&&!"".equals(message.command.trim())">and COMMAND =#{message.command}</if> <if test="message.description!=null&&!"".equals(message.description.trim())">and DESCRIPTION like '%' #{message.description} '%'</if> </where> order by ID limit #{page.dbIndex},#{page.dbNumber} </select>
最后把查询的结果返回list.jsp页面;至此,分页结束;
拦截器:
待学习