zoukankan      html  css  js  c++  java
  • 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&amp;&amp;!&quot;&quot;.equals(message.command.trim())">and COMMAND =#{message.command}</if>
            <if test="message.description!=null&amp;&amp;!&quot;&quot;.equals(message.description.trim())">and DESCRIPTION like '%' #{message.description} '%'</if>
        </where>
        order by ID limit #{page.dbIndex},#{page.dbNumber}
        </select>

    最后把查询的结果返回list.jsp页面;至此,分页结束;

    拦截器:

    待学习

  • 相关阅读:
    重谈MST及Kruskal算法
    小技巧—边权转点权
    JDOJ 1062 过路费
    总结—二分答案求解问题
    CF10D LCIS
    NOIP 2012 摆花
    SDOI 2014 旅行
    CF550C Divisibility by Eight
    CF295C Greg and Friends
    USACO Closing the Farm
  • 原文地址:https://www.cnblogs.com/lzj-learn/p/12512264.html
Copyright © 2011-2022 走看看