项目场景:
配比计算器实现的功能就是将各种厂家不同的矿石中的元素,通过不同比例混合,使每种元素达到指定值,并且总价最低。页面使用的jsp,修改起来是真不方便。最后mybatis Yes!!
经历过程:
一、配比计算器功能完善(排列组合,数字拆分实现)
问题描述:
前提:每个厂家有一种矿石,矿石中有不同元素且含量不一样,现在有多家厂商。
过程:将这些矿石混合,形成新的矿石,使元素含量达标。
目的:新的矿石在元素含量达标的情况下,耗资最低。
实现过程:
(1)将数字拆分:效果:5->{ (1,4);(1,1,3);(1,1,1,2);(1,1,1,1,1);(2,3);(2,1,2);(2,1,1,1)… }
代码:
public class CaifengNumUtils {
static Set<int[]> caifeng = new HashSet<int[]>();
public static Set<int[]> getCaifeng(int fenShu,int yq) {
caifeng = new HashSet<int[]>();
int[] data = new int[fenShu];
splitInteger(fenShu,fenShu,data,0,yq);
return caifeng;
}
public static int splitInteger(int sum, int max, int[] data, int index, int yq) {
if (max > sum) max = sum;
if (sum < 1 || max < 1) return 0;
if (sum == 1 || max == 1) {
if (sum == 1) {
data[index] = sum;
print(data, index+1, yq);
} else {
for (int i = 0; i < sum; i++) {
data[index++] = max;
}
print(data, index, yq);
}
return 1;
}
if (sum == max) {
data[index] = max;
print(data, index+1, yq);
return 1 + splitInteger(sum, max-1, data, index, yq);
} else if (sum > max) {
data[index] = max;
//一定注意这里的先后顺序
return splitInteger(sum-max, max, data, index+1, yq) + splitInteger(sum, max-1, data, index, yq);
} else {
//sum < max
return splitInteger(sum, sum, data, index, yq);
}
}
//打印数组
public static void print(int[] data, int index, int yq) {
ZuheNumUtils t=new ZuheNumUtils();
if(index==yq) {
int [] result=new int[yq];
for (int i = 0; i <= index -1; i++) {
result[i]=data[i];
}
caifeng.add(result);
}
}
public static int count(int sum, int max) {
if (sum < 1 || max < 1) return 0;
else if (sum == 1 || max == 1){
return 1;
} else if (sum < max) {
return count(sum,sum);
} else if (sum == max) {
return 1+count(sum, sum-1);
} else {
return count(sum, max-1)+count(sum-max,max);
}
}
}
(2)排列组合效果{1,2,3}->{ (1,2,3);(1,3,2);(2,1,3);(2,3,1);(3,1,2);(3,2,1) }
代码:
public class paileiNumUtils {
static Set<ShopBean []> conpanyId = new HashSet<ShopBean []>();
static Set<String> conpany = new HashSet<String>();
private static long factorial(int n) {
long sum = 1;
while( n > 0 ) {
sum = sum * n--;
}
return sum;
}
public static long arrangement(int m, int n) {
return m <= n ? factorial(n) / factorial(n - m) : 0;
}
public static long combination(int m, int n) {
return m <= n ? factorial(n) / (factorial(m) * factorial((n - m))) : 0;
}
public static void combinationSelect(ShopBean[] dataList, int n) {
System.out.println(String.format("C(%d, %d) = %d", dataList.length, n, combination(n, dataList.length)));
combinationSelect(dataList, 0, new ShopBean[n], 0);
}
ate static void combinationSelect(ShopBean[] dataList, int dataIndex, ShopBean[] resultList, int resultIndex) {
int resultLen = resultList.length;
int resultCount = resultIndex + 1;
if (resultCount > resultLen) {
// 全部选择完时,输出组合结果
ShopBean [] q=new ShopBean [resultList.length];
String s = "";
for(int i=0;i<resultList.length;i++) {
q[i]=resultList[i];
s= s+resultList[i].getId()+",";
}
conpany.add(s);
conpanyId.add(q);
return;
}
// 递归选择下一个
for (int i = dataIndex; i < dataList.length + resultCount - resultLen; i++) {
resultList[resultIndex] = dataList[i];
combinationSelect(dataList, i + 1, resultList, resultIndex + 1);
}
}
public Set<ShopBean[]> px(List<ShopBean> tlist,int yq) {
ShopBean[] array = new ShopBean[tlist.size()];
tlist.toArray(array);
conpanyId = new HashSet<ShopBean []>();
combinationSelect(array, yq);
return conpanyId;
}
}
(3)筛掉不符合的配比配方,目标配方纯储存在testbean中,厂商配方shopbean中。
public void main(List<ShopBean> slist,testbean pp, int fenShu) {
for(int yq=1;yq<=slist.size();yq++) {
Set<int[]> caifeng=t1.getCaifeng(fenShu, yq);
Set<ShopBean[]> conpanyId=new HashSet<ShopBean []>();
conpanyId=t.px(slist, yq);
for(ShopBean [] k:conpanyId) {
for(int[] i:caifeng) {
Set<String> zuhe=new HashSet<String>();
zuhe=t2.zuhe(i, yq);
testbean result = new testbean();
for(String str:zuhe) {
String[] getArr = str.split(",");
int[] array = Arrays.asList(getArr).stream().mapToInt(Integer::parseInt).toArray();
List <testbean> peibiList=new ArrayList<>();
for(int o=0;o<array.length&&array.length==k.length;o++){
// System.out.print("id="+k[o].getId()+" X "+array[o]+" : ");
// 7种原材料配比数
testbean peibit=t3.PeiBi(k[o],array[o],fenShu);
peibiList.add(peibit);
}
result=t3.resultpeibiList(peibiList);
t3.resultduibi(pp,result);
}
}
}
}
}
二、页面优化
界面是jsp写的,为了美化,我使用了一些标签,如:<c:if>、${fn:}、fmt。
(1)使用这些标签时,首先要在jsp文件引用。<c:if>用 :
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
${fn:}用:
<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn"%>
fmt用:
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
(2)<c:if> <c:forEach>我常用的方法:
<c:forEach items="${pflist}" var="S">
<tr>
<td>${
S.id }</td>
</c:forEach>
pflist在java中放入request.setAttribute(“pflist”,pflist);
<c:forEach items="${sessionScope.pflist}" var="S">
<tr>
<td>${
S.id }</td>
</c:forEach>
pflist在java中放入request.getSession.setAttribute(“pflist”,pflist);
(3)${fn:}可以在界面实现一些逻辑操作
如:
<c:forEach items="${sessionScope.tList}" var="S">
<tr>
<tr>
<td>${S.id }</td>
<c:if test="${fn:length(sessionScope.tList ) == 1}"><td style="width: 60px;border:1px solid;">全部</td></c:if>
<c:if test="${fn:length(sessionScope.tList ) != 1}"><td style="width: 60px;border:1px solid;">${S.peibi }</td></c:if>
</tr>
</tr>
</c:forEach>
${fn:length(Str) }可以获得字符串的长度,还有其他的一些方法。
(4)fmt主要对显示的数据进行处理,用法:
<fmt:formatNumber type="number" value="${S.na }" pattern="0.00"/>
这里使数据显示两位小数
(5)jsp页面常用的js方法
1.弹出消息对话框
<%
if ((String) request.getAttribute("info") == "success") {
%>
<script>
alert("操作成功!");
</script>
<%
request.setAttribute("info", "clear");
} else if ((String) request.getAttribute("info") == "false") {
%>
<script>
alert("操作失败!请检查收藏名是否重复。");
</script>
<%
request.setAttribute("info", "clear");
}
%>
2.弹出输入对话框
<script language=JavaScript>
function pbdName(){
var pbdname = prompt('请为配比单输入名字(最多五个字符)','');
if (pbdname.length>0 && pbdname.length<=5) window.location.href='${pageContext.request.contextPath}/Demo/keeppeibidianaction?&pbdname='+pbdname;
else alert("请为配比单输入名字")
}
</script>
3.js暂停页面刷新
event.preventDefault()
4.获取网页控件的value值
let companyName = document.getElementsByName("companyName")[0].value
总结:
1.jsp在动态交互上实在是不中,局部刷新还是要靠ajax技术。没有vue的舒服。写前端时尽量使用新技术,方便快捷。
2.编写jsp页面前,先建一个html。查看效果,然后在放入jsp页面中。
3.jap可以编写Java,但有点鸡肋,用<% %>形式。
4.页面没效果了话,重启服务器或者清除一下浏览器缓存。
发展:
1.改用新的技术,比如vue。
三、mybatis注解开发
之前通过编写xml进行开发,感觉还是有点麻烦,毕竟这个老项目差不多是一个表一个对象,就改变了下思路,使用注解开发的方式试试。
(1)在bean目录下新建个对象
(2)在dao层目录编写对象的接口
(3)在接口上使用注释并编写语句
public interface IPbdBeanDao {
@Insert("insert into pbdbean(id,na,ga,v,fe,s,shihui,huifafeng,conpanyid,conpanyname,peibi,money,flag,pbdname)values(#{id},#{Na},#{Ga},#{V},#{Fe},#{S},#{shihui},#{huifafeng},#{conpanyid},#{conpanyname},#{peibi},#{money},#{flag},#{pbdName})")
boolean savePbdBean(pbdBean pbdBean);
@Select("select * from pbdbean where flag = 'result'")
List<pbdBean> findAllPbd_resulta();
@Select("select * from pbdbean where flag = 'yq' and pbdname = #{pbdName}")
pbdBean findPbd_yqByPbdName(String pbdName);
@Select("select * from pbdbean where flag = 'tlist' and pbdname = #{pbdName}")
List<pbdBean> findPbd_tlistByPbdName(String pbdName);
@Select("select * from pbdbean where flag = 'result' and pbdname = #{pbdName}")
pbdBean findPbd_resultByPbdName(String pbdName);
@Delete("delete from pbdbean where pbdname = #{pbdName}")
boolean deletePbdByPbdName(String pbdName);
}
(4)在Action中创建代理对象调用方法即可
public List<pbdBean> findAllPbd_resulta() {
// 获取session
sqlSession = new SessionFactoryUtils().initFactory();
// 代理对象
iPbdBeanDao = sqlSession.getMapper(IPbdBeanDao.class);
// 逻辑处理
List<pbdBean> pbdBeanList = iPbdBeanDao.findAllPbd_resulta();
// 关闭session
new SessionFactoryUtils().destroyFactory(sqlSession);
// 逻辑处理
return pbdBeanList;
}
项目链接:
https://github.com/Dream9898123/comput