电商项目第三天

本文介绍了电商项目中Dubbo的优化方法,包括跳过Zookeeper的直接连接方式,以及FastDFS分布式文件系统的原理和应用。同时,文章还详细讲解了商品信息的分页查询与修改的具体实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

电商项目第三天

优化dubbo

为了能更快速的开发,我们需优化dubbo,只需了解其工作原理即可。
采取直接连接,跳过zookeeper
dubbo-provider.xml更改:

<!-- 2.设置注册中心,zookeeper地址 -->	
<!-- <dubbo:registry address="ip+端口号" protocol="zookeeper"/> -->
<dubbo:registry address="N/A"/>

dubbo-consumer.xml

<!-- 2.设置注册中心,zookeeper地址 -->	
<!-- <dubbo:registry address="ip+端口号" protocol="zookeeper"/> -->
<dubbo:registry address="N/A" check="false"/>
<!-- 全局配置 -->
<dubbo:consumer timeout="超时时间" check="false"/>
后台搭建

void 无返回值 常用语Ajax请求
ModelAndView 企业开发不常用
String + Model 常用

搭建顺序

dao-mapper-service-serviceImpl-controller

代码实现
商品回显(分页)

pojo:

//品牌ID  bigint
private Long id;
//品牌名称
private String name;
//描述
private String description;
//图片URL
private String imgUrl;
//排序  越大越靠前   
private Integer sort;
//是否可用   0 不可用 1 可用
...
//附加字段
private Integer pageNo = 1;
private Integer pageSize = 10;
//开始行
private Integer startRow;
...
public void setPageNo(Integer pageNo) {
		//计算开始行
		this.startRow = (pageNo-1)*pageSize;
		this.pageNo = pageNo;
	}
...
public void setPageSize(Integer pageSize) {
		//计算开始行
		this.startRow = (pageNo-1)*pageSize;
		this.pageSize = pageSize;
	}

dao:

//查询结果集
public List<Brand> selectBrandListByQuery(BrandQuery brandQuery);
//查询总条数
public Integer selectCount(BrandQuery brandQuery);

mapper:

<!-- 配置映射 -->
<resultMap type="Brand" id="brand">
	<result column="img_url" property="imgUrl"/><!-- 图片地址 -->
	<result column="is_display" property="isDisplay"/><!-- 是否可用 -->
</resultMap>

<!-- 查询 -->
<select id="selectBrandListByQuery" parameterType="BrandQuery" resultMap="brand">
	select id,name,description,img_url,sort,is_display
	from bbs_brand
	<where>
		<if test="name != null">
			name like "%"#{name}"%"   <!-- 模糊查询  -->
		</if>
		<if test="isDisplay != null">
			and is_display = #{isDisplay}
		</if>
	</where>
	<if test="startRow != null">
		limit #{startRow},#{pageSize}
	</if>
</select>
<!-- 查询总条数 -->
<select id="selectCount" parameterType="BrandQuery" resultType="Integer">
	select count(1)
	from bbs_brand
	<where>
		<if test="name != null">
			name like "%"#{name}"%"   <!-- 模糊查询  -->
		</if>
		<if test="isDisplay != null">
			and is_display = #{isDisplay}
		</if>
	</where>
</select>

service:

//查询分页对象
public Pagination selectPaginationByQuery(String name,Integer isDisplay,Integer pageNo);
//参数:查询名称、是否可用、起始页

serviceImpl:

public Pagination selectPaginationByQuery(String name,Integer isDisplay,Integer pageNo){
	BrandQuery bq = new BrandQuery();
	bq.setPageNo(Pagination.cpn(pageNo));
	bq.setPageSize(5);//设置每页显示数目
	StringBuilder params = new StringBuilder();
	if(null != name){
		bq.setName(name);
		params.append("name=").append(name);//回显查询名称
	}
	if(null != isDisplay){
		bq.setIsDisplay(isDisplay);
		params.append("&isDisplay=").append(isDisplay);//回显是否可用
	}else{
		bq.setIsDisplay(1);//默认点击按钮为是
		params.append("&isDisplay=").append(1);//点击左侧菜单进入没有是否可用,默认为可用
	}
	/**
	 * 构造器
	 * 
	 * @param pageNo
	 *            页码
	 * @param pageSize
	 *            每页几条数据
	 * @param totalCount
	 *            总共几条数据
	 */
	Pagination pagination = new Pagination(
			bq.getPageNo(),
			bq.getPageSize(),
			brandDao.selectCount(bq)
			);
	//设置结果集
	pagination.setList(brandDao.selectBrandListByQuery(bq));
	//设置分页展示
	pagination.pageView("/brand/list.do", params.toString());
	return pagination;
}

controller:

//分页列表查询
@RequestMapping(value="/brand/list.do")
public String list(String name,Integer isDisplay,Integer pageNo,Model model){
	
	Pagination pagination = brandService.selectPaginationByQuery(name, isDisplay, pageNo);
	model.addAttribute("pagination", pagination);
	model.addAttribute("name", name);
	if(null != isDisplay){
		model.addAttribute("isDisplay", isDisplay);
	}else{
		model.addAttribute("isDisplay", 1);
	}
	return "brand/list";
}

前端页面:

//数据回显
<c:forEach items="${pagination.list}" var="brand">
...${brand.id}...
</c:forEach>
//分页
<c:forEach items="${pagination.pageView}" var="page">
${page }
</c:forEach>
商品信息修改

dao:

//通过id查询,数据回显
public Brand selectBrandById(Long id);
//修改
public void updateBrandById(Brand brand);

mapper:

<!-- 按id查询 -->
<select id="selectBrandById" parameterType="Long" resultMap="brand">
	select id,name,description,img_url,sort,is_display
	from bbs_brand
	<where>
		id=#{id}
	</where>
</select>	
<!-- 修改 -->
<update id="updateBrandById" parameterType="Brand">
	update bbs_brand 
	<set>
		<if test="name != null">
			name = #{name},
		</if>
		<if test="description != null">
			description = #{description},
		</if>
		<if test="imgUrl != null">
			img_url = #{imgUrl},
		</if>
		<if test="sort != null">
			sort = #{sort},
		</if>
		<if test="isDisplay != null">
			is_display = #{isDisplay}
		</if>
	</set>
	<where>
		id=#{id}
	</where>
</update>

service:

//通过id查询,数据回显
public Brand selectBrandById(Long id);
//修改
public void updateBrandById(Brand brand);

serviceImpl:

@Override
public Brand selectBrandById(Long id) {
	// TODO Auto-generated method stub
	return brandDao.selectBrandById(id);
}
@Override
public void updateBrandById(Brand brand) {
	// TODO Auto-generated method stub
	brandDao.updateBrandById(brand);
}

controller:

//去修改
	@RequestMapping(value="/brand/toEdit.do")
	public String toEdit(Long id,Model model){
		Brand brand = brandService.selectBrandById(id);
		model.addAttribute("brand", brand);
		return "brand/edit";
	}
//修改
	@RequestMapping(value="/brand/edit.do")
	public String edit(Brand brand){
		brandService.updateBrandById(brand);
		return "redirect:/brand/list.do";
	}
FastDFS分布式文件系统原理

client(本机)向 tracker(跟踪器)发送请求 ,tracker查看管理的服务器,把分配好的存储地址返回client,client再根据得到的存储地址去找 storage(存储节点),进行文件上传,上传结束后,返回存储文件的地址信息。

通俗的说:你让人揍了,你去找老大搬救兵,老大看看手下谁有空,并把手下的联系方式给你,你通过联系方式找到帮手,带着帮手回去找场子了。

图片上传流程

配置上传图片工具类,common包下新建fastUtils,并引入配置文件 fdfs_client.conf
fastUtils:

public static String uploadPic(byte[] pic,String name,long size){
	ClassPathResource resource = new ClassPathResource("fdfs_client.conf");
	String path = null;
	//ClientGlobal读取配置文件
	try {
		//读取配置文件
		ClientGlobal.init(resource.getClassLoader().getResource("fdfs_client.conf").getPath());
		//老大客户端
		TrackerClient trackerClient = new TrackerClient();
		TrackerServer trackerServer = trackerClient.getConnection();
		//小弟客户端
		StorageServer storageServer = null; 
		StorageClient1 storageClient1 = new StorageClient1(trackerServer, storageServer);
		//上传图片
		String ext = FilenameUtils.getExtension(name);//获取文件拓展名
		//meta 信息
		NameValuePair[] meta_list = new NameValuePair[3];
		meta_list[0] = new NameValuePair("fileName",name);
		meta_list[1] = new NameValuePair("fileNameExt",ext);
		meta_list[2] = new NameValuePair("fileSize",String.valueOf(size));
		//图片路径信息,还缺少ip
		path = storageClient1.upload_file1(pic, ext, meta_list);
	} catch (Exception e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
	return path;
}

设置固定ip,业务常量

public class ConStants {
	//图片服务器
	public static final String IMG_URL = "http://ip.../";
}

service:

//上传图片
public String upLoadPic(byte[] pic,String name,long size);

serviceImpl:

@Override
public String upLoadPic(byte[] pic, String name, long size) {
	// TODO Auto-generated method stub
	return FastDFSUtils.uploadPic(pic, name, size);
}

controller:


@Autowired
private UploadService uploadService;
//上传图片
@RequestMapping(value="/upload/uploadPic.do")
public void uploadPic(@RequestParam(required=false) MultipartFile pic,HttpServletResponse response){
	try {
		String path = uploadService.upLoadPic(pic.getBytes(), pic.getOriginalFilename(), pic.getSize());
		
		String url = ConStants.IMG_URL+path;
		JSONObject jo = new JSONObject();
		jo.put("url", url);
		
		response.setContentType("application/json;charset=UTF-8");
		response.getWriter().write(jo.toString());
	} catch (IOException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
}

第三天内容结束
所学知识

  1. 基础业务流程的巩固
  2. 分页工具类的应用(看了源码才明白差距)
  3. FastDFS原理及使用
  4. 新的编程思想

遇到错误

  1. controller参数写了实体类却没有接到对象信息(原因:实体类没写set方法)
  2. meta信息不能为空,否则显示空指针异常
  3. 图片不回显(原因:虚拟机镜像损坏)
  4. 控制台显示连接超时(原因:固定业务常量ip写错了,蠢!!!)
  5. 之前没搞懂分页的原理,看了源码已了解

致谢晓欣老师!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值