使用struts2框架来实现CRUD(create、read、update、delete)
![](http://img1.ph.126.net/hcwcAl4euJcs1bKbV60C5w==/6630477327954683449.gif)
<?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN" "http://struts.apache.org/dtds/struts-2.3.dtd"> <struts> <constant name="struts.enable.DynamicMethodInvocation" value="false" /> <constant name="struts.devMode" value="true" /> <constant name="struts.locale" value="en_US"/> <package name="crud1" namespace="/" extends="struts-default"> <interceptors> <!-- 自定义拦截器 --> <interceptor name="mylogger" class="com.huai.interceptor.LoggerInterceptor"/> <!--自定义一个拦截器栈 --> <interceptor-stack name="myStack"> <interceptor-ref name="mylogger"/> <interceptor-ref name="defaultStack"/> </interceptor-stack> </interceptors> <!--设置默认的自定义拦截器,不再是系统的defaultStack --> <default-interceptor-ref name="myStack"></default-interceptor-ref> <action name="userToList" class="com.huai.action.UserAction" method="toList"> <result name="toList">/list.jsp</result> </action> <action name="userToAdd" class="com.huai.action.UserAction" method="toAdd"> <result name="toAdd">/add.jsp</result> </action> <action name="userAdd" class="com.huai.action.UserAction" method="add"> <result name="toList">/list.jsp</result> <result name="toAdd">/add.jsp</result> <result name="input">/add.jsp</result> </action> <action name="userToUpdate" class="com.huai.action.UserAction" method="toUpdate"> <result name="toUpdate">/update.jsp</result> </action> <action name="userUpdate" class="com.huai.action.UserAction" method="update"> <result name="toList">/list.jsp</result> </action> <action name="userDelete" class="com.huai.action.UserAction" method="delete"> <result name="toList">/list.jsp</result> </action> <action name="userToQuery" class="com.huai.action.UserAction" method="toQuery"> <result name="toQuery">/query.jsp</result> </action> <action name="userQuery" class="com.huai.action.UserAction" method="query"> <result name="toList">/list.jsp</result> <result name="input">/query.jsp</result> </action> </package> </struts>
UserAction
package com.huai.action; import java.util.List; import com.db.dao.DAOImpl;import com.opensymphony.xwork2.ActionSupport;import com.ov.UserModel;import com.ov.UserQueryModel; public class UserAction extends ActionSupport{ /** * */ private static final long serialVersionUID = 1L; private List<UserModel> list; private String[] sexs = new String[]{"男","女"}; private UserModel user; private UserQueryModel uqm; private String info; public List<UserModel> getList() { return list; } public void setList(List<UserModel> list) { this.list = list; } public String[] getSexs(){ return this.sexs; } public void setSexs(String[] sexs){ this.sexs = sexs; } public UserModel getUser(){ return this.user; } public void setUser(UserModel user){ this.user = user; } public UserQueryModel getUqm() { return uqm; } public void setUqm(UserQueryModel uqm) { this.uqm = uqm; } public String getInfo(){ return this.info; } public void setInfo(String info){ this.info = info; } public String toList()throws Exception{ DAOImpl dao = new DAOImpl(); list = dao.getAll(); return "toList"; } public String toAdd()throws Exception{ return "toAdd"; } public String add()throws Exception{ DAOImpl dao = new DAOImpl(); UserModel user_temp = null; //先判断增加的用户的id是否已经存在 //先用添加的userId号遍历数据库,返回一个user对象 user_temp=dao.getSingle(user.getUserId()); if(user_temp == null){ dao.create(user); return this.toList(); }else{ this.info = "The userId has existed !"; return "toAdd"; } } public String toUpdate()throws Exception{ DAOImpl dao = new DAOImpl(); user = dao.getSingle(user.getUserId()); return "toUpdate"; } public String update()throws Exception{ DAOImpl dao = new DAOImpl(); dao.update(user); return toList(); } public String delete()throws Exception{ DAOImpl dao = new DAOImpl(); dao.delete(user.getUserId()); return this.toList(); } public String toQuery()throws Exception{ return "toQuery"; } public String query()throws Exception{ DAOImpl dao = new DAOImpl(); list = dao.getByCondition(uqm); return "toList"; } }
DataSourceHolder
package com.db_source; import java.beans.PropertyVetoException; import com.mchange.v2.c3p0.ComboPooledDataSource; public class DataSourceHolder { private ComboPooledDataSource cpds = null; public DataSourceHolder() throws PropertyVetoException{ //这里使用了c3p0的数据源获取数据库的connection //没有c3p0-config.xml文件,这里用快捷配置方式 cpds = new ComboPooledDataSource(); cpds.setDriverClass( "com.mysql.jdbc.Driver" ); cpds.setJdbcUrl( "jdbc:mysql://localhost:3306/test" ); cpds.setUser("root"); cpds.setPassword("mysql"); } public ComboPooledDataSource getDataSource(){ return this.cpds; } }
DAOImpl
package com.db.dao; import java.beans.PropertyVetoException;import java.sql.Connection;import java.sql.SQLException; import com.db_source.DataSourceHolder;import com.mchange.v2.c3p0.ComboPooledDataSource;import com.ov.UserModel;import com.ov.UserQueryModel; import java.sql.*;import java.util.ArrayList;import java.util.List; public class DAOImpl { private ComboPooledDataSource dataSourceHolder = null; public DAOImpl(){ try { dataSourceHolder = new DataSourceHolder().getDataSource(); } catch (PropertyVetoException e) { e.printStackTrace(); } } //create a user public void create(UserModel user){ Connection conn = null; try { conn = dataSourceHolder.getConnection(); final String sql = "insert into tb1_user(userId, name, sex, age) values(?,?,?,?)"; java.sql.PreparedStatement ps = conn.prepareStatement(sql); int count = 1; ps.setInt(count++, user.getUserId()); ps.setString(count++, user.getName()); ps.setString(count++, user.getSex()); ps.setInt(count++, user.getAge()); ps.execute(); ps.close(); } catch (SQLException e) { e.printStackTrace(); }finally{ try { conn.close(); } catch (SQLException e) { e.printStackTrace(); } } } //modify user's information public void update(UserModel user){ Connection conn = null; try { conn = dataSourceHolder.getConnection(); final String sql = "update tb1_user set name=?, sex=?, age=? where userId=?"; java.sql.PreparedStatement ps = conn.prepareStatement(sql); int count = 1; ps.setString(count++, user.getName()); ps.setString(count++, user.getSex()); ps.setInt(count++, user.getAge()); ps.setInt(count++, user.getUserId()); ps.execute(); ps.close(); } catch (Exception e) { e.printStackTrace(); }finally{ try{ conn.close(); }catch(Exception e){ e.printStackTrace(); } } } public void delete(int userId){ Connection conn = null; try { conn = dataSourceHolder.getConnection(); final String sql = "delete from tb1_user where userId=?"; java.sql.PreparedStatement ps = conn.prepareStatement(sql); ps.setInt(1, userId); ps.execute(); ps.close(); } catch (Exception e) { e.printStackTrace(); } finally{ try { conn.close(); } catch (SQLException e) { e.printStackTrace(); } } } //返回单个用户-user public UserModel getSingle(int userId){ UserModel user = null; Connection conn = null; try { conn = dataSourceHolder.getConnection(); final String sql = "select * from tb1_user where userId=?"; PreparedStatement ps = conn.prepareStatement(sql); ps.setInt(1, userId); ResultSet rs = ps.executeQuery(); if(rs.next()){ user = this.rs2Model(rs); } rs.close(); ps.close(); } catch (Exception e) { e.printStackTrace(); }finally{ try { conn.close(); } catch (SQLException e) { e.printStackTrace(); } } return user; } private UserModel rs2Model(ResultSet rs)throws Exception{ UserModel user = new UserModel(); user.setUserId(rs.getInt("userId")); user.setName(rs.getString("name")); user.setSex(rs.getString("sex")); user.setAge(rs.getInt("age")); return user; } //返回所有用户 public List<UserModel> getAll(){ List<UserModel> list = new ArrayList<UserModel>(); Connection conn = null; try{ conn = dataSourceHolder.getConnection(); // final String sql = "select * from tb1_user order by userId"; PreparedStatement ps = conn.prepareStatement(sql); ResultSet rs = ps.executeQuery(); while(rs.next()){ UserModel user = this.rs2Model(rs); list.add(user); } rs.close(); ps.close(); }catch(Exception e){ e.printStackTrace(); }finally{ try{ conn.close(); }catch(Exception e){ e.printStackTrace(); } } return list; } //下面几个用于选择性查询 //此方法生成查询命令的where private String generateWhere(UserQueryModel uqm){ StringBuffer buffer = new StringBuffer(); if(uqm.getUserId() > 0){ buffer.append(" and userId = ? "); } if(uqm.getName() != null && uqm.getName().trim().length() > 0){ buffer.append(" and name like ? "); } if(uqm.getSex() != null && uqm.getSex().trim().length() > 0){ buffer.append(" and sex = ? "); } if(uqm.getAge() > 0){ buffer.append(" and age >= ? "); } if(uqm.getAge2() > 0){ buffer.append(" and age <= ? "); } return buffer.toString(); } private void preparePs(UserQueryModel uqm, PreparedStatement ps) throws SQLException{ int count = 1; if(uqm.getUserId() > 0){ ps.setInt(count++, uqm.getUserId()); } if(uqm.getName() != null && uqm.getName().trim().length() > 0){ ps.setString(count++, "%"+uqm.getName()+"%"); } if(uqm.getSex() != null && uqm.getSex().trim().length() > 0){ ps.setString(count++, uqm.getSex()); } if(uqm.getAge() > 0){ ps.setInt(count++, uqm.getAge()); } if(uqm.getAge2() > 0){ ps.setInt(count++, uqm.getAge2()); } } public List<UserModel> getByCondition(UserQueryModel uqm){ List<UserModel>list = new ArrayList<UserModel>(); Connection conn = null; try { conn = dataSourceHolder.getConnection(); final String sql = "select * from tb1_user where 1=1 "+this.generateWhere(uqm)+" order by userId"; PreparedStatement ps = conn.prepareStatement(sql); this.preparePs(uqm, ps); ResultSet rs = ps.executeQuery(); while(rs.next()){ UserModel user = this.rs2Model(rs); list.add(user); } rs.close(); ps.close(); } catch (Exception e) { e.printStackTrace(); }finally{ try { conn.close(); } catch (SQLException e) { e.printStackTrace(); } } return list; } }
UserModel
package com.ov; public class UserModel { private int userId; private String name; private String sex; private int age; public UserModel(){} public UserModel(int userId, String name, String sex, int age){ this.userId = userId; this.name = name; this.sex = sex; this.age = age; } public int getUserId() { return userId; } public void setUserId(int userId) { this.userId = userId; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + age; result = prime * result + ((name == null) ? 0 : name.hashCode()); result = prime * result + ((sex == null) ? 0 : sex.hashCode()); result = prime * result + userId; return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; UserModel other = (UserModel) obj; if (age != other.age) return false; if (name == null) { if (other.name != null) return false; } else if (!name.equals(other.name)) return false; if (sex == null) { if (other.sex != null) return false; } else if (!sex.equals(other.sex)) return false; if (userId != other.userId) return false; return true; } }
UserQueryModel
package com.ov; public class UserQueryModel extends UserModel{ private int age2; public int getAge2() { return age2; } public void setAge2(int age2) { this.age2 = age2; } }
UserAction-en-US.properties
add.title = Create a Useradd.submit = Createupdate.title = Update a Userupdate.submit = Updatequery.title = Query Usersquery.submit = Queryquery.age1 = Min Agequery.age2 = Max Agequery.error = your min age is more than your max age.list.title = Users Infolist.operation = operationlist.add=Create a Userlist.query = Query Usersuser.userId = userIduser.name = nameuser.sex = sexuser.age = age
UserAction-zh-CN.properties
add.title = \u6DFB\u52A0\u7528\u6237add.submit = \u6DFB\u52A0update.title = \u4FEE\u6539\u7528\u6237update.submit = \u4FEE\u6539query.title = \u67E5\u8BE2\u7528\u6237query.submit = \u67E5\u8BE2query.age1 = \u5E74\u9F84\u6700\u5C0F\u503Cquery.age2 = \u5E74\u9F84\u6700\u5927\u503Cquery.error = \u60A8\u8F93\u5165\u7684\u5E74\u9F84\u6700\u5C0F\u503C\u5927\u4E8E\u6700\u5927\u503Clist.title = \u7528\u6237\u4FE1\u606Flist.operation = \u64CD\u4F5Clist.add=\u6DFB\u52A0\u7528\u6237list.query = \u67E5\u8BE2\u7528\u6237user.userId = \u7528\u6237\u7F16\u53F7user.name = \u59D3\u540Duser.sex = \u6027\u522Buser.age = \u5E74\u9F84
UserAction-userAdd-validation.xml(这是UserAction类中的userAdd方法中的xml验证文件)
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE validators PUBLIC "-//Apache Struts//XWork Validator 1.0.3//EN" "http://struts.apache.org/dtds/xwork-validator-1.0.3.dtd"> <validators> <field name="user.userId"> <field-validator type="int"> <param name="min">1</param> <message>请输入编号,整数类型</message> </field-validator> </field> <field name="user.name"> <field-validator type="requiredstring"> <param name="trim">true</param> <message>请填写姓名</message> </field-validator> </field> <field name="user.age"> <field-validator type="int"> <param name="min">18</param> <param name="max">50</param> <message>请输入的年龄在${min}到之间${max}</message> </field-validator> </field></validators>
UserAction-userQuery-validation.xml(这是UserAction类中的uerQuery方法中的验证xml文件)
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE validators PUBLIC "-//Apache Struts//XWork Validator 1.0.3//EN" "http://struts.apache.org/dtds/xwork-validator-1.0.3.dtd"> <validators> <validator type="expression"> <param name="expression"> <!-- ![CDATA[]的作用是是不用一些符号的转义--> <![CDATA[(uqm.age2 > 0 && uqm.age <= uqm.age2) || uqm.age2 == 0]]> </param> <message key="query.error"/> </validator></validators>
LoggerInterceptor
package com.huai.interceptor; import java.util.Map; import org.apache.struts2.dispatcher.*; import com.opensymphony.xwork2.*;import com.opensymphony.xwork2.Result;import com.opensymphony.xwork2.interceptor.Interceptor; public class LoggerInterceptor implements Interceptor{ /** * 这个类实现了拦截器Interceptor接口 * 目的是打印相关信息,便于程序调试 * 方法的执行时间是在action之前,而在result之后 * * * 注意:去掉此类不会影响到整个项目 */ private static final long serialVersionUID = 1L; @Override public void destroy() { } @Override public void init() { } @Override public String intercept(ActionInvocation invocation) throws Exception { System.out.println("--------------------------------"); //打印当前的action类名 System.out.println("Action: "+invocation.getAction().getClass().getName()); //打印action类中所调用的方法 System.out.println("Method: "+invocation.getProxy().getMethod()); //打印当前上下文context之中的所有request参数 //参数是以映射的关系存放的 Map<String, Object> params = invocation.getInvocationContext().getParameters(); for(String key : params.keySet()){ Object obj = params.get(key); //遍历打印映射中的数组 if(obj instanceof String[]){ String[] arr = (String[])obj; System.out.println("Param: "+key); for(String value : arr){ System.out.println(value); } } } /** * 此方法前面的代码在action之前执行 * 此方法后面的代码在result之后执行 * 注意:如果没有invoke()方法,将不会执行后面的invocation(拦截器) */ String resultCode = invocation.invoke(); Result rresult = invocation.getResult(); if(rresult instanceof ServletDispatcherResult){ ServletDispatcherResult result = (ServletDispatcherResult)rresult; //打印result所调转到的jsp页面名称 System.out.println("JSP: "+result.getLastFinalLocation()); } System.out.println("---------------------------------"); return resultCode; } }
list.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib prefix="s" uri="/struts-tags"%><!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>list_show_page</title> </head><body> <center> <h1>显示用户信息</h1> <h2> <s:a href="/strutsdemon_crud001/userToAdd.action">添加用户</s:a> </h2> <h2> <s:a href="/strutsdemon_crud001/userToQuery.action">查询用户</s:a> </h2> </center> <table align="center" border="1" cellpadding="1" cellspacing="0"> <tr> <td>编号</td> <td>姓名</td> <td>性别</td> <td>年龄</td> <td colspan="2" align="center">操作</td> </tr> <s:iterator value="list"> <tr> <td><s:property value="userId" /></td> <td><s:property value="name" /></td> <td><s:property value="sex" /></td> <td><s:property value="age" /></td> <td><a href="/strutsdemon_crud001/userToUpdate.action?user.userId=<s:property value='userId'/>"> 修改 </a></td> <!--这个是javascript的用法,作用是当用户按下删除键的时候提醒用户是否确定删除--> <td><a href="javascript:if(confirm('Are you sure ?')) window.location.href='/strutsdemon_crud001/userDelete.action?user.userId=<s:property value='userId'/>'"> 删除 </a> </td> </tr> </s:iterator> </table></body></html>
add.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib prefix="s" uri="/struts-tags"%><!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title><s:text name="add.title"/></title> </head><body><h1>add-page</h1><h4><s:property value="info"/></h4><s:form action="userAdd" method="post" namespace="/"> <%-- <s:textfield name="user.userId" label="编号"></s:textfield> <s:textfield name="user.name" label="姓名"></s:textfield> <s:select list="sexs" name="user.sex" label="性别"></s:select> <s:textfield name="user.age" label="年龄"></s:textfield> <s:submit value="添加"></s:submit> --%> <s:textfield name="user.userId" key="user.userId"/> <s:textfield name="user.name" key="user.name"/> <s:select name="user.sex" list="sexs" key="user.sex"/> <s:textfield name="user.age" key="user.age"/> <s:submit name="" key="add.submit"/></s:form></body></html>
query.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib prefix="s" uri="/struts-tags"%><!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>查询用户信息</title></head><body><center> <s:actionerror/> <h1><s:text name="query.title"/></h1> <s:form action="userQuery" method="post" namespace="/" > <!-- 这是非国际化标签的输入表 --> <%-- <s:textfield name="uqm.userId" label="编号" value="0"/> <s:textfield name="uqm.name" label="姓名"/> <s:select name="uqm.sex" list="sexs" label="性别" headerKey="" headerValue="请选择"/> <s:textfield name="uqm.age" label="年龄最小值" value="0"/> <s:textfield name="uqm.age2" label="年龄最大值" value="0"/> <s:submit value="查询"/> --%> <!--下面用到了国际化标签,所以有key --> <s:textfield name="uqm.userId" key="user.userId"/> <s:textfield name="uqm.name" key="user.name"/> <s:select name="uqm.sex" list="sexs" headerKey="" headerValue="Choose" key="user.sex"/> <s:textfield name="uqm.age" value="0" key="query.age1"/> <s:textfield name="uqm.age2" value="0" key="query.age2"/> <s:submit name="" key="add.submit"/> </s:form></center></body></html>
update.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib prefix="s" uri="/struts-tags"%><!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>update-page</title></head><body><h2>Update-Page</h2><s:form action="userUpdate" method="post" namespace="/"> <s:textfield name="user.userId" label="编号"></s:textfield> <s:textfield name="user.name" label="姓名"></s:textfield> <s:select list="sexs" name="user.sex" label="性别"></s:select> <s:textfield name="user.age" label="年龄"></s:textfield> <s:submit value="修改"></s:submit></s:form></body></html>
最后,还需配置web.xml文件(这个很简单),还要在INF-Web下面的lib中复制相关的jar包,包括数据库连接驱动、struts包和c3p0包。数据库的表tb1_user的属性分别是userId name sex age ,userId是primary key!
使用struts2框架来实现CRUD(create、read、update、delete)相关推荐
- Spring笔记 整合SSM[Struts2框架] 万神小栈
一 spring概述 1.1 web项目开发中的耦合度问题 微信小程序搜索 万神小栈 更多资源等你发现! 如果文章对你有帮助别忘了点赞加关注喔~ 在servlet中需要调用service中的方法,则需 ...
- struts2找不到action_第一次用上Struts2框架做Web开发的体验……
SliiyStruts2 又名 sb-struts2,因为struts真的太难用了(也许在很多年前是很好用的,但是现在看来,被其他框架秒成渣) 前言 想不到我还是得和这struts框架打交道啊,从一开 ...
- Struts2框架学习---ONE
通过阅读本你将掌握: struts2框架的配置 入门程序的实现: 配置文件的加载顺序: ...
- SSM框架整合之CRUD操作
SSM框架整合之CRUD操作 说明: 主要将SSM框架整合,做简单的业务逻辑操作CRUD,所以前端并不怎么好看,但是业务逻辑更集中SSM整合和CRUD操作,非常适合刚学过Sping + SpringM ...
- 基于Struts2框架的名片管理系统
目录 1.系统设计 2.数据库设计 3.系统管理 4.用户管理 5.名片管理 本篇博文将分享一款基于Struts2框架的名片管理系统,JSP引擎为Tomcat9.0,数据库采用的是MySQL5.5,集 ...
- java struts2 框架 入门简介
目录 一.Struts2框架执行流程 二.Struts2的快速入门 1.导入jar包 2.配置web.xml文件 3.配置struts.xml文件 4.创建Action来完成逻辑操作 三.Struts ...
- Struts2框架学习Action命名空间创建方式
Struts2框架中Action类时一个单独的javabean对象,相比struts1来说,不需要去继承任何类型或实现任何借口,表单数据包含在Action中,而Struts1则必须继承org ...
- Maven构建Struts2框架的注意事项
[本人出错点:404,就是在web.xml配置文件中少配置了struts.xml的路径] 1.创建Maven,搭建Struts框架,实现最基本的Hello World 在pom.xml中加入strut ...
- Spring整合Struts2框架的第一种方式(Action由Struts2框架来创建)。在我的上一篇博文中介绍的通过web工厂的方式获取servcie的方法因为太麻烦,所以开发的时候不会使用。...
1. spring整合struts的基本操作见我的上一篇博文:https://www.cnblogs.com/wyhluckdog/p/10140588.html,这里面将spring与struts2 ...
最新文章
- 面试题:如何求根号2
- 导出SAP表结构到EXCEl
- boost::type_erasure::tuple相关的测试程序
- 查看 PHP apache nginx mysql 是如何编译的
- CodeSmith 基础用法和例子
- Zookeeper环境安装
- android生成aar无效,android studio生成aar包并在其他工程引用aar包的方法
- android com.squareup,android – 无法导入com.squareup.okhttp.OkHttpClient;
- python中分割字符串两种方法正则分组别名_Python 正则表达式(分组)
- 微信小程序引入骨架屏组件
- Android Q (Android 10.0)系统新特性
- Jmeter之web压力测试
- 3dmax2020软件安装教程
- 《BBC 跟拍 49 年:穷人与富人的人生七年》
- 【基础】PHP变量及变量作用域
- Android 导出PDF PdfDocument
- xyz坐标转换ybc_经纬度转换XYZ
- c语言转义字符 pdf,C语言教程讲义 pdf版
- 阿里巴巴2018秋招总结
- java常见正则表达式用法
热门文章
- python银行开户_Python数据挖掘与Stata应用实证寒假工作坊
- python列表题目_day5.python列表练习题
- VBA编程常用语句(转载)
- PouchContainer 发布 0.3.0 版本,支持 Kubernetes 拥抱 CNCF 生态
- 详解深度学习中的Normalization,不只是BN(1)
- WinRAR技巧:解压后自动打开解压好的文件夹
- Splunk 会议回想: 大数据的关键是机器学习
- TCP协议客户端读取文本文件,服务器端输出到文本文件
- 记录JVM垃圾回收算法
- 异常以及异常处理框架探析