说明对JDBC进行简单的封装,方便使用完整代码:https://pan.bigdataboy.cn/#/s/nMC0数据库数据创表DROPTABLEIFEXISTSuser;CREATETABLEuser(idBIGINT(20)NOTNULLauto_incrementCOMMENT'主键ID',nameVARCHAR(30)NULLDEFAULTNULLCOMMENT'姓名',ageINT(11)NULLDEFAULTNULLCOMMENT'年龄',emailVARCHAR(50)NULLDEFAULTNULLCOMMENT'邮箱',PRIMARYKEY(id));加入数据INSERTINTOuser(id,name,age,email)VALUES(1,'Jone',18,'test1@bigdataboy.com'),(2,'Jack',20,'test2@bigdataboy.com'),(3,'Tom',28,'test3@bigdataboy.com'),(4,'Sandy',21,'test4@bigdataboy.com'),(5,'Billie',24,'test5@bigdataboy.com');构建目录工具类连接工具类,封装连接对象,方便获取连接packagecn.bigdataboy.util;importjava.sql.PreparedStatement;importjava.sql.Connection;importjava.sql.DriverManager;importjava.sql.ResultSet;importjava.sql.SQLException;publicclassDBConnectionUtil{//创建连接参数privatestaticStringdriver="com.mysql.jdbc.Driver";privatestaticStringurl="jdbc:mysql://localhost:3306/jdbctest?characterEncoding=utf8";privatestaticStringusername="";privatestaticStringpassword="";//获取连接对象publicstaticConnectiongetConnection(){Connectionconn=null;//获取连接try{//加载驱动Class.forName(driver);conn=DriverManager.getConnection(url,username,password);}catch(SQLExceptionthrowables){throwables.printStackTrace();}catch(ClassNotFoundExceptione){e.printStackTrace();}returnconn;}//关闭全部publicstaticvoidcloseAll(ResultSetrs,PreparedStatementps,Connectionconn){if(rs!=null){try{rs.close();}catch(SQLExceptionthrowables){throwables.printStackTrace();}};if(ps!=null){try{ps.close();}catch(SQLExceptionthrowables){throwables.printStackTrace();}};if(conn!=null){try{conn.close();}catch(SQLExceptionthrowables){throwables.printStackTrace();}}}}测试连接工具类publicstaticvoidmain(String[]args){Connectionconnection=getConnection();System.out.println(connection);}用户实体类用户实体类的字段需要与数据表字段对应packagecn.bigdataboy.entity;publicclassUser{privateintid;privateStringname;privateintage;privateStringemail;publicintgetId(){returnid;}publicvoidsetId(intid){this.id=id;}publicStringgetName(){returnname;}publicvoidsetName(Stringname){this.name=name;}publicintgetAge(){returnage;}publicvoidsetAge(intage){this.age=age;}publicStringgetEmail(){returnemail;}publicvoidsetEmail(Stringemail){this.email=email;}}定义dao层接口dao层主要功能是提供对数据库数据的操作类packagecn.bigdataboy.dao;importcn.bigdataboy.entity.User;publicinterfaceUserDao{//通过id查询用户UsergetUserById(intid);}实现UserDao接口packagecn.bigdataboy.dao.impl;importcn.bigdataboy.dao.UserDao;importcn.bigdataboy.entity.User;importcn.bigdataboy.util.DBConnectionUtil;importjava.sql.Connection;importjava.sql.PreparedStatement;importjava.sql.ResultSet;importjava.sql.SQLException;publicclassUserDaoImplimplementsUserDao{//通过id查询用户publicUsergetUserById(intid){Useruser=null;Connectionconn=null;PreparedStatementps=null;ResultSetrs=null;try{//通过连接工具类获取连接对象conn=DBConnectionUtil.getConnection();Stringsql="select*fromuserwhereid=?";ps=conn.prepareStatement(sql);ps.setInt(1,id);//设置第一个问号的值rs=ps.executeQuery();//执行SQL语句//判断是否返回到值,多个值需要循环使用next()获取if(rs.next()){//设置user值user=newUser();user.setId(rs.getInt("id"));user.setName(rs.getString("name"));user.setAge(rs.getInt("age"));user.setEmail(rs.getString("email"));}}catch(SQLExceptionthrowables){throwables.printStackTrace();}finally{//关闭全部DBConnectionUtil.closeAll(rs,ps,conn);}returnuser;}}测试实现的getUserById()方法packagecn.bigdataboy.dao;importcn.bigdataboy.dao.impl.UserDaoImpl;importcn.bigdataboy.entity.User;importorg.junit.Test;publicclassTestUserDaoImpl{@TestpublicvoidTestGetUserById(){intid=1;UserDaoImpluserDao=newUserDaoImpl();Useruser=userDao.getUserById(id);System.out.println(user.getId());System.out.println(user.getName());System.out.println(user.getAge());System.out.println(user.getEmail());System.out.println(user.getClass());}}其他的修改、添加、删除数据都是一样的,完整代码里有
说明Axios是一个基于promise的HTTP库,可以用在浏览器和node.js中。相关请求引入:https://cdn.jsdelivr.net/npm/axios/dist/axios.min.jsGET请求精简(只有url,没有参数)axios.get(url).then(response=>{//请求成功console.log(response.data);}).catch(error=>{//请求失败,console.log(error);});完整参数axios.get(url,{//设置请求头信息,可以传递空值headers:{K:V,},//传递参数params:{K:V,},}).then(response=>{//请求成功console.log(response.data);}).catch(error=>{//请求失败,console.log(error);});POST请求qs库地址:https://cdn.bootcdn.net/ajax/libs/qs/3.0.0/qs.jsqs.stringify():将对象或者数组序列化成URL的格式qs.parse():将qs.stringify()序列化的对象或者数组转回去letdata={K:V}axios.post("api",qs.stringify(data),{headers:{'token':token}}).then(response=>{//请求成功letres=response.data;console.log(res);}).catch(error=>{//请求失败,console.log(error);});其他请求待更新
案例介绍CSS有点丑,但是功能完整,将就看一下完整代码:https://pan.bigdataboy.cn/#/s/Oeia点击回车键添加内容清空所有内容总条数显示内容删除清空内容,隐藏底部条数与清空按钮功能说明内容添加v-model绑定表单内容用于数据绑定,@keyup.enter绑定回车键事件,添加内容<inputtype="text"v-model="inputValue"@keyup.enter="add"/>内容显示及删除v-for循环数组,显示内容。@click绑定点击事件,删除内容<ul><liv-for="(item,index)inlist"><span>{{index+1}}</span><span>{{item}}</span><buttonclass="remove"@click="remove(index)">X</button></li></ul>显示总条数及清空v-show判断是否显示,{{list.length}}显示总条数,@click绑定点击事件,用于清空数组<divv-show="list.length!=0"><span>{{list.length}}items</span><buttonclass="clear"@click="clear">Clear</button></div>Vue代码varvue=newVue({el:"#app",data:{//内容数组list:["吃饭饭","睡觉觉","打豆豆"],//输入的内容inputValue:"",},methods:{//添加add:function(){this.list.push(this.inputValue)},//移除remove:function(index){this.list.splice(index,1)},//清空clear:function(){this.list=[]}}})
说明上下条数切换第一条时,上一条按钮禁止点击最后一条时,下一条按钮禁止点击<scriptsrc="js/vue.js"type="text/javascript"charset="utf-8"></script><body><divid="app"><!--当第一条时,按钮禁止--><buttontype="button"v-bind:disabled="index==0?true:false"@click="prev">上一条</button><br/><spanv-text="arr[index]"></span><br/><!--最后一条时,按钮禁止--><buttontype="button"v-bind:disabled="index==arr.length-1?true:false"@click="next">下一条</button></div></body><script>varvue=newVue({el:"#app",data:{arr:["你要努力的去生活,因为你只有努力了,才知道自己真的不行。","好看的皮囊三千一晚,有趣的灵魂要车要房。","别人的钱财,乃我的身外之物。","别人的身体里都是才华,你的身体里都是珍珠奶茶。",],index:0},methods:{prev:function(){this.index-=1},next:function(){this.index+=1}}})</script>
v-text设置标签的文本属性v-text会覆盖原本标签的值标签想要部分设置文本可以使用{{}}方式v-text、{{}}支持逻辑表达式<scriptsrc="js/vue.js"type="text/javascript"charset="utf-8"></script><body><divid="app"><h2>信息:{{message}}</h2><h2>信息:{{message+"!"}}</h2><h2v-text="name">姓名</h2><h2v-text="name+'!'">姓名</h2></div></body><script>varvue=newVue({el:"#app",data:{message:"大数据男孩",name:"Bigdataboy",}})</script>v-html设置元素的innerHTML,data对象里的HTML结构会解析成标签,v-text只会解析成文本<scriptsrc="js/vue.js"type="text/javascript"charset="utf-8"></script><body><divid="app"><pv-html="content"></p></div></body><script>varvue=newVue({el:"#app",data:{content:"<h2>大数据男孩</h2>"}})</script>v-on为元素绑定事件完整格式:v-on:事件="方法名"缩写:@事件="方法名"绑定的方法定义在methods属性里面相关事件:click点击、dblclick双击、mouseenter鼠标移动…<body><divid="app"><inputtype="button"value="v-on指令"v-on:click="fun"><inputtype="button"value="v-on缩写"@click="fun"><pv-text="message"@click="changeMessage"></p></div></body><script>varvue=newVue({el:"#app",data:{message:"大数据男孩",},methods:{fun:function(){alert("事件绑定")},changeMessage:function(){this.message+="真帅"},},})</script>v-on补充传参事件绑定方法写成函数调用形式,可以传入自定义参数<scriptsrc="js/vue.js"type="text/javascript"charset="utf-8"></script><body><divid="app"><inputtype="button"value="按钮"@click="doBtn('老铁','666666')"/></div></body><script>varvue=newVue({el:"#app",methods:{doBtn:function(p1,p2){console.log(p1,p2)}}})</script>修饰符事件的后面跟上.修饰符可以对事件进行限制更多访问:https://cn.vuejs.org/v2/api/#v-on<scriptsrc="js/vue.js"type="text/javascript"charset="utf-8"></script><body><divid="app"><inputtype="text"@keyup.enter="doEnter('回车被点击')"/></div></body><script>varvue=newVue({el:"#app",methods:{doEnter:function(p){console.log(p)}}})</script>v-show用于显示&隐藏标签支持条件表达式本质是控制display:none;<scriptsrc="js/vue.js"type="text/javascript"charset="utf-8"></script><body><divid="app"><!--布尔值--><imgv-show="true"src="./img/1.jpg"style="width:10%;height:10%;"/><!--变量控制--><imgv-show="isShow"src="./img/1.jpg"style="width:10%;height:10%;"/><!--条件表达式--><imgv-show="age>18"src="./img/1.jpg"style="width:10%;height:10%;"/></div></body><script>varvue=newVue({el:"#app",data:{isShow:true,age:17},})</script>v-if用于显示&隐藏标签支持条件表达式本质是判定为false时把标签移除v-if相对于v-show,更消耗性能,因为v-if需要操作DOM树<body><divid="app"><inputtype="button"@click="toggleIsShow"value="切换v-if"/><p></p><!--变量控制--><imgv-if="isShow"src="./img/1.jpg"style="width:10%;height:10%;"/><!--条件表达式--><imgv-if="age>18"src="./img/1.jpg"style="width:10%;height:10%;"/></div></body><script>varvue=newVue({el:"#app",data:{isShow:true,age:17},methods:{toggleIsShow:function(){this.isShow=!this.isShow}}})</script>v-bind为元素绑定属性完整写法:v-bind:属性缩写::属性如果设置的class属性,建议使用对象方式判断是否添加类名<scriptsrc="js/vue.js"type="text/javascript"charset="utf-8"></script><body><divid="app"><!--绑定src属性(完整写法)--><imgv-bind:src="isSrc"style="width:10%;height:10%;"/><br/><!--绑定src属性(缩写写法)--><img:src="isSrc"style="width:10%;height:10%;"/><br/><!--绑定类名(建议对象写法)--><img:src="isSrc":class="{img:isShow,active:isActive}"style="width:10%;height:10%;"/><!--绑定类名(数组写法)--><img:src="isSrc":class="[show,active]"style="width:10%;height:10%;"/></div></body><script>varvue=newVue({el:"#app",data:{isSrc:"./img/1.jpg",isShow:true,isActive:true,show:"show",active:"active",}})</script>v-for根据数组生成列表结构v-for经常与数组搭配使用语法:(item,index)in数组改变数组的内容会同步更新到页面上,是响应式的<scriptsrc="js/vue.js"type="text/javascript"charset="utf-8"></script><body><divid="app"><h2>大数据男孩</h2><ul><liv-for="(item,index)inarr">{{index+1}}{{item}}</li></ul><h2>兴趣</h2><h3v-for="iininterest"v-bind:title="i.name">{{i.name}}</h3></div></body><script>varvue=newVue({el:"#app",data:{arr:["帅气","没钱","可爱","有趣","想了解吗?"],interest:[{"name":"摄影"},{"name":"网络"},{"name":"哲学"},]}})</script>v-model便捷设置和获取表单元素的值绑定的数据会和表单元素的值相关联绑定的数据<—->表单元素的值<scriptsrc="js/vue.js"type="text/javascript"charset="utf-8"></script><body><divid="app"><inputtype="text"v-model="message"/><h2v-text="message"></h2></div></body><script>varvue=newVue({el:"#app",data:{message:"",}})</script>
概述官网:https://cn.vuejs.org/第一个Vue程序引入Js<!--开发环境版本,包含了有帮助的命令行警告--><scriptsrc="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>渲染数据数据渲染不支持单标签、html、body标签<divid="app">{{message}}<p>{{date}}</p></div>Vue数据渲染支持同步刷新渲染数据data对象,支持选择的标签及后代标签<script>varvue=newVue({el:"#app",//挂载点选择器都支持(建议使用ID选择器)data:{message:"HelloBigdataboy",date:"2020.9.275.20"}})</script>data对象渲染复杂类型数据<body><divid="app">{{message}}<h2>{{infor.name}}</h2><ul><li>{{advantage[0]}}</li><li>{{advantage[1]}}</li><li>{{advantage[2]}}</li></ul></div></body><script>varvue=newVue({el:"#app",data:{message:"HelloBigdataboy",//普通类型infor:{//Json对象name:"bigdataboy",age:"18"},advantage:["帅气","幽默","有内涵"]//数组}})</script>
指针数组就是一个数组,其中的元素是指针变量。#include<stdio.h>intmain(){inta=1;intb=2;intc=3;//指针数组放入指针变量int*iarr[3]={&a,&b,&c};//循环打印inti;for(i=0;i<3;i++){printf("%d\n",*iarr[i]);}return0;}数组指针数组指针是一个指针,它指向的是一个数组。#include<stdio.h>intmain(){//声明一个数组inttemp[5]={1,2,3,4,5};//指向数组指针int(*p)[5]=&temp;//遍历打印inti;for(i=0;i<5;i++){//打印内存地址printf("%p\n",*p+i);//访问数组地址值//打印地址的变量printf("%d\n",*(*p+i));//访问数组地址值获取地址值变量}return0;}
爬取难点HTML的canvas标签生成的图片,使用平常获取图片URL下载是行不通的。说明爬虫完整代码https://pan.bigdataboy.cn/#/s/wjHw网站csTimer-魔方竞速训练专用计时器爬取内容模仿公式公式对应的canvas图片工具选取Pythonselenium开始爬取爬取canvas的思路是执行canvas.toDataURL("image/png")方法获取图片的base64编码,再转码为bytes,然后保存在本地构造主类classMain:#图片保存路径IMG_PATH="./img/"#公式保存文件FILE="a.txt"#保存公式的个数COUNT=5000#保存速度SPEED=0.1#None:无限制。支持浮点数def__init__(self):#TODO打开网站defsave(self,i):#TODO保存公式及图片defrun(self):#TODO运行类构造类方法def__init__(self):options=ChromeOptions()options.add_experimental_option('excludeSwitches',['enable-automation'])#隐藏自动化测试#options.add_argument("--headless")#注释掉,就无需打开浏览器窗口#加载网站self.bro=webdriver.Chrome(executable_path="./chromedriver_win32/chromedriver.exe",options=options)self.bro.get(url="https://www.cstimer.net/")#检查网页是否加载完成WebDriverWait(self.bro,60).until(EC.presence_of_element_located((By.XPATH,'//div[@id="leftbar"]/div[@class="mybuttonc6"]/div/span[2]')))#判断图片框是否显示ifnotself.bro.find_element_by_id('toolsDiv').is_displayed():#点击显示图片self.bro.find_element_by_xpath('//div[@id="leftbar"]/div[@class="mybuttonc6"]/div/span[2]').click()保存类方法defsave(self,i):#保存公式formula=self.bro.find_element_by_xpath('//div[@id="scrambleTxt"]/div').textwithopen(self.FILE,mode='a+',encoding="UTF-8")asf:text=f"{formula}----{i}\n"logger.info(text)f.write(text)#保存图片JS='returndocument.getElementById("toolsDiv").childNodes[0].childNodes[0].childNodes[0].toDataURL("image/png");'img_base64=self.bro.execute_script(JS).split(',')[1]#执行js文件得到带图片的base64编码img_bytes=base64.b64decode(img_base64)#转为bytes类型path=f"{self.IMG_PATH}{i}.png"logger.info(path)withopen(path,'wb')asf:#保存图片到本地f.write(img_bytes)运行类方法defrun(self):i=1whileself.COUNT>=i:self.bro.find_element_by_xpath('//div[@class="title"]/nobr[2]/span[2]').click()self.save(i)ifself.SPEED:sleep(self.SPEED)logger.info(f"延迟:{str(self.SPEED)}中....")i+=1logger.info(f"爬取完成")使用if__name__=='__main__':mian=Main()mian.run()
引入内存如何存放变量内存中不存放变量,存放的是一堆十六位进制的地址值,编译器就会把这些地址值与相应变量对应起来。指针通常所说的指针,就是地址的意思,C语言中有专门存放指针的变量类型—指针变量.跟普通变量不同,指针变量存放的是地址值,所以一个地址是占4个字节的空间指针变量的类型是所存变量的类型定义指针变量定义指针变量跟普通变量十分相似,只是中间多了一个星号(*)//不推荐定义未初始化的指针变量,不然可能产生意想不到的Bug。(未定义就会随机分配地址,这很危险)//使用指针变量一定要初始化char*pc;int*pi;取地址运算符和取值运算符如需要获取某个变量的地址,就需要使用取地址运算(&)这里(*)表示定义指针变量charc='A';//取地址值赋值给指针变量char*pc=&c;如果需要访问指针变量指向的数据,可以使用取值运算符(*)这里(*)表示获取指针变量指向的值。//打印出的原本的值printf("i=%d\n",*pi);//%p打印指针变量的地址值printf("*pi=%p\n",*pi);代码#include<stdio.h>intmain(){//定义变量charc='A';inti=123;//获取地址赋值给指针变量char*pc=&c;int*pi=&i;//打印原本变量printf("c=%c\n",*pc);printf("i=%d\n",*pi);//打印地址值printf("*pc=%p\n",&pc);printf("*pi=%p\n",&pi);return0;}
定义//定义长度为10的数组arr,其中的元素的类型只能是int//对数组不赋值,里面会是随机的数据(栈结构)intarr[10];取值//取出索引0位置的元素arr[0];赋值//索引为5的位置,赋值101010arr[5]=101010;数组初始化//将数组中的所有值初始化为0intarr[5]={0};//数组元素赋予不同的值intarr[5]={0,1,2,3,4};//只给一部分元素赋值,其余会默认为0intarr[5]={0,1,2};//C99特性,对指定索引赋值,其余未被指定的默认0intarr[5]={[0]=0,[2]=5};//直接指定元素,可以不定义数组的长度intarr[]={0,1,2,3};二维数组数组内嵌套数组二维数组定义intarr[3][5];//不进行初始化,数组内就是随机的值intarr[][5];//第一个可以不定义(编译期会自动推算),第二个必须写二维数组取值//取出索引0位置下的索引为0的元素arr[0][0];二维数组赋值//给索引2下的索引3赋值为55arr[2][3]=55;二维数组初始化//全部赋值arr[2][3]={1,2,3,4,5,6};//不推荐这样写arr[2][3]={{1,2,3},{4,5,6}};//推荐写法//部分赋值arr[2][3]={{1,2},{4,5}};//没有赋值的位置默认为0//指定位置赋值arr[2][3]={{[0][0]=1,[0][1]=2},{4,5,6}};
if判断语句单条件判断inti=10;if(i<18){printf("你还小呢!!!\n");}else{printf("还行满18岁了\n");};多条件判断inti=10;if(i<18){printf("你还小呢!!!\n");}elseif(i==18){printf("才刚刚18岁\n");}else{printf("嗯已经大于18岁了\n");};if嵌套inti=10;if(i<18){printf("你还小呢!!!\n");}elseif(i>=18){//嵌套ifif(i==18){printf("刚刚18岁\n");}else{printf("不错已经成年了\n");};};swich匹配语句break;表示跳出该语句+,不然会继续执行后面的匹配块的语句。charsing='A';switch(sign){//语句块case'A':{printf("%c级不错\n",sign);};break;//单行语句case'B':printf("%c级还行\n",sign);break;//没有匹配到的默认语句default:printf("没有这个评级\n");break;};while语句统计用户输入字符的个数#include<stdio.h>intmain(){printf("输入一串字符:");//第一次调用getchar()会等待用户输入内容,存入缓冲区getchar();intcount=1;/*再次调用,这不会等待用户输入内容而是从缓冲区读取内容,一次读取一个字符*/while(getchar()!='\n'){count=count+1;};printf("你输入了%d个字符\n",count);//当缓冲区读取完成时,再一次调用,又会等待用户输入getchar();return0;}dowhile语句先执行,再判断do{循环体;}while(判断语句);for循环intcount;for(count=0;count<0;count++){printf("循环体")}//c99标准可以在表达式定义变量//gcc-std=c99for(intcount=0;count<0;count++){printf("循环体")}灵活的for循环for循环的表达式可以按照需要进行省略,但是分号不能省略for(表达式1;表达式2;表达式3){}for(;表达式2;表达式3){}for(表达式1;;表达式3){}for(表达式1;表达式2;){}for(;;){}//这个相当于死循环break结束循环,相当于跳到循环尾continue跳过本次循环