ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

博客项目注意点

2019-10-26 15:09:05  阅读:149  来源: 互联网

标签:category String 项目 博客 list private 注意 Integer public


登录

如果出现:Write operations are not allowed in read-only mode (FlushMode.MANUAL): Turn your Session into FlushMode.COMMIT/AUTO or remove ‘readOnly’ marker from transaction definition错误时。

需要在业务层开启事务,如果需要对数据库进行曾,删,改时

1.在hibernate的配置文件中配置事务管理器,事务增强(开启注解)

<!--配置事务管理器-->
<bean id="transactionManager"
      class="org.springframework.orm.hibernate5.HibernateTransactionManager">
    <property name="sessionFactory" ref="sessionFactory"/>
</bean>
<!--开启注解  增强-->
<tx:annotation-driven transaction-manager="transactionManager"/>

2.直接在业务类上加入注解

@Transactional
public class CategoryServiceImpl implements CategoryService {
    @Setter
    private CategoryDao categoryDao;
    @Override
    public void addCategory(Category category) {
        categoryDao.addCategory(category);
    }

}

分类

json jar包导入正确

使用data-id=" " 将id绑定到按钮上发送请求时可以携带id过去

<a href="#" class="updatebtn" data-id="<s:property value="#category.cid"/>">
    <img class="img_icon" src="${pageContext.request.contextPath}/images/edit_icon.png" alt="">
</a>

使用Ajax(前端技术) 将请求发送给web层

 $.post("${pageContext.request.contextPath}/category/category_updateUI.action",{"cid":cid},function (data) {
          },"json");

将web层取出的数据直接在页面显示

//将取出的数据转化为json类型
JSONArray jsonArray = JSONArray.fromObject(oneCategory, jsonConfig);
System.out.println(jsonArray.toString());

//将数数据打印到页面
ServletActionContext.getResponse().setContentType("text/html;charset=UTF-8");
ServletActionContext.getResponse().getWriter().println(jsonArray.toString());

通过json可以直接将数据传到data里,所以取得时候直接用data取就行了

          $.post("${pageContext.request.contextPath}/category/category_updateUI.action",{"cid":cid},function (data) {
             console.log("-------json------");
              console.log(data);
             /!*把json数据展示到文本框 *!/
              $("#parentid2").val(data[0].cparentid);
              $("#cname2").val(data[0].cname);
          },"json");

注意:在使用迭代器的时候按钮的标注不能使用id,因为id时唯一的表示,要使用class

<s:iterator value="categoryList" var="category">
    <ul class="list_goods_ul">
        <li><s:property value="#category.cparentid"/> </li>
        <li><s:property value="#category.cname"/></li>
        <li>
            <a href="#" class="updatebtn" data-id="<s:property value="#category.cid"/>">
                <img class="img_icon" src="${pageContext.request.contextPath}/images/edit_icon.png" alt="">
            </a>
        </li>
        <li><a href="#"><img class="img_icon" src="${pageContext.request.contextPath}/images/delete_icon.png" alt=""></a></li>
    </ul>
</s:iterator>

样式地址使用绝对路径:${pageContext.request.contextPath}

文章

建立关系映射注意点:有外键的一定要注意在domain里面也要创建一个相应的外键对象

在配置文件中要描述是多对一还是一对多配置好,get,set方法

private Integer article_id;
private String article_title;
private String article_content;
private Integer article_time;
private String article_pic;
private String article_desc;
//外键
private Category category;
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
    <class name="com.blog.domain.Article" table="article" >
        <!--建立类属性哪一个是主键  还要跟数据库当中主键进行对象-->
        <id name="article_id" column="article_id" >
            <generator class="native"/>
         </id>
        <!--建立类中的普通属性与数据库当中字段进行关联-->
        <property name="article_title" column="article_title" />
        <property name="article_content" column="article_content"/>
        <property name="article_time" column="article_time"/>
        <property name="article_pic" column="article_pic"/>
        <property name="article_desc" column="article_desc"/>
        <many-to-one name="category" class="com.blog.domain.Category" column="article_cid"></many-to-one>
    </class>
</hibernate-mapping>

注意点:

要是出现错误:

org.hibernate.LazyInitializationException: could not initialize proxy [com.blog.domain.Category#2] - no Session

是由于事务在业务层开启和关闭的当,而用tostring覆盖了category属性的时候,由于使用的是懒加载方式所以会报出没有找到session的错误

解决:

<!--配置延迟加载-->
<filter>
    <filter-name>OpenSessionInViewFilter</filter-name>
    <filter-class>org.springframework.orm.hibernate5.support.OpenSessionInViewFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>OpenSessionInViewFilter</filter-name>
    <url-pattern>*.action</url-pattern>
</filter-mapping>

给web.xml文件配置一个延迟加载过滤器,让事务在web层也开启,注意:需要把延迟加载配置在struts的前面

分页

需要数据:当前页的页码(currentPage) 一页展示多少条数据(pageSize)

当前页查询的角标(index) 总的记录数(totalCount) 总的分页数(totalPage)

当前页的数据(pageList)

数据库中查询的位置=(currentPage-1)*pageSize

总页数=totalCount*1.0 / totalPage 向上取整(ceil)

示例代码:

package com.blog.domain;

import java.util.List;

public class PageBean<T> {
    /*当前页*/
    private Integer currentPage;
    /*一页有多少条数据*/
    private Integer pageSize;
    /*当前查询的角标*/
    private Integer index;
    /*总的记录数*/
    private Integer totalCount;
    /*总页数*/
    private Integer totalPage;
    /*当前页的数据*/
    private List<T> pageList;

    /*如果当前页没有设置,默认设置为第1页*/
    public void setCurrentPage(Integer currentPage) {
        if (currentPage == null) {
            currentPage = 1;
        }
        this.currentPage = currentPage;
    }
    /*如果没有设置当前页总记录数据,设置默认记录数为一页5条*/
    public void setPageSize(Integer pageSize) {
        if (pageSize == null) {
            pageSize = 5;
        }
        this.pageSize = pageSize;
    }
    /*计算当前页从数据库当中查询的位置*/
    public Integer getIndex() {
        return (currentPage-1)*pageSize;
    }
    /*计算总页数*/
    public Integer getTotalPage() {
        double ceil = Math.ceil(totalCount * 1.0 / pageSize);
        return (int)ceil;
    }
}

文章分页注意:

1.创建PageBean

2.创建一个action方法,并由jsp发送action地址

3.web层接受参数,创建离线查询语句,调用业务层处理数据,将数据写入值栈,请求转发

public class ArticleAction extends ActionSupport implements ModelDriven<Article> {
    @Override
    public Article getModel() {
        return article;
    }
    @Setter
    private Article article;
    @Setter
    private ArticleService articleService;
    public String list(){
        List<Article> list = articleService.list();
        ActionContext.getContext().getValueStack().set("list",list);
        return "list";
    }

    public String add(){
        System.out.println(article.getArticle_title());
        return null;
    }
    @Setter
    private Integer currentPage;
    @Setter
    private String keyWord;
    public String pageList(){
        //离线条件查询
        DetachedCriteria detachedCriteria = DetachedCriteria.forClass(Article.class);
        //添加查询条件这也是为什么要把离线条件查询直接写在web的原因
        if (keyWord!=null){
            detachedCriteria.add(Restrictions.like("article_title","%"+ keyWord+ "%"));
        }
        PageBean<Article> pageBean=articleService.getPageList(detachedCriteria,currentPage,5);
        ActionContext.getContext().getValueStack().push(pageBean);
        return "list";

    }

}

4.业务层给pagebean设置属性,调用dao层查询数据,返回一个pageBean给web层

    public PageBean<Article> getPageList(DetachedCriteria detachedCriteria, Integer currentPage, int pageSize) {
        //设置数据,查询数据库
        //1.设置当前页
        pageBean.setCurrentPage(currentPage);
        //2.设置一页显示的个数
        pageBean.setPageSize(pageSize);
/*        //3.设置数据库查询的位子
        pageBean.setIndex(pageBean.getIndex());*/
        //4.设置总的记录数 需要从数据库中查找
        Integer totalCount=articleDao.getTotalCount(detachedCriteria);
        pageBean.setTotalCount(totalCount);
        //5.设置总页数
        pageBean.setTotalPage(pageBean.getTotalPage());
        //6.设置每页的数据 需要从数据库中查找
        List<Article> pageList=articleDao.getTotalList(detachedCriteria,pageBean.getIndex(),pageBean.getPageSize());
        pageBean.setPageList(pageList);
        return pageBean;
    }

5.dao层依据需求查询出数据给业务层

@Override
public Integer getTotalCount(DetachedCriteria detachedCriteria) {
    //使用setProjection(Projections.rowCount());查询出总的记录数,别的数据不需要
    //要注意的是查询出来的结果是一个Long类型的集合
    detachedCriteria.setProjection(Projections.rowCount());
    List<Long> list = ( List<Long>)this.getHibernateTemplate().findByCriteria(detachedCriteria);
    if(list.size()>0){
        return list.get(0).intValue();
    }
    return 0;
}

@Override
public List<Article> getTotalList(DetachedCriteria detachedCriteria, Integer index, Integer pageSize) {
    //由于之前使用过 detachedCriteria.setProjection(Projections.rowCount());所以要把他里面的条件清空
    //否者查询的还是之前的条件
    detachedCriteria.setProjection(null);
    List<Article> list = (List<Article>)this.getHibernateTemplate().findByCriteria(detachedCriteria, index, pageSize);
    return list;
}

关键字搜索:

1.参数的回显-----由于请求会将参数存到值栈的非根区的parameters所以取得时候应该要加上#号

<input type="text" class="am-form-field" id="input_search" value="<s:property value="#parameters.keyWord"/>" />

2.绑定参数执行下一页------为了让分页数据可以进行下一页查找,应该将回显参数也传给web层

否者会导致无法查看下一页的查询数据

//分页
$("#page").paging({
    pageNo:<s:property value="currentPage"/>,
    totalPage: <s:property value="totalPage"/>,
    totalSize: <s:property value="totalCount"/>,
    callback: function(num) {
        var keyWord = $("#input_search").val();
         $(window).attr('location','${ctx}/article/article_pageList.action?currentPage='+num+"&keyWord="+keyWord);
    }
});

开发者模式

<constant name="struts.devMode" value="true"></constant>
<package name="Article" extends="struts-default" namespace="/article">
    <action name="article_*" class="articleAction" method="{1}">
        <result name="list" >/mgr_main.jsp</result>
        <allowed-methods>list,add,pageList</allowed-methods>
    </action>
</package>

在需要打开开发者模式的Struts前面加上

在需要查看debug的jsp加上

<s:debug></s:debug>

就可以点击查看debug值栈里面的数据

图片上传

步骤:

1.监听发布按钮

$("#send").click(function () {
    $("#blog_form").submit();
})

2.设置form表单 在form表单后面加上enctype=“multipart/form-data”(文件上传)属性

<form id="blog_form" action="${pageContext.request.contextPath}/article/article_add.action" method="post" enctype="multipart/form-data">
    
</form>

3.在action里面处理文件上传

​ 3.1设置文件上传需要的属性注入进来

@Setter
private String uploadFileName; // 文件名称
@Setter
private File upload; // 上传文件 upload 临时文件
@Setter
private String uploadContentType; // 文件类型

​ 3.2处理方法里面的文件上传

    public String add() throws IOException {
        //上传图片
/*        System.out.println(uploadFileName);
        System.out.println(upload);
        System.out.println(uploadContentType);*/
        //1.判断文件临时文件是否存在
        if (upload!=null){
            /* 临时文件存在就开始处理*/
            //2.设置文件的上传路径
            String path = ServletActionContext.getServletContext().getRealPath("/upload");
            /*对文件名称进行处理*/
         /*   截取文件后缀名*/
            //3.获取截取角标
            int index = uploadFileName.lastIndexOf(".");
            //4开始截取
            String suffixName = uploadFileName.substring(index);
            //5.生成随机的名字并去除里面的‘-’
            String uuidFileName = UUID.randomUUID().toString().replace("-", "")+suffixName;
            //6.判断上传路径是否存在,不存在就创建一个
            File file = new File(path);
            if(!file.exists()){
                file.mkdirs();
            }
            //7.上传文件
            File dictFile = new File(path + "/" + uuidFileName);
            FileUtils.copyFile(upload,dictFile);

        }
        return null;
    }

文件上传处理步骤:

​ 1.首先判断文件是否存在 if (upload!=null){ }存在的话就处理

​ 2.设置文件的上传路径 ServletActionContext.getServletContext().getRealPath("/upload");

​ 3.随机生成文件名

​ 3.1先获取文件的截取角标

​ int index = uploadFileName.lastIndexOf(".");

​ 3.2截取文件的后缀

​ String suffixName = uploadFileName.substring(index);

​ 3.3随机生成文件名并和后缀拼接 还要将里面的‘-’ 去掉

​ String uuidFileName = UUID.randomUUID().toString().replace("-", “”)+suffixName;

​ 4.判断上传的路径是否存在 如果不存在就创建一个

        File file = new File(path);
        if(!file.exists()){
            file.mkdirs();
        }

​ 5.上传文件

        File dictFile = new File(path + "/" + uuidFileName);
        FileUtils.copyFile(upload,dictFile);

注意:导入的file包应该是import java.io.File;

分类下拉框

父框(前面一个)

1.一到添加文章的界面就显示父类的属性,使用json异步加载的办法

​ 1.先发送一个action,携带cparentid=0的参数从数据库获取分类数据

​ 1.1根据cparentid查找。

​ 1.2将查找出来的数据转为json格式设置响应字符的编码并反显到function()中。

public String getCategory() throws IOException {
    List<Category> list=articleService.getCategory(cparentid);
    //把list转化为json格式回显
    JSONArray jsonArray = JSONArray.fromObject(list,new JsonConfig());
    //设置响应字符编码
    ServletActionContext.getResponse().setContentType("text/html;charset=utf-8");
    ServletActionContext.getResponse().getWriter().println(jsonArray.toString());
    return null;
}

​ 2.获取的数据回显到function(data) 遍历data并且写入到option里面

$.post("${ctx}/article/article_getCategory.action",{"cparentid":0},function (data) {
    console.log(data);
    //遍历
    $(data).each(function (i, obj) {
        $("#category_select").append("<option value="+obj.cid+">"+obj.cname+"</option>");
    })
    //一进来出发事件
    $("#category_select").trigger("change");
},"json");

子框(后面一个)

1.注册一个change事件

2.从父类的option中取出value ,var cid = $("#category_select").val();

3.根据父类的value从数据库中查找出父类对应子类的category

4.将category在子框中显示

注意:

​ 1.将category在子框中显示钱需要将子框里面的数据先清空 $("#skill_select").empty();否者会导致所有的子类叠加

​ 2.在进入添加文章的界面时就需要让父类出发change事件否者一进来子类不会被加载

//一进来出发事件
$("#category_select").trigger("change");
//监听分类改变
$("#category_select").on("change",function () {
    var cid = $("#category_select").val();
    $.post("${ctx}/article/article_getCategory.action",{"cparentid":cid},function (data) {
        $("#skill_select").empty();
        $(data).each(function (i, obj) {
            $("#skill_select").append("<option value="+obj.cid+">"+obj.cname+"</option>");
        })
    },"json")
})

标签:category,String,项目,博客,list,private,注意,Integer,public
来源: https://blog.csdn.net/weixin_43174445/article/details/102756510

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有