事务管理、AOP总结以及MyBatis高级应用

一、事务(交易)管理
(1)容器类==集合框架==集合
(2)Web容器==Web服务器==Servlet容器==Servet引擎
(3)传播
REQUIRED:如果有事务,则参与到当前事务,如果没有则自动开始新事务,总之,必须有事务。默认最常用规则!!!
propagation=Propagation.REQUIRED
REQUIRES_NEW:必须有新事务,没有事务开启新事务,已经有事务时候,也开启新的独立事务。
propagation=Propagation.REQUIRES_NEW
NEVER:方法永远不参与事务
propagation=Propagation.NEVER
NOT_SUPPORTED:不支持事务, 如果在事务中调用,把当前事务临时挂起,执行以后再继续处理事务。
propagation=Propagation.NOT_SUPPORTED
NESTED:嵌套,当前方法不能单独使用,必须嵌套到其他事务中使用。
propagation=Propagation.NESTED
MANDATORY:不支持事务, 不能再事务中调用,如果调用就出现异常
propagation=Propagation.MANDATORY
二、AOP总结
反射->动态代理->AOP->声明式事务管理
动态代理:
(1)JDK 动态代理: java.lang.reflect.Proxy 使用是有前提的,必须有接口!!
(2)CGlib动态代理:基于类的动态代理
注:Spring的AOP动态代理会自动利用 JDK Proxy和CGlib,如果有接口就优先使用JDK Proxy,其他情况下使用CGlib
三、MBatis高级应用
分页查询
分页查询,其目的在于在查询结果较多,需要分批向浏览器传输数据。在查询结果多时候经常采用。
实现分页查询:
(1)数据持久层支持分页查询功能,主要是才有分页查询SQL实现,可以根据数据行范围,返回一部分查询结果。
(2)业务层将页号换算为分页查询参数,提交给数据层。
(3)表现层控制器与HTML页面配合显示出适当的页面效果。
案例:分页查询笔记本列表
数据层 NotebookDao.java :

/**
 * 分页查询,必须传递参数:
 *  userId: 用户的ID
 *  start: 查询起始行号
 *  rows: 一次查询的最多行数
 * @param params 封装参数的Map
 * @return List<Map> 
 */
List<Map<String, Object>>
    findNotebooksByPage(
        Map<String, Object> params);

添加SQL NotebookMapper.java:

<select id="findNotebooksByPage"
    parameterType="map"
    resultType="map">
    select 
        cn_notebook_id as id,
        cn_notebook_name as name
    from
        cn_notebook
    where
        cn_user_id=#{userId}
    <if test="start != null">
        limit #{start}, #{rows} 
    </if>
</select>

添加业务层方法 NotebookService.java:

List<Map<String, Object>> 
    listNotebooks(String userId, 
    int pageNum, int pageSize)
    throws UserNotFoundException;

实现业务层方法 NotebookServiceImpl.java

@Transactional(readOnly=true)
public List<Map<String, Object>> listNotebooks(
    String userId, int pageNum, int pageSize)
    throws UserNotFoundException {
    if(userId==null||userId.trim().isEmpty()){
        throw new UserNotFoundException("ID空");
    }
    User user = userDao.findUserById(userId);
    if(user==null){
        throw new UserNotFoundException("木有人");
    }
    //计算出起始行号
    int start = pageNum*pageSize;
    Map<String, Object> params=
        new HashMap<String, Object>();
    params.put("userId", userId);
    params.put("start", start);
    params.put("rows", pageSize);
    return notebookDao.findNotebooksByPage(params);
}

添加控制器方法 NotebookController.java:

@RequestMapping("notebooks.do")
@ResponseBody
public JsonResult<List<Map<String, Object>>>
    notebooks(String userId, int page){
    int size=6;
    List<Map<String, Object>> list=
        notebookService.listNotebooks(
            userId, page, size);
    return new JsonResult<List<Map<String,Object>>>(list);
}

重构 loadNotebooksAction 方法:

function loadNotebooksAction(){

    //获取 page 数据 
    //$(this)是li.more, 显示li时候,已经在LI
    //上绑定了页号数据,这里是获取页号数据
    //如果不存在这个数居说明是第一次显示
    //则显示第0页的内容
    var page=$(this).data('page');
    if(! page){
        page = 0;
    }

    //console.log('loadNotebooksAction()');
    //var url='notebook/list.do';
    var url='notebook/notebooks.do';
    //var data={userId:getCookie('userId')};
    var data={userId:getCookie('userId'),
            page:page};
    //console.log(data);
    //console.log(url);
    $.getJSON(url, data, function(result){
        if(result.state==SUCCESS){
            var list=result.data;
            console.log(list); 
            model.updateNotebooks(list, page);
        }
    });
}

重构 updateNotebooks 方法:

model.updateNotebooks=function(list, page){
    var template='<li class="online notebook">'+
        '<a>'+
        '<i class="fa fa-book " title="online" rel="tooltip-bottom"></i>'+
        '[notebook.name]</a></li>';
    //检查如果是第一次获得笔记本列表,就直接
    //保存到 模型中,如果是追加显示就将两个
    //数组合并为一个笔记本列表
    if(! this.notebooks ){
        this.notebooks=list;
    }else{
        //concat 方法用于合并两个数组
        this.notebooks=
            this.notebooks.concat(list); 
    }
    //console.log(this);
    var ul=$('#notebooks').empty();
    for(var i=0;i<this.notebooks.length;i++){
        var notebook=this.notebooks[i];
        // id name
        var li=template.replace(
            '[notebook.name]', notebook.name);
        //在DOM对象上绑定数据 index
        li = $(li).data('index',i);
        ul.append(li);
    }
    var li = $('<li class="online more">'+
            '<a>More...</a></li>');
    //绑定下一页的页号
    li.data('page', page+1);
    ul.append(li);
};

重构事件监听js edit_init.js:

...
//绑定点击笔记本列表的事件
//showNotesAction函数定义在edit_note.js中
$('#notebooks').on(
        'click','li.notebook', showNotesAction);
//绑定 More 连接监听  
$('#notebooks').on(
        'click','li.more', loadNotebooksAction);
...

四、关于全文检索:
(1)数据量非常大:搜索引擎技术,进行全文检索,如:org.apache.lucene
(2)小数据量:可以使用 like 模糊查询,like是没有索引支持的顺序查询,性能很差。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值