导图社区 JavaSE-JavaEEDB
JavaSE-JavaEEDB思维导图,包括:Spring、Hibernate框架、struts2框架、js+jquery+ajax、JSP、Servlet(后期补充)、HTTP协议。
编辑于2022-06-28 21:43:29JavaSE-JavaEE+DB
Spring
spring定义
Spring是一个轻量级JavaEE开源框架
IOC/DI(控制反转/依赖注入)
控制反转/依赖注入:在service实现中声明dao接口或在action中声明service接口 生成setter getter 方法之后, 具体的实现类在spring.xml(anntoation: @Component("talentDao") 接口实现id,@Resource(name="talentDao")接口实现注入到接口中)中配置, 具体的实现就会自动注入到set方法中,这种方式的注入叫做依赖注入(setter注入,构造注入,接口注入),而这种控制权由spring容器来管理(而以前是由我们主动new出来的)。 这种把控制权交给spring容器来容管理的形式叫做控制反转;
AOP面向切面编程
日志、事务(HibernateTransactionManager利用AOP进行事务处理)、异常处理、权限、安全统计、性能控制 目的是将业务代码与日志代码相分离,实现低偶合
代理类实现类InvocationHandler{ public void invoke(Object o, Method m) { long start = System.currentTimeMillis(); System.out.println("starttime:" + start); System.out.println(o.getClass().getName()); m.invoke(target); long end = System.currentTimeMillis(); System.out.println("time:" + (end-start)); } public class Client { public static void main(String[] args) throws Exception { Tank t = new Tank(); InvocationHandler h = new TimeHandler(t); Moveable m = (Moveable)Proxy.newProxyInstance((classCload,被代理接口,代理类)Moveable.class, h); m.move(); } }
一、配置xml实现方式 二、annation注解实现
<!-- 数据源 --><!-- <bean id="dataSourse" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"> <property name="driverClassName" value="com.mysql.jdbc.Driver"></property> <property name="url" value="jdbc:mysql://127.0.0.1:3306/spring"></property> <property name="username" value="root"></property> <property name="password" value="123456"></property> </bean> --> <!-- 数据库连接属性 --> <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="locations"> <value>classpath:jdbc.properties</value> </property> </bean> <!-- 数据源 --> <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"> <property name="driverClassName" value="${jdbc.driverClassName}" /> <property name="url" value="${jdbc.url}" /> <property name="username" value="${jdbc.username}" /> <property name="password" value="${jdbc.password}" /> </bean> <!-- serviceImpl中 setDaop写 @Resource(name="userDao") 相当于<s:properyt ref="u"> set(daoimpl)注入 <bean id="userService" class="com.service.impl.UserServiceImpl" scope="prototype"> <property name="userDao" ref="u" /> </bean> --> <context:annotation-config /> <!-- <bean id="userDao" class="com.dao.impl.UserDaoImpl"> </bean> 代替此标签 表示在com包中查询 com.dao.impl.UserDaoImpl 中设置@Component("userDao") 相当于 id=userDao 在com包下搜索 注解标签 --> <context:component-scan base-package="com"/> <!--<bean id="userService" class="com.service.impl.UserServiceImpl"></bean> 用userServiceImpl中@Component("userDao")来替代--> <!-- 容器启动时 需要产生代理 自动产生代理 autoproxy注解行式 面向切面编程 --> <!--<aop:aspectj-autoproxy/> --> <!-- 初始化LogInterceptor 类--> <bean id="logInterceptor" class="com.aop.LogInterceptor"></bean> <aop:config> <!-- 切点 将切面方法 统一由切点来管理 --> <aop:pointcut id="daoPointCut" expression="execution(public * com.dao..*.*(..))" /> <!-- 引用 com.aop.LogInterceptor类 id--> <aop:aspect id="logId" ref="logInterceptor"> <!--在befor方法之后执行daoPointCut对应的 execution(public * com.dao..*.*(..)) --> <!--<aop:before method="befor" pointcut-ref="daoPointCut"/> --> <aop:before method="befor" pointcut="execution(public * com.dao..*.*(..))"/> <aop:after-returning method="after" pointcut-ref="daoPointCut"/> </aop:aspect> </aop:config> </beans>
//切面 @Aspect public class LogInterceptor { public void myMethod(){} public void befor(){ System.out.println("@Before"); } public void after(){ System.out.println("@AfterReturning"); } public void exceptions(){ System.out.println("@AfterThrowing"); } }
spring框架类型
Core(IOC/DI)核心框架
AOP Spring AOP Aspectj集成
Dao Spring jdbc事务管理
ORM Spring (hibernate Ibatis JPA)
web Spring (struts Webwork JSF)
J2ee 服务集成 (EJB JMS RMI JavaMail)
spring MVC 采用MVC模式web框架
beanFactory与ApplicationContext区别:
建议使用ApplicationContext实现了BeanFactory接口建立在它的基础之上的
Hibernate框架
hibernate定义
采用ORM机制的持久层的开源框架
ORM机制
对象关系映射(把对表的操作简化成对实体对象的操作)
hibernate操作7个步骤
1、conifguration读取xml解析 2、SessionFactory解析配置信息,建立数据源工厂对象 3、Session数据连接对象 4、Transaction事务对象 5、session持久对象: save()、update()、delete、get()、load() 6、tx.comit();tx.rollback() 7、关闭session
Session缓存机制
一级缓存(session)
session对象的生命周期
结构Map(key,value)
Hibernate自带,只能管理不能配置
常见方法
s.evick()
s.flush()
s.clear()
二级缓存(sessionFactory)
外部提供插件
sessionFactory生命周期
开发步骤
hibernate3.jar
cfg.xml
配置ecache.xml
查询缓存
查询优化
配置cfg.xml
q.setCacheable(true)
hibernate原理图
struts2框架
Struts定义
基于MVC模式的web的开源框架(把请求和展现分开,易于扩展) M:model javabean DTO V:view jsp c:contler:action
struts1原理图
当web.xml启动时只创建一个action(单态),当很多用户批量访问时此时需要考虑线程同步问题
struts2原理图
每次访问action时就创建一个action(多态),因此不用考虑线程同步问题
struts2细节
struts.xml
struts2命名空间
namespace决定action路径,默认""可以接收所有action namespace="/"或着namespace="/XXX"或着为namespace="/XXX/YYY" 对应action路径/index.action或着/XXX/index.action或着/xxx/yyy/index.action
type类型
dispatcher(jsp中的forword跳转 服务器跳转到某个页面)
redirect(客户端跳转到视图页面)
chain(服务器端跳转到某个(forwardaction)action)
redirectAction(客户端跳转 到某一个action)
action.java
public class IndexAction extends ActionSupport
跳转方式
普通调用 <action name="hello" class="IndexAction" method="add"> <result >/Hello.jsp</result> </action> DMI动态调用 <a href="<%=basePath%>frout/hello!add">hello world</a> 通配符调用
Ognl表达试
struts2声明试异常处理
有异常可以随便往出抛出,最后由struts2跳转到一个页面统一管理
<package name="bbs2009_default" extends="struts-default"> <global-results> <result name="error">/error.jsp</result> </global-results> <global-exception-mappings> <exception-mapping result="error" exception="java.lang.Exception"></exception-mapping> </global-exception-mappings> </package>
struts2拦截器原理
自定义拦截器案例 public class MyInterceptor implements Interceptor { public void destroy() { } public void init() { } public String intercept(ActionInvocation invocation) throws Exception { long start = System.currentTimeMillis(); String r = invocation.invoke(); long end = System.currentTimeMillis(); System.out.println("action time = " + (end - start)); return r; } } struts.xml <package name="test" namespace="/" extends="struts-default"> <interceptors> <interceptor name="my" class="com.interceptor.MyInterceptor"></interceptor> </interceptors> <action name="test" class="com.action.TestAction"> <result>/test.jsp</result> <interceptor-ref name="my"></interceptor-ref> <interceptor-ref name="defaultStack"></interceptor-ref> </action> </package>
js+jquery+ajax
js_ajax
异步处理,局部刷新
1、利用XMLHttpRequest判断浏览器类型 2、注册回调函数callback xmlHttp.onreadystatechange=callback; 3、open打开连接 xmlHttp.open("post", "http://localhost:8080/rcfb/talent/test.zealinfo?name="+userName, true); 4、//post方式需要自己设置http请求头 xmlHttp.setRequestHeader("Content-Type","application/x-www-form-urllencoded"); 5、进行发送 xmlHttp.send(null); 6、通过回调函数访问服务器,返回给客户端数据
详细操作(post请求): var xmlHttp; function doSave(){ //获取user属性值 var userName = document.getElementById('userId').value; //创建XmlHttpRequest对象 if(window.XMLHttpRequest){ //FireFox Mozillar Opera Safari IE7 IE8 xmlHttp=new XMLHttpRequest(); //fireforx if(xmlHttp.overrideMimeType){ xmlHttp.overrideMimeType("text/xml"); } }else if(window.ActiveXObject){ //ie6 ie5 var activeName=["MSXML2.XMLHTTP","Microsoft.XMLHTTP"]; for(var i=0;i<activeName.length;i++){ try{ xmlHttp=new ActiveXObject(activeName[i]); break; }catch(e){ } } } if(!xmlHttp){ alert("XMLHttpRequest对象创建失败"); return; }else{ } //注册回调函数 xmlHttp.onreadystatechange=callback; //设置连接信息 xmlHttp.open("post", "http://localhost:8080/rcfb/talent/test.zealinfo?name="+userName, true); //post方式需要自己设置http请求头 xmlHttp.setRequestHeader("Content-Type","application/x-www-form-urllencoded"); //发送数据,开始和服务器进行交互 //同步方式下,send这句话会在服务器数据库回来后才执行 //异步方式下,send这句话会立即执行; xmlHttp.send(null); } //回调函数 function callback(){ //判断对象的状态是交互完成 if(xmlHttp.readyState==4){ //判断http交互是否成功 if(xmlHttp.status==200){ //获取服务器端的返回对象 //获取服务器端文本数据 var responseText=xmlHttp.responseText; var div1 = document.getElementById('div1'); div1.innerHTML=responseText; } } }
public void test() throws IOException{ ActionContext context = ActionContext.getContext(); HttpServletResponse response = (HttpServletResponse) context.get(ServletActionContext.HTTP_RESPONSE); HttpServletRequest request = (HttpServletRequest) context.get(ServletActionContext.HTTP_REQUEST); response.setContentType( "text/html;charset-utf-8"); String userName=request.getParameter("name"); if(userName.equals("123")){ response.getWriter().write("ok"); //response.getWriter().print("success"); }else{ response.getWriter().write("您输入的用户名有误!"); //response.getWriter().print("error!"); } }
jquery+ajax
//jquery的ajax操作步骤 function doSave(){ $.ajax({ type:"post",//http请求 url: "http://localhost:8080/rcfb/talent/test.zealinfo",//服务器url data: "name="+$('#userId').val(),//发送给服务器的数据 dataType: "html",//告诉jquery 返回的数据类型 success:function(data){ $('#div1').html(data); } //定义交互完成,并且服务器端,正确返回数据时调用的回调函数 }); }
public void test() throws IOException{ ActionContext context = ActionContext.getContext(); HttpServletResponse response = (HttpServletResponse) context.get(ServletActionContext.HTTP_RESPONSE); HttpServletRequest request = (HttpServletRequest) context.get(ServletActionContext.HTTP_REQUEST); response.setContentType( "text/html;charset-utf-8"); String userName=request.getParameter("name"); if(userName.equals("123")){ response.getWriter().write("ok"); //response.getWriter().print("success"); }else{ response.getWriter().write("您输入的用户名有误!"); //response.getWriter().print("error!"); } }
JSP
jsp工作原理:
http://localhost:8080/ServletJsp/lihaoran.jsp
web服务器
第一次访问jsp文件web服务器就会把lihaoran.jsp翻译成Servlet--lihaoran_jsp.java 如果某个jsp文件被修改了也相当第一次访问
jsp-->生成的lihaoran_jsp.java文件格式简化: public final class lihaoran_jsp extends org.apache.jasper.runtime.HttpJspBase { public void _jspInit() {} public void _jspService(HttpServletRequest request, HttpServletResponse response) throws java.io.IOException, ServletException out.write(" <body>\r\n"); out.println("hello world"+"当前日期="+new java.util.Date()); out.write(" </body>\r\n"); out.write("</html>\r\n"); } public void _jspDestroy() {}
再将lihaoran_jsp.java编译成lihaoran_jsp.class,然后所.class加载到内存当中执行
第二次以上访问就直接访问.class内存实例,因此jsp也是单例的,所以第一次访问jsp网站速度慢,二次以后会快
Jsp定义:
jsp是基于Servlet的动态网站技术 jsp是包涵java的html页面 jsp=html+java+css+javascript
JSP九大内置对象
1、Request:接收客户端Http请求 request.getParameter("user"); 2、Response:封装jsp产生的回应给浏览器请求信息 response.sendRedirect("/ServletJsp/ServletMain?user="+username); 3、session:用于保存用户信息,保存用户行为 request.getSession().setAttribute("usersession",username); String usersession=(String) request.getSession().getAttribute("usersession"); 4、application:多个用户共享此对象,可以做计数器 5、config:代表jsp对应的Servlet的配置,可以得到web.xml中的参数 6、page:本jsp网页使用即有效 7、pageContext:jsp页面的上下文 8、out:向客户端传输数据,字节流 9、exception:代表运行时异常
Servlet(后期补充)
B/S与C/S区别
B/S:浏览器(html/jsp)和服务器 C/S:客户端(自己开发)与服务器
服务器
Tomcat
Jboss
WebLogic(BEA)
WebSpher(IBM)
Servlet定义
Servlet是运行在服务器端并包括HTML页面的Java代码
Servlet生命周期
init()初始化一次
Service方法 public void doPost(HttpServletRequest request, HttpServletResponse response) public void doGet(HttpServletRequest request, HttpServletResponse response) 每次请求访问则被调用 而request, response)对象每次都是全新的
destroy()服务器/revload停止消毁
售票系统解决并发(同时抢票)
1、如果一个变量需要多个用户共享,则应当在访问该变量的时候,加同步机制; synchronized(对象){} 2、如果 一个变量不需要共享,则直接在doGet()/doPost()定义,这样不会存在线程安全问题
int tick=3;//成员变量 response.setContentType("text/html;character=utf-8"); response.setCharacterEncoding("UTF-8"); response.getWriter().println("彩票系统"); synchronized(this){ if(this.tick>0){ System.out.println("我买到了彩票"+this.tick); response.getWriter().print("我买到乐膘"+this.tick); try { Thread.sleep(10000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } this.tick--; }else{ System.out.println("你没有买到票"); response.getWriter().print("我没有买到票"+this.tick); } }
定时发送电子邮件
web.xml <servlet> <servlet-name>ServletAction1</servlet-name> <servlet-class>com.ServletAction1</servlet-class> <!-- 1表示servlet 被init的顺序(代表第一个被调用) --> <load-on-startup>1</load-on-startup> </servlet>
ServetAction1.java public void init() throws ServletException { System.out.println("调用ServletAction方法"); //创建线程 SendMailThread sm = new SendMailThread(); sm.start(); }
SendMailThread类 public class SendMailThread extends Thread{ public void run(){ int i=0; try { while(true){ //每休眠10s钟,就去扫描sendmail,看看那个邮件被没被发送出去 Thread.sleep(10*1000); System.out.println("发出第"+(++i)+"邮件"); } } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
HttpServletResponse
response.getWriter();与response.getOutputStream()区别: getWriter()回送字符数据,效率高 getOutputStream()回送字节数据
两中流不可同时使用;原因是Tomact在接收第一个流的时候就被close了 所有再接收第二个流的时候会报错
SendRedirect()重定向 优点:传送的速度快 缺点:它只能传送字符串,不能传对象 属于服务器端跳转,当第一次跳转可以设置为post,而redirect302转发后(response.sendRedirect("/ServletJsp/ServletMain?user="+username);), 就以get的形式传输,所有中文注意乱码解决
HttpServletRequest
Http请求头的信息都会被封装到HttpServletRequest对象当中
HTTP 协议
http协议定义
1、http协议全称:超文本传输协议 2、http协议是建立在TCP/IP协议基础之上建立的
http版本1.0与1.1区别:
Http1.0短连接 http1.1长连接 所谓的长和短指的是:时间的长连接1.1版本大概是30秒,短连接是发送完就断开连接
http请求方式get/post区别:
1、传输的方式:get请求方式发送时是在url地地址中发送,而post请求提交时是从包体中发送 2、传输大小:http协议没有传输大小的限制,特定的浏览器,服务器有限制,例如I.E.限制(2k+35) 而fireFox理论上没有限制,有限制取决于操作系统 3、安全性:post提交安全,get提交相对不安全
http消息请求头
客户端浏览器向服务器发送请求request
请求头信息: POST /rcfb/user/getLogin.zealinfo HTTP/1.1-->请求行 Get/Post Accept: image/jpeg, application/x-ms-application, image/gif, application/xaml+xml, image/pjpeg, application/x-ms-xbap, */*-->告诉服务器,我可以接收文本、图片,网页等信息; Referer: http://localhost:8080/rcfb/index.zealinfo-->告诉服务器是从哪里来的,可以该上盗链,防下载; Accept-Language: zh-CN-->接收字符编码 User-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; Tablet PC 2.0)-->告诉浏览器内核 Content-Type: application/x-www-form-urlencoded Accept-Encoding: gzip, deflate-->可以接收gzip, deflate压缩之后的数据 Host: localhost:8080-->我要找的主机是 localhost:8080 Content-Length: 46 Connection: Keep-Alive-->保持连接,发送完数据,我不关闭连接; Cache-Control: no-cache-->缓存 Cookie: JSESSIONID=FFEA458426B435CB09B75D6116F74BFE userAdd.userName=lihaoran&userAdd.passWord=123-->包体内容
获取请求代码演示: public void goHeaderInfo() throws IOException{ ActionContext context = ActionContext.getContext(); HttpServletRequest request = ServletActionContext.getRequest(); HttpServletResponse response = (HttpServletResponse) context.get(ServletActionContext.HTTP_RESPONSE); HttpSession session = ServletActionContext.getRequest().getSession(); response.setCharacterEncoding("UTF-8");//将这段返回页面信息代码转换成utf-8 response.setContentType("text/html;charset=UTF-8");//页面要以utf-8形式显示 String accept=request.getHeader("Accept"); String referer=request.getHeader("Referer"); String host=request.getHeader("Host"); String charet=request.getHeader("Accept-Encoding"); String cookie=request.getHeader("Cookie"); String Connection=request.getHeader("Connection"); String cache=request.getHeader("Cache-Contro"); String agent=request.getHeader("User-Agent"); String date=request.getHeader("Date"); String project=ServletActionContext.getServletContext().getContextPath();//获取项目名 //防盗链 告诉服务器我来自己哪里 常用在防盗链referer: http://localhost:8080/SSH_Base_jdbcTempte_session_XML20/pages/test/daolian.jsp if(referer==null||!referer.startsWith("http://localhost:8080"+project)){ response.sendRedirect(project+"/say/errors.lihaoran"); return; } response.getWriter().println("告诉服务器我可以接收的内容accept:"+accept+"<br/>"); response.getWriter().println("可接收的压缩格式:Accept-Encoding\t "+charet+"<br/>"); response.getWriter().println("告诉服务器我来自己哪里 常用在防盗链referer:\t "+referer+"<br/>"); response.getWriter().println("主机地址Host:\t"+host+"<br/>"); response.getWriter().println("保持连接,发完数据不关闭链接Connection:\t"+Connection+"<br/>"); response.getWriter().println("告诉服务器浏览器内核User-Agent:\t"+agent+"<br/>"); response.getWriter().println("缓存Cache-Contro:\t"+cache+"<br/>"); response.getWriter().println("浏览器发送http请求时间Date:\t"+date+"<br/>"); response.getWriter().println("cookie:\t"+cookie+"<br/>"); }
Http响应头信息
服务器响应浏览器请求信息
响应头信息: HTTP/1.1 302 Moved Temporarily-->状态行200表示成功; 302表示让浏览器转到别一个链接上(redirectAction ),404表示错误;500服务器错误; Server: Apache-Coyote/1.1-->告诉浏览器 我的服务是tomact Location: http://localhost:8080/rcfb/user/list.zealinfo-->定位到另一个url地址 Refresh: url=http://localhost:8080/rcfb/index.zealinfo-->告诉浏览器多久之后刷新到index.zealinfo页面上 Content-Type: text/html;charset=UTF-8-->内容文本格式,字符UTF-8字符 content-Encoding:gzip-->告诉浏览器,我是以gzip的压缩后传输的 Content-Length: 0 Content-Disposition: filename="2013-01-21 11-11-59.doc"-->告诉浏览器有文件要下载 set-cookie:JSESSIONID=FFEA458426B435CB09B75D6116F74BFE--> Last-Modified: Wed, 13 Feb 2013 12:50:35 GMT-->告诉浏览器,上次更新时间是... Date: Wed, 13 Feb 2013 15:51:55 GMTopic
//底层写法 服务器跳转 response.setStatus(302); response.setHeader("Location","say/getInfo2.lihaoran"); //两者等同 //现实用法 response.sendRedirect("say/getInfo2.lihaoran"); //分钟 自动刷新跳转到url新链接上去 //response.setHeader("Refresh","5;url=say/getInfo2.lihaoran");
文件下载案例
//文件下载 public void getDownload() throws IOException{ ActionContext context = ActionContext.getContext(); HttpServletRequest request = ServletActionContext.getRequest(); HttpServletResponse response = (HttpServletResponse) context.get(ServletActionContext.HTTP_RESPONSE); //防盗链 String referer=request.getHeader("Referer"); String project=ServletActionContext.getServletContext().getContextPath();//获取项目名 //防盗链 告诉服务器我来自己哪里 常用在防盗链referer: http://localhost:8080/SSH_Base_jdbcTempte_session_XML20/pages/test/daolian.jsp if(referer==null||!referer.startsWith("http://localhost:8080"+project)){ response.sendRedirect(project+"/say/errors.lihaoran"); return; } //处理下载后中文乱码 String temps = java.net.URLEncoder.encode("简历.rar","utf-8"); String realpath; realpath = ServletActionContext.getServletContext().getRealPath(File.separator+"DownLoad" +File.separator+ "简历.rar") ; response.setHeader("Content-Disposition","attachment;filename="+temps); //文件输入流 FileInputStream fis = new FileInputStream(realpath); byte buff[]=new byte[1024]; int len=0; OutputStream os = response.getOutputStream(); while((len=fis.read(buff))>0){ os.write(buff,0,len); } //关闭链接 os.close(); fis.close(); }
处理浏览器缓存
//缓存 public void cacheInfo() throws IOException{ ActionContext context = ActionContext.getContext(); HttpServletResponse response = (HttpServletResponse) context.get(ServletActionContext.HTTP_RESPONSE); response.setCharacterEncoding("UTF-8");//将这段返回页面信息代码转换成utf-8 response.setContentType("text/html;charset=UTF-8");//页面要以utf-8形式显示 //指定页面不缓存 response.setDateHeader("Expires",-1); //保证兼容 response.setHeader("Cache-Control","no-cache"); response.setHeader("Pragma","no-cache"); //设置缓存一天失效 //response.setDateHeader("Expires",System.currentTimeMillis()+3600*1000*24); response.getWriter().print("当前时间"+new java.util.Date().toLocaleString()); }
处理中文乱码
//处理乱码工具类 public static String getStringEncode(String encode) throws UnsupportedEncodingException{ return new String(encode.getBytes("iso-8859-1"),"utf-8"); } username =EncodeTool.getStringEncode(this.username);
Struts中以redirectAction 页面提交方法是post 方式时 乱码解决方法action.xml <!-xml配置方法--> <action name="getEcode" class="com.action.session.SessionAction" method="getEcode"> <result name="success" type="redirectAction"> <param name="actionName">getEcode2.lihaoran</param> <param name="username">${username}</param> <param name="passworld">${passworld}</param> </result> </action> <!-- 解决中乱码--> <action name="getEcode2" class="com.action.session.SessionAction" method="getEcode2"> <result name="success" type="dispatcher">/pages/test/encodeList.jsp</result> </action>
getEcode()方法 public String getEcode() throws UnsupportedEncodingException{ HttpServletRequest request = ServletActionContext.getRequest(); //对参数不做任何处理 return SUCCESS; }
getEcode2()方法 public String getEcode2() throws Exception{ HttpServletRequest request = ServletActionContext.getRequest(); //需要转一次码 username =EncodeTool.getStringEncode(this.username); passworld = EncodeTool.getStringEncode(this.passworld); return SUCCESS; }
Struts中以redirectAction 页面提交方法是超链接或get方式提交时 需转两次码 解决方法如下:acton.xml文件同上 Action.java //处理中文乱码 两次转码 public String getEcode() throws UnsupportedEncodingException{ HttpServletRequest request = ServletActionContext.getRequest(); //重写向前 转码成 utf-8 username =EncodeTool.getStringEncode(this.username); passworld = EncodeTool.getStringEncode(this.passworld); return SUCCESS; } //redirectAction 乱码解决方法 public String getEcode2() throws Exception{ HttpServletRequest request = ServletActionContext.getRequest(); //重写向后转码成 utf-8 username =EncodeTool.getStringEncode(this.username); passworld = EncodeTool.getStringEncode(this.passworld); return SUCCESS; }
J D B C
package com.tool; import java.io.FileInputStream; import java.io.IOException; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.Properties; public class SqlTool { //定义三个连接变量 private static Connection conn=null; private static PreparedStatement ps=null; private static ResultSet rs=null; //连接数据库用户名,密码 url 驱动 private static String username=null; private static String passworld=null; private static String driver=null; private static String url=null; private static FileInputStream fis=null; //使用静态块加载驱动 static{ try { //创建porperty Properties p = new Properties(); fis= new FileInputStream("jdbc.properties"); p.load(fis); username=(String) p.getProperty("username"); passworld=(String) p.getProperty("passworld"); driver=(String) p.getProperty("driver"); url=(String) p.getProperty("url"); Class.forName(driver); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); }finally{ try { //关闭文件流 fis.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } public static Connection getConnection(){ try { conn= DriverManager.getConnection(url,username,passworld); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } return conn; } /** * 统一的crud */ public static void executeUpdate(String sql,String[] parameters){ try { conn=DriverManager.getConnection(url,username,passworld); ps=conn.prepareStatement(sql); if(parameters!=null){ for (int i = 0; i ps.setString(i+1,parameters[i]); } } ps.executeUpdate(); //获取数据库连接 } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); throw new RuntimeException(e.getMessage()); }finally{ //close(rs,ps,conn); } } //写一个查询 //表示要查询的sql语句 //select * from emp where ename=? public static ResultSet executeQuery(String sql,String[] parameters){ try { //获取数据库连接 conn=DriverManager.getConnection(url,username,passworld); //创建ps对象==>sql语句对象 ps=conn.prepareStatement(sql); //根据实际情况 if(parameters!=null){ for(int i=0;i ps.setString(i+1,parameters[i]); } } rs=ps.executeQuery(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); throw new RuntimeException(e.getMessage()); }finally{ //close(rs,ps,conn); } return rs; } /**关闭资源 * @param rs * @param ps * @param conn */ public static void close(ResultSet rs,Statement ps,Connection conn){ if(rs!=null){ try { rs.close(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } rs=null; if(ps!=null){ try { ps.close(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } ps=null; if(conn!=null){ try { conn.close(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } public static Connection getConn() { return conn; } public static PreparedStatement getPs() { return ps; } public static ResultSet getRs() { return rs; } } package com; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import com.tool.SqlTool; /** * @author Administrator * */ public class TestOracle { public static void main(String args[]){ //查询方法 //selects(); //添加 //inserts(); //修改 updates(); } /**查询 * */ public static void selects(){ ResultSet rs=null; try { String sql="select * from lihaoran"; rs=SqlTool.executeQuery(sql, null); while(rs.next()){ System.out.println(rs.getString("ename")); } } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); }finally{ SqlTool.close(rs,SqlTool.getPs(), SqlTool.getConn()); } } /**添加 * */ public static void inserts(){ String insert="insert into lihaoran(empno,ename) values(2,'lihaoran')"; try { SqlTool.executeUpdate(insert,null); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); }finally{ SqlTool.close(SqlTool.getRs(),SqlTool.getPs(), SqlTool.getConn()); } } public static void updates(){ /*String sql1="update lihaoran set sal=sal+10 where empno=7369"; String sql2="update lihaoran set sal=sal+10 where empno=7499"; SqlTool.executeUpdate(sql1,null); SqlTool.executeUpdate(sql2,null); SqlTool.close(SqlTool.getRs(),SqlTool.getPs(), SqlTool.getConn()); */ Connection conn=null; try{ String sql1="update lihaoran set sal=sal-10 where empno=7369"; String sql2="update lihaoran set sal=sal+10 where empno=7499"; //得到连接 conn=SqlTool.getConnection(); //设置不自动提交 conn.setAutoCommit(false); PreparedStatement pst1=conn.prepareStatement(sql1); PreparedStatement pst2=conn.prepareStatement(sql2); pst1.executeUpdate(); pst2.executeUpdate(); //把两个事务看作一个事务统一提交 conn.commit(); }catch (Exception e) { e.printStackTrace(); //如果事务出现异常可以统一回滚 try { conn.rollback(); } catch (SQLException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } // TODO: handle exception }finally{ //关闭资源 SqlTool.close(SqlTool.getRs(),SqlTool.getPs(), SqlTool.getConn()); } } }
加载驱动
Class.forName("...")
建立连接
conn=DriverManager.getConnection(url,username,passworld);
执行sql
Statement
PreparedStatement预处理
ps=conn.prepareStatement(sql); ps.executeUpdate();
添加
修改
删除
ps.executeQuery()
查询
CallableStatement调用存储过程
import java.sql.Connection ; import java.sql.DriverManager ; import java.sql.SQLException ; import java.sql.CallableStatement ; import java.sql.Types ; public class ProcDemo{ // 定义MySQL的数据库驱动程序 public static final String DBDRIVER = "org.gjt.mm.mysql.Driver" ; // 定义MySQL数据库的连接地址 public static final String DBURL = "jdbc:mysql://localhost:3306/mldn" ; // MySQL数据库的连接用户名 public static final String DBUSER = "root" ; // MySQL数据库的连接密码 public static final String DBPASS = "mysqladmin" ; public static void main(String args[]) throws Exception{ // 所有异常抛出 Connection conn = null ; // 数据库连接 CallableStatement cstmt = null ; // 数据库操作 String sql = "{CALL myproc(?,?,?)}" ; // 调用过程 Class.forName(DBDRIVER) ; // 加载驱动程序 conn = DriverManager.getConnection(DBURL,DBUSER,DBPASS) ; cstmt = conn.prepareCall(sql) ; cstmt.setInt(1,70) ; // 设置第一个参数是70 cstmt.setInt(2,80) ; // 设置第二个参数是80 cstmt.registerOutParameter(2,Types.INTEGER) ; cstmt.registerOutParameter(3,Types.INTEGER) ; cstmt.execute() ; // 执行过程 System.out.println("INOUT的返回值:" + cstmt.getInt(2)) ; System.out.println("OUT的返回值:" + cstmt.getInt(3)) ; cstmt.close() ; conn.close() ; // 数据库关闭 } }; DELIMITER // DROP PROCEDURE myproc // -- 删除过程 CREATE PROCEDURE myproc(IN p1 int,INOUT p2 int,OUT p3 int) BEGIN SELECT p1,p2,p3 ; -- 输出p1、p2、p3的内容 SET p1=10 ; SET p2=20 ; SET p3=30 ; END // DELIMITER ; SET @x1=70 ;-- 定义变量x1,内容为70 SET @x2=80 ;-- 定义变量x2,内容为80 CALL myproc(@x1,@x2,@x3) ; SELECT @x1,@x2,@x3 ;
处理执行查询ResultSet
ps=conn.prepareStatement(sql); rs=ps.executeQuery();查询 while(rs.next()){ System.out.println(rs.getString("ename")); }
关闭资源
import java.sql.Connection ; import java.sql.DriverManager ; import java.sql.SQLException ; import java.sql.Statement ; public class TranDemo02{ // 定义MySQL的数据库驱动程序 public static final String DBDRIVER = "org.gjt.mm.mysql.Driver" ; // 定义MySQL数据库的连接地址 public static final String DBURL = "jdbc:mysql://localhost:3306/mldn" ; // MySQL数据库的连接用户名 public static final String DBUSER = "root" ; // MySQL数据库的连接密码 public static final String DBPASS = "mysqladmin" ; public static void main(String args[]) throws Exception{ // 所有异常抛出 Connection conn = null ; // 数据库连接 Statement stmt = null ; // 定义数据库操作 Class.forName(DBDRIVER) ; // 加载驱动程序 conn = DriverManager.getConnection(DBURL,DBUSER,DBPASS) ; conn.setAutoCommit(false) ;// 取消掉自动提交 stmt = conn.createStatement() ; stmt.addBatch("INSERT INTO user(name,password,age,sex,birthday)" + " VALUES ('LXH-1','hello-1',11,'男','1975-03-05') ") ; stmt.addBatch("INSERT INTO user(name,password,age,sex,birthday)" + " VALUES ('LXH-2','hello-2',12,'女','1976-03-05') ") ; // 加入“'”之后,此SQL语法就出现了错误,所以,肯定执行到此语句的时候出现代码错误 stmt.addBatch("INSERT INTO user(name,password,age,sex,birthday)" + " VALUES ('LXH-'3','hello-3',13,'男','1977-06-01') ") ; stmt.addBatch("INSERT INTO user(name,password,age,sex,birthday)" + " VALUES ('LXH-4','hello-4',14,'女','1965-03-05') ") ; stmt.addBatch("INSERT INTO user(name,password,age,sex,birthday)" + " VALUES ('LXH-5','hello-5',15,'女','1965-08-05') ") ; try{ int temp[] = stmt.executeBatch() ; System.out.println("更新了:" + temp.length+ "条数据。") ; conn.commit() ; // 所有的操作成功了 }catch(Exception e){ try{ conn.rollback() ; }catch(Exception e1){ } } stmt.close() ; conn.close() ; // 数据库关闭 } }; import java.sql.Connection ; import java.sql.DriverManager ; import java.sql.SQLException ; import java.sql.Statement ; import java.sql.Savepoint ; public class TranDemo03{ // 定义MySQL的数据库驱动程序 public static final String DBDRIVER = "org.gjt.mm.mysql.Driver" ; // 定义MySQL数据库的连接地址 public static final String DBURL = "jdbc:mysql://localhost:3306/mldn" ; // MySQL数据库的连接用户名 public static final String DBUSER = "root" ; // MySQL数据库的连接密码 public static final String DBPASS = "mysqladmin" ; public static void main(String args[]) throws Exception{ // 所有异常抛出 Connection conn = null ; // 数据库连接 Statement stmt = null ; // 定义数据库操作 Class.forName(DBDRIVER) ; // 加载驱动程序 conn = DriverManager.getConnection(DBURL,DBUSER,DBPASS) ; conn.setAutoCommit(false) ;// 取消掉自动提交 stmt = conn.createStatement() ; stmt.executeUpdate("INSERT INTO user(name,password,age,sex,birthday)" + " VALUES ('LXH-1','hello-1',11,'男','1975-03-05') ") ; stmt.executeUpdate("INSERT INTO user(name,password,age,sex,birthday)" + " VALUES ('LXH-2','hello-2',12,'女','1976-03-05') ") ; Savepoint sp = conn.setSavepoint() ; // 设置保存点 stmt.executeUpdate("INSERT INTO user(name,password,age,sex,birthday)" + " VALUES ('LXH-4','hello-4',14,'女','1965-03-05') ") ; stmt.executeUpdate("INSERT INTO user(name,password,age,sex,birthday)" + " VALUES ('LXH-5','hello-5',15,'女','1965-08-05') ") ; try{ conn.rollback(sp) ; // 回滚到保存点 conn.commit() ; // 所有的操作成功了 }catch(Exception e){ e.printStackTrace() ; } stmt.close() ; conn.close() ; // 数据库关闭 } };
conn.setAutoCommit(false) ; // 取消掉自动提交 try { ps.executeUpdate("insert..."); Savepoint sp = conn.setSavepoint() ; // 设置保存点 ps.executeUpdate("insert..."); conn.rollback(sp);//回滚到保存点 conn.commit() ; // 所有的操作成功了 } catch (SQLException e) { --conn.rollback()//事务回滚 }finally{ rs.close();//关闭资源 conn.close(); }
事务控制
事物特征ACID:
原子性Atomicity
一致性Consistency
隔离性isolation
持久性Durability
处理大数据CLOB
import java.sql.Connection ; import java.sql.DriverManager ; import java.sql.SQLException ; import java.sql.PreparedStatement ; import java.io.File ; import java.io.FileInputStream ; import java.io.InputStream ; public class ClobDemo01{ // 定义MySQL的数据库驱动程序 public static final String DBDRIVER = "org.gjt.mm.mysql.Driver" ; // 定义MySQL数据库的连接地址 public static final String DBURL = "jdbc:mysql://localhost:3306/mldn" ; // MySQL数据库的连接用户名 public static final String DBUSER = "root" ; // MySQL数据库的连接密码 public static final String DBPASS = "mysqladmin" ; public static void main(String args[]) throws Exception{ // 所有异常抛出 Connection conn = null ; // 数据库连接 PreparedStatement pstmt = null ; String name = "李兴华" ; // 表示姓名 String sql = "INSERT INTO userclob(name,note) VALUES (?,?) " ; Class.forName(DBDRIVER) ; // 加载驱动程序 conn = DriverManager.getConnection(DBURL,DBUSER,DBPASS) ; pstmt = conn.prepareStatement(sql) ; // 创建PreapredStatement对象 File f = new File("d:" + File.separator + "mldn.txt") ; InputStream input = null ; input = new FileInputStream(f) ; // 通过输入流读取文件 pstmt.setString(1,name) ; pstmt.setAsciiStream(2,input,(int)f.length()) ; pstmt.executeUpdate() ; conn.close() ; // 数据库关闭 } }; import java.sql.Connection ; import java.sql.DriverManager ; import java.sql.SQLException ; import java.sql.PreparedStatement ; import java.sql.ResultSet ; import java.io.File ; import java.io.FileInputStream ; import java.io.InputStream ; import java.util.Scanner ; public class ClobDemo02{ // 定义MySQL的数据库驱动程序 public static final String DBDRIVER = "org.gjt.mm.mysql.Driver" ; // 定义MySQL数据库的连接地址 public static final String DBURL = "jdbc:mysql://localhost:3306/mldn" ; // MySQL数据库的连接用户名 public static final String DBUSER = "root" ; // MySQL数据库的连接密码 public static final String DBPASS = "mysqladmin" ; public static void main(String args[]) throws Exception{ // 所有异常抛出 Connection conn = null ; // 数据库连接 PreparedStatement pstmt = null ; ResultSet rs = null ; int id = 1 ; // 读取的编号 String sql = "SELECT name,note FROM userclob WHERE id=? " ; Class.forName(DBDRIVER) ; // 加载驱动程序 conn = DriverManager.getConnection(DBURL,DBUSER,DBPASS) ; pstmt = conn.prepareStatement(sql) ; // 创建PreapredStatement对象 pstmt.setInt(1,id) ; rs = pstmt.executeQuery() ; if(rs.next()){ String name = rs.getString(1) ; StringBuffer note = new StringBuffer() ; System.out.println("姓名:" + name) ; InputStream input = rs.getAsciiStream(2) ; Scanner scan = new Scanner(input) ; // 使用Scanner类读取内容 scan.useDelimiter("\r\n") ;// 将文件换行作为分割符 while(scan.hasNext()){ note.append(scan.next()).append("\n") ; } System.out.println("内容:" + note) ; input.close() ; } rs.close() ; pstmt.close() ; conn.close() ; // 数据库关闭 } }; import java.sql.Connection ; import java.sql.DriverManager ; import java.sql.SQLException ; import java.sql.PreparedStatement ; import java.sql.Clob ; import java.sql.ResultSet ; public class ClobDemo03{ // 定义MySQL的数据库驱动程序 public static final String DBDRIVER = "org.gjt.mm.mysql.Driver" ; // 定义MySQL数据库的连接地址 public static final String DBURL = "jdbc:mysql://localhost:3306/mldn" ; // MySQL数据库的连接用户名 public static final String DBUSER = "root" ; // MySQL数据库的连接密码 public static final String DBPASS = "mysqladmin" ; public static void main(String args[]) throws Exception{ // 所有异常抛出 Connection conn = null ; // 数据库连接 PreparedStatement pstmt = null ; ResultSet rs = null ; int id = 1 ; // 读取的编号 String sql = "SELECT name,note FROM userclob WHERE id=? " ; Class.forName(DBDRIVER) ; // 加载驱动程序 conn = DriverManager.getConnection(DBURL,DBUSER,DBPASS) ; pstmt = conn.prepareStatement(sql) ; // 创建PreapredStatement对象 pstmt.setInt(1,id) ; rs = pstmt.executeQuery() ; if(rs.next()){ String name = rs.getString(1) ; System.out.println("姓名:" + name) ; Clob c = rs.getClob(2) ; String note = c.getSubString(1,(int)c.length()) ; System.out.println("内容:" + note ) ; c.truncate(100) ;// 只能读100个内容 System.out.println("部分读取内容:" + c.getSubString(1,(int)c.length())) ; } rs.close() ; pstmt.close() ; conn.close() ; // 数据库关闭 } };
处理海量文字
处理大数据BLOB
import java.sql.Connection ; import java.sql.DriverManager ; import java.sql.SQLException ; import java.sql.PreparedStatement ; import java.io.File ; import java.io.FileInputStream ; import java.io.InputStream ; public class BlobDemo01{ // 定义MySQL的数据库驱动程序 public static final String DBDRIVER = "org.gjt.mm.mysql.Driver" ; // 定义MySQL数据库的连接地址 public static final String DBURL = "jdbc:mysql://localhost:3306/mldn" ; // MySQL数据库的连接用户名 public static final String DBUSER = "root" ; // MySQL数据库的连接密码 public static final String DBPASS = "mysqladmin" ; public static void main(String args[]) throws Exception{ // 所有异常抛出 Connection conn = null ; // 数据库连接 PreparedStatement pstmt = null ; String name = "李兴华" ; String sql = "INSERT INTO userblob(name,photo) VALUES (?,?) " ; Class.forName(DBDRIVER) ; // 加载驱动程序 conn = DriverManager.getConnection(DBURL,DBUSER,DBPASS) ; pstmt = conn.prepareStatement(sql) ; File f = new File("d:" + File.separator + "mldn.gif") ; // 图片文件 InputStream input = null ; input = new FileInputStream(f) ; pstmt.setString(1,name) ; // 设置第一个“?”的内容 pstmt.setBinaryStream(2,input,(int)f.length()) ; // 设置输入流 pstmt.executeUpdate() ; // 更新数据库 pstmt.close() ; conn.close() ; // 数据库关闭 } }; import java.sql.Connection ; import java.sql.DriverManager ; import java.sql.SQLException ; import java.sql.PreparedStatement ; import java.io.File ; import java.io.FileOutputStream ; import java.sql.ResultSet ; import java.io.InputStream ; import java.io.InputStream ; import java.io.OutputStream ; public class BlobDemo02{ // 定义MySQL的数据库驱动程序 public static final String DBDRIVER = "org.gjt.mm.mysql.Driver" ; // 定义MySQL数据库的连接地址 public static final String DBURL = "jdbc:mysql://localhost:3306/mldn" ; // MySQL数据库的连接用户名 public static final String DBUSER = "root" ; // MySQL数据库的连接密码 public static final String DBPASS = "mysqladmin" ; public static void main(String args[]) throws Exception{ // 所有异常抛出 Connection conn = null ; // 数据库连接 PreparedStatement pstmt = null ; ResultSet rs = null ; int id = 1 ; String sql = "SELECT name,photo FROM userblob WHERE id=?" ; Class.forName(DBDRIVER) ; // 加载驱动程序 conn = DriverManager.getConnection(DBURL,DBUSER,DBPASS) ; pstmt = conn.prepareStatement(sql) ; pstmt.setInt(1,id) ; rs = pstmt.executeQuery() ;// 执行查询 if(rs.next()){ String name = rs.getString(1) ; System.out.println("姓名:" + name) ; InputStream input = rs.getBinaryStream(2) ; File f = new File("d:" + File.separator + "loadmldn.gif") ;// 图片文件 OutputStream out = null ; out = new FileOutputStream(f) ; int temp = 0 ; while((temp=input.read())!=-1){ // 边读边写 out.write(temp) ; } input.close() ; out.close() ; } pstmt.close() ; conn.close() ; // 数据库关闭 } }; import java.sql.Connection ; import java.sql.DriverManager ; import java.sql.SQLException ; import java.sql.PreparedStatement ; import java.sql.Blob ; import java.sql.ResultSet ; import java.io.File ; import java.io.FileOutputStream ; import java.io.InputStream ; import java.io.InputStream ; import java.io.OutputStream ; public class BlobDemo03{ // 定义MySQL的数据库驱动程序 public static final String DBDRIVER = "org.gjt.mm.mysql.Driver" ; // 定义MySQL数据库的连接地址 public static final String DBURL = "jdbc:mysql://localhost:3306/mldn" ; // MySQL数据库的连接用户名 public static final String DBUSER = "root" ; // MySQL数据库的连接密码 public static final String DBPASS = "mysqladmin" ; public static void main(String args[]) throws Exception{ // 所有异常抛出 Connection conn = null ; // 数据库连接 PreparedStatement pstmt = null ; ResultSet rs = null ; int id = 1 ; String sql = "SELECT name,photo FROM userblob WHERE id=?" ; Class.forName(DBDRIVER) ; // 加载驱动程序 conn = DriverManager.getConnection(DBURL,DBUSER,DBPASS) ; pstmt = conn.prepareStatement(sql) ; pstmt.setInt(1,id) ; rs = pstmt.executeQuery() ;// 执行查询 if(rs.next()){ String name = rs.getString(1) ; System.out.println("姓名:" + name) ; Blob b = rs.getBlob(2) ; File f = new File("d:" + File.separator + "loadmldn.gif") ;// 图片文件 OutputStream out = null ; out = new FileOutputStream(f) ; out.write(b.getBytes(1,(int)b.length())) ; out.close() ; } pstmt.close() ; conn.close() ; // 数据库关闭 } };
处理二进制文件,图片、声音、视频、文本
元数据
DatabaseMetaData
import java.sql.Connection ; import java.sql.DriverManager ; import java.sql.SQLException ; import java.sql.DatabaseMetaData ; import java.sql.ResultSet ; public class DatabaseMetaDataDemo{ // 定义MySQL的数据库驱动程序 public static final String DBDRIVER = "org.gjt.mm.mysql.Driver" ; // 定义MySQL数据库的连接地址 public static final String DBURL = "jdbc:mysql://localhost:3306/mldn" ; // MySQL数据库的连接用户名 public static final String DBUSER = "root" ; // MySQL数据库的连接密码 public static final String DBPASS = "mysqladmin" ; public static void main(String args[]) throws Exception{ // 所有异常抛出 Connection conn = null ; // 数据库连接 DatabaseMetaData dmd = null ; // 数据库元数据 ResultSet rs = null ; Class.forName(DBDRIVER) ; // 加载驱动程序 conn = DriverManager.getConnection(DBURL,DBUSER,DBPASS) ; dmd = conn.getMetaData() ; // 实例化对象 System.out.println("数据库名称:" + dmd.getDatabaseProductName() ) ; System.out.println("数据库版本:" + dmd.getDatabaseMajorVersion() + "." + dmd.getDatabaseMinorVersion()) ; rs = dmd.getPrimaryKeys(null,null,"user") ; // 取得user表的主键 while(rs.next()){ System.out.println("表类别:" + rs.getString(1)) ; System.out.println("表模式:" + rs.getString(2)) ; System.out.println("表名称:" + rs.getString(3)) ; System.out.println("列名称:" + rs.getString(4)) ; System.out.println("主键序列号:" + rs.getString(5)) ; System.out.println("主键名称:" + rs.getString(6)) ; } conn.close() ; // 数据库关闭 } };
ResultSetMetaData
import java.sql.Connection ; import java.sql.DriverManager ; import java.sql.SQLException ; import java.sql.ResultSetMetaData ; import java.sql.PreparedStatement ; public class ResultSetMetaDataDemo{ // 定义MySQL的数据库驱动程序 public static final String DBDRIVER = "org.gjt.mm.mysql.Driver" ; // 定义MySQL数据库的连接地址 public static final String DBURL = "jdbc:mysql://localhost:3306/mldn" ; // MySQL数据库的连接用户名 public static final String DBUSER = "root" ; // MySQL数据库的连接密码 public static final String DBPASS = "mysqladmin" ; public static void main(String args[]) throws Exception{ // 所有异常抛出 Connection conn = null ; // 数据库连接 ResultSetMetaData rsmd = null ; // 数据库元数据 PreparedStatement pstmt = null ; Class.forName(DBDRIVER) ; // 加载驱动程序 conn = DriverManager.getConnection(DBURL,DBUSER,DBPASS) ; String sql = "SELECT id,name,password,age,sex,birthday FROM user" ; pstmt = conn.prepareStatement(sql) ; // 实例化对象 rsmd = pstmt.getMetaData() ; System.out.println("一共返回" + rsmd.getColumnCount() + "条数据。") ; if(rsmd.isAutoIncrement(1) ){ System.out.println(rsmd.getColumnName(1)+"列是自动增长的。") ; } conn.close() ; // 数据库关闭 } };
集合类框架
Collection接口
List(有序可重复的)
²List接口:线性数据结构(只有一个前驱结点和一个后继结点):遍历下标
ArrayList,Vector,LinkedList的存储性能和特性: ArrayList和Vector都是使用数组方式存储数据,此数组元素数大于实际存储的数据以便增加和插入元素, 它们都允许直接按序号索引元素,但是插入元素要涉及数组元素移动等内存操作,所以索引数据快而插入数据慢, Vector由于使用了synchronized方法(线程安全),通常性能上较ArrayList差,而LinkedList使用双向链表实现存储, 按序号索引数据需要进行前向或后向遍历,但是插入数据时只需要记录本项的前后项即可,所以插入速度较快。
ArrayList(数组形式存取)
package com.data; import java.util.ArrayList; import java.util.Iterator; importjava.util.List; publicclass ArrayApp { publicstaticvoid main(String args[]){ ArrayList list = newArrayList(); System.out.println("集合是否为空:"+list.isEmpty()); list.add("my"); list.add("name"); list.add("is "); list.add("lihaoran"); list.add("lihaoran"); System.out.println("iterator遍历:"); Iterator iter = list.iterator(); while (iter.hasNext()) { System.out.print(iter.next()+"\t"); } System.out.println(); System.out.println("由前向后输出"); for(int i=0;i System.out.print(list.get(i)+"\t"); } System.out.println(""); System.out.println("由后向前输出:"); for (int i =list.size()-1; i >=0; i--) { System.out.print(list.get(i)+"\t"); } System.out.println(""); System.out.println("以数组的形式输出"); String[] str=(String[]) list.toArray(new String[]{}); for (int i = 0; i length; i++) { System.out.print(str[i]+"\t"); } System.out.println(""); System.out.println("指定对象数组:"); Object[] obj = list.toArray(); for (int i = 0; i length; i++) { String s =(String)obj[i]; System.out.print(s+"\t"); } System.out.println(); System.out.println("lihaoran的位置:"+list.lastIndexOf("lihaoran")); System.out.println(list.contains("lihaoran")?"存在":"不存在"); System.out.println("集合是否为空:"+list.isEmpty()); } }
底层数组实现的,当实例化一个ArrayList是也相当实例化了一个数组 所以对元素的随即访问较快,而增加删除操作慢
ArrayList与Vector区别: ArrayList采用异步处理性能高,非线程安全 Vector采用同步处理性能低,线程安全
Vector(数组形式存取)
package com.data; import java.util.ArrayList; import java.util.Iterator; importjava.util.List; publicclass ArrayApp { publicstaticvoid main(String args[]){ Vector list = new Vector(); System.out.println("集合是否为空:"+list.isEmpty()); list.add("my"); list.add("name"); list.add("is "); list.add("lihaoran"); list.add("lihaoran"); System.out.println("iterator遍历:"); Iterator iter = list.iterator(); while (iter.hasNext()) { System.out.print(iter.next()+"\t"); } System.out.println(); System.out.println("由前向后输出"); for(int i=0;i System.out.print(list.get(i)+"\t"); } System.out.println(""); System.out.println("由后向前输出:"); for (int i =list.size()-1; i >=0; i--) { System.out.print(list.get(i)+"\t"); } System.out.println(""); System.out.println("以数组的形式输出"); String[] str=(String[]) list.toArray(new String[]{}); for (int i = 0; i length; i++) { System.out.print(str[i]+"\t"); } System.out.println(""); System.out.println("指定对象数组:"); Object[] obj = list.toArray(); for (int i = 0; i length; i++) { String s =(String)obj[i]; System.out.print(s+"\t"); } System.out.println(); System.out.println("lihaoran的位置:"+list.lastIndexOf("lihaoran")); System.out.println(list.contains("lihaoran")?"存在":"不存在"); System.out.println("集合是否为空:"+list.isEmpty()); } }
LinkList(链表形式存取)
import java.util.ArrayList ; import java.util.List ; import java.util.ListIterator ; public class ListIteratorDemo01{ public static void main(String argsp[]){ List all = new ArrayList() ; all.add("hello") ; all.add("_") ; all.add("world") ; ListIterator iter = all.listIterator() ; System.out.print("由前向后输出:") ; while(iter.hasNext()){ String str = iter.next() ; System.out.print(str + "、") ; } System.out.print("\n由后向前输出:") ; while(iter.hasPrevious()){ String str = iter.previous() ; System.out.print(str + "、") ; } } }; import java.util.ArrayList ; import java.util.List ; import java.util.ListIterator ; public class ListIteratorDemo02{ public static void main(String argsp[]){ List all = new ArrayList() ; all.add("hello") ; all.add("_") ; all.add("world") ; ListIterator iter = all.listIterator() ; System.out.print("由前向后输出:") ; while(iter.hasNext()){ String str = iter.next() ; System.out.print(str + "、") ; iter.set("LI - " + str) ; // 修改内容 } System.out.print("\n由后向前输出:") ; iter.add("LXH"); while(iter.hasPrevious()){ String str = iter.previous() ; System.out.print(str + "、") ; } } };
LinkedList 底层实现是一个双向链表,每一个结点都包含了前一个元素的引用和后一个元素的引用和结点值 所以对元素的随即访问很慢,而增删较快
Set(无序不可重复的)
²Set:无序今集;采用的是哈希算法:遍历的对象
HashSet(散列存取)
import java.util.HashSet ; import java.util.Set ; public class HashSetDemo01{ public static void main(String args[]){ Set allSet = new HashSet() ; allSet.add("A") ;// 增加内容 allSet.add("B") ;// 增加内容 allSet.add("C") ;// 增加内容 allSet.add("C") ;// 重复内容 allSet.add("C") ;// 重复内容 allSet.add("D") ;// 增加内容 allSet.add("E") ;// 增加内容 System.out.println(allSet) ; } };
hashCode()和equals()完成重复元素的判断
TreeSet(有序存取)
import java.util.TreeSet ; import java.util.Set ; public class TreeSetDemo01{ public static void main(String args[]){ Set allSet = new TreeSet() ; allSet.add("C") ;// 增加内容 allSet.add("C") ;// 重复内容 allSet.add("C") ;// 重复内容 allSet.add("D") ;// 增加内容 allSet.add("B") ;// 增加内容 allSet.add("A") ;// 增加内容 allSet.add("E") ;// 增加内容 System.out.println(allSet) ; } };
依靠Comparable接口完成排序
SortedSet
import java.util.SortedSet ; import java.util.TreeSet ; public class TreeSetDemo05{ public static void main(String args[]){ SortedSet allSet = new TreeSet() ; // allSet.add("A") ;// 增加内容 allSet.add("B") ;// 增加内容 allSet.add("C") ;// 增加内容 allSet.add("C") ;// 增加内容 allSet.add("C") ;// 增加内容 allSet.add("D") ;// 增加内容 allSet.add("E") ;// 增加内容 System.out.println("第一个元素:" + allSet.first()) ; System.out.println("最后一个元素:" + allSet.last()) ; System.out.println("headSet元素:" + allSet.headSet("C")) ; System.out.println("tailSet元素:" + allSet.tailSet("C")) ; System.out.println("subSet元素:" + allSet.subSet("B","D")) ; } };
排序
Map接口
HashMap
import java.util.HashMap ; import java.util.Map ; public class HashMapDemo01{ public static void main(String args[]){ Map map = null; // 声明Map对象,其中key和value的类型为String map = new HashMap() ; map.put("mldn","www.mldn.cn") ; // 增加内容 map.put("zhinangtuan","www.zhinangtuan.net.cn") ;// 增加内容 map.put("mldnjava","www.mldnjava.cn") ; // 增加内容 String val = map.get("mldn") ; // 根据key取出值 System.out.println("取出的内容是:" + val) ; } }; import java.util.HashMap ; import java.util.Map ; public class HashMapDemo02{ public static void main(String args[]){ Map map = null; // 声明Map对象,其中key和value的类型为String map = new HashMap() ; map.put("mldn","www.mldn.cn") ; // 增加内容 map.put("zhinangtuan","www.zhinangtuan.net.cn") ;// 增加内容 map.put("mldnjava","www.mldnjava.cn") ; // 增加内容 if(map.containsKey("mldn")){ // 判断key是否存在 System.out.println("搜索的key存在!") ; }else{ System.out.println("搜索的key不存在!") ; } if(map.containsValue("www.mldn.cn")){ // 判断value是否存在 System.out.println("搜索的value存在!") ; }else{ System.out.println("搜索的value不存在!") ; } } }; import java.util.HashMap ; import java.util.Map ; import java.util.Iterator ; import java.util.Set ; public class HashMapDemo03{ public static void main(String args[]){ Map map = null; // 声明Map对象,其中key和value的类型为String map = new HashMap() ; map.put("mldn","www.mldn.cn") ; // 增加内容 map.put("zhinangtuan","www.zhinangtuan.net.cn") ;// 增加内容 map.put("mldnjava","www.mldnjava.cn") ; // 增加内容 Set keys = map.keySet() ; // 得到全部的key Iterator iter = keys.iterator() ; while(iter.hasNext()){ String str = iter.next() ; System.out.print(str + "、") ; } } }; import java.util.HashMap ; import java.util.Map ; import java.util.Iterator ; import java.util.Collection ; public class HashMapDemo04{ public static void main(String args[]){ Map map = null; // 声明Map对象,其中key和value的类型为String map = new HashMap() ; map.put("mldn","www.mldn.cn") ; // 增加内容 map.put("zhinangtuan","www.zhinangtuan.net.cn") ;// 增加内容 map.put("mldnjava","www.mldnjava.cn") ; // 增加内容 Collection values = map.values() ; // 得到全部的value Iterator iter = values.iterator() ; while(iter.hasNext()){ String str = iter.next() ; System.out.print(str + "、") ; } } };
HashMap和Hashtable的区别 一.历史原因:Hashtable是基于陈旧的Dictionary类的,HashMap是Java1.2引进的Map接口的一个实现 二.同步性:Hashtable是线程安全的,也就是说是同步的,而HashMap是线程序不安全的,不是同步的 三.值:只有HashMap可以让你将空值作为一个表的条目的key或value
HashTable
import java.util.HashMap ; import java.util.Map ; import java.util.Set ; import java.util.Iterator ; import java.util.Collection ; public class HashtableDemo01{ public static void main(String args[]){ Map map = null; // 声明Map对象,其中key和value的类型为String map = new HashMap() ; map.put("mldn","www.mldn.cn") ; // 增加内容 map.put("zhinangtuan","www.zhinangtuan.net.cn") ;// 增加内容 map.put("mldnjava","www.mldnjava.cn") ; // 增加内容 System.out.print("全部的key:") ; Set keys = map.keySet() ; // 得到全部的key Iterator iter = keys.iterator() ; while(iter.hasNext()){ String str = iter.next() ; System.out.print(str + "、") ; } System.out.print("\n全部的value:") ; Collection values = map.values() ; // 得到全部的value Iterator iter2 = values.iterator() ; while(iter2.hasNext()){ String str = iter2.next() ; System.out.print(str + "、") ; } } };
TreeMap
import java.util.TreeMap ; import java.util.Map ; import java.util.Set ; import java.util.Iterator ; import java.util.Collection ; public class TreeMapDemo01{ public static void main(String args[]){ Map map = null; // 声明Map对象,其中key和value的类型为String map = new TreeMap() ; map.put("A、mldn","www.mldn.cn") ; // 增加内容 map.put("C、zhinangtuan","www.zhinangtuan.net.cn") ; // 增加内容 map.put("B、mldnjava","www.mldnjava.cn") ;// 增加内容 Set keys = map.keySet() ; // 得到全部的key Iterator iter = keys.iterator() ; while(iter.hasNext()){ String str = iter.next() ; System.out.println(str + " --> " + map.get(str)) ; // 取出内容 } } };
SortedMap
Collections接口(集合类的帮助类)
Collections是针对集合类的一个帮助类,他提供一系列静态方法实现对各种集合的搜索、排序、线程安全化等操作
sort排序
import java.util.Collections ; import java.util.List ; import java.util.ArrayList ; import java.util.Iterator ; public class CollectionsDemo06{ public static void main(String args[]){ List all = new ArrayList() ; // 返回空的 List集合 Collections.addAll(all,"1、MLDN","2、LXH","3、mldnjava") ; Collections.addAll(all,"B、www.mldn.cn") ; Collections.addAll(all,"A、www.mldnjava.cn") ; System.out.println("排序之前的集合:" + all) ; Collections.sort(all) ; System.out.println("排序之后的集合:" + all) ; } };
binarySearch查找
I/O 流 操 作
数据类型划分
字节流
import java.io.* ; public class Copy{ public static void main(String args[]){ if(args.length!=2){ // 判断是否是两个参数 System.out.println("输入的参数不正确。") ; System.out.println("例:java Copy 源文件路径 目标文件路径") ; System.exit(1) ; // 系统退出 } File f1 = new File(args[0]) ; // 源文件的File对象 File f2 = new File(args[1]) ; // 目标文件的File对象 if(!f1.exists()){ System.out.println("源文件不存在!") ; System.exit(1) ; } InputStream input = null ; // 准备好输入流对象,读取源文件 OutputStream out = null ; // 准备好输出流对象,写入目标文件 try{ input = new FileInputStream(f1) ; }catch(FileNotFoundException e){ e.printStackTrace() ; } try{ out = new FileOutputStream(f2) ; }catch(FileNotFoundException e){ e.printStackTrace() ; } if(input!=null && out!=null){ // 判断输入或输出是否准备好 int temp = 0 ; try{ while((temp=input.read())!=-1){ // 开始拷贝 out.write(temp) ;// 边读边写 } System.out.println("拷贝完成!") ; }catch(IOException e){ e.printStackTrace() ; System.out.println("拷贝失败!") ; } try{ input.close() ; // 关闭 out.close() ; // 关闭 }catch(IOException e){ e.printStackTrace() ; } } } }
字节流直接操作的是文件,(图片,字节等形式)
OutPutStream输出流/写流(所把数据写入到文件中)
FileOutPutStream
package com.io; import java.io.File; importjava.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.OutputStream; publicclass FileOutputStreamDemo1 { publicstaticvoid main(String[] args) throws Exception { File f = new File("D:"+File.separator+"hello.doc"); //new FileOutputStream(f,true); 设置true在后面缀加 OutputStream os = new FileOutputStream(f,true); String str="hello world lihaoran"; byte[] b = str.getBytes(); for (int i = 0; i length; i++) { os.write(b[i]); } //os.write(b); os.close(); } }
write()
InputStream输入流(从文件中往出读数据)
FileInputStream
package com.io; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.InputStream; public class FileInputStreamDemo { public static void main(String[] args) throws Exception { File f = new File("D:"+File.separator+"hello.doc"); InputStream is = new FileInputStream(f); byte[] b = new byte[is.available()]; int temp=0; int len=0; while((temp=is.read())!=-1){ b[len]=(byte)temp; len++; } System.out.print(new String(b)); is.close(); } } package com.io; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.InputStream; public class FileInputStreamDemo { public static void main(String[] args) throws Exception { File f = new File("D:"+File.separator+"hello.doc"); InputStream is = new FileInputStream(f); byte[] b = new byte[is.available()]; is.read(b); System.out.print(new String(b)); is.close(); } }
available
read
字符流
字符流:数据先存放在缓存之后,再从缓存中写入文件 (字符形式)
Writer输出流/写流(所把数据写入到文件中)
FileWriter
package com.io; import java.io.File; import java.io.FileWriter; import java.io.Writer; publicclass WriterDemo { publicstaticvoid main(String[] args) throws Exception { File f = new File("D:"+File.separator+"hello.doc"); //true缀加 Writer wr = new FileWriter(f,true); String str="liharoan hello world"; wr.write(str); wr.close(); } }
write
Reader输入流(从文件中往出读数据)
FileReader
package com.io; import java.io.File; import java.io.FileReader; import java.io.Reader; publicclass ReaderDemo { publicstaticvoid main(String[] args) throws Exception { File f = new File("D:"+File.separator+"hello.doc"); //true缀加 Reader r = new FileReader(f); char[] b = newchar[(int) f.length()]; for(int i=0;ilength;i++){ r.read(b); } System.out.println(new String(b)); r.close(); } } package com.io; import java.io.File; import java.io.FileReader; import java.io.Reader; publicclass ReaderDemo { publicstaticvoid main(String[] args) throws Exception { File f = new File("D:"+File.separator+"hello.doc"); //true缀加 Reader r = new FileReader(f); char[] b = newchar[(int) f.length()]; /*for(int i=0;i r.read(b); } System.out.println(new String(b));*/ int temp=0; int len=0; while((temp=r.read())!=-1){ b[len]=(char)temp; len++; } System.out.println(new String(b)); r.close(); } }
read
其它流的类型
转换流
OutputStreamWriter
import java.io.* ; public class OutputStreamWriterDemo01{ public static void main(String args[]) throws Exception { // 所有异常抛出 File f = new File("d:" + File.separator + "test.txt") ; Writer out = null ; // 字符输出流 out = new OutputStreamWriter(new FileOutputStream(f)) ; // 字节流变为字符流 out.write("hello world!!") ; // 使用字符流输出 out.close() ; } };
将字节流转换成字符流写入到文件中
InputStreamReader
import java.io.* ; public class InputStreamReaderDemo01{ public static void main(String args[]) throws Exception{ File f = new File("d:" + File.separator + "test.txt") ; Reader reader = null ; reader = new InputStreamReader(new FileInputStream(f)) ; // 将字节流变为字符流 char c[] = new char[1024] ; int len = reader.read(c) ; // 读取 reader.close() ; // 关闭 System.out.println(new String(c,0,len)) ; } };
将字节流变为字符流读取文件内容
内存流
import java.io.* ; public class ByteArrayDemo01{ public static void main(String args[]){ String str = "HELLOWORLD" ; // 定义一个字符串,全部由大写字母组成 ByteArrayInputStream bis = null ; // 内存输入流 ByteArrayOutputStream bos = null ; // 内存输出流 bis = new ByteArrayInputStream(str.getBytes()) ; // 向内存中输出内容 bos = new ByteArrayOutputStream() ; // 准备从内存ByteArrayInputStream中读取内容 int temp = 0 ; while((temp=bis.read())!=-1){ char c = (char) temp ;// 读取的数字变为字符 bos.write(Character.toLowerCase(c)) ; // 将字符变为小写 } // 所有的数据就全部都在ByteArrayOutputStream中 String newStr = bos.toString() ; // 取出内容 try{ bis.close() ; bos.close() ; }catch(IOException e){ e.printStackTrace() ; } System.out.println(newStr) ; } };
打印流
import java.io.* ; public class PrintDemo03{ public static void main(String arg[]) throws Exception{ PrintStream ps = null ; // 声明打印流对象 // 如果现在是使用FileOuputStream实例化,意味着所有的输出是向文件之中 ps = new PrintStream(new FileOutputStream(new File("d:" + File.separator + "test.txt"))) ; String name = "李兴华" ; // 定义字符串 int age = 30 ; // 定义整数 float score = 990.356f ; // 定义小数 char sex = 'M' ; // 定义字符 ps.printf("姓名:%s;年龄:%s;成绩:%s;性别:%s",name,age,score,sex) ; ps.close() ; } };
管道流
import java.io.* ; class Send implements Runnable{ // 线程类 private PipedOutputStream pos = null ; // 管道输出流 public Send(){ this.pos = new PipedOutputStream() ; // 实例化输出流 } public void run(){ String str = "Hello World!!!" ; // 要输出的内容 try{ this.pos.write(str.getBytes()) ; }catch(IOException e){ e.printStackTrace() ; } try{ this.pos.close() ; }catch(IOException e){ e.printStackTrace() ; } } public PipedOutputStream getPos(){ // 得到此线程的管道输出流 return this.pos ; } }; class Receive implements Runnable{ private PipedInputStream pis = null ;// 管道输入流 public Receive(){ this.pis = new PipedInputStream() ; // 实例化输入流 } public void run(){ byte b[] = new byte[1024] ;// 接收内容 int len = 0 ; try{ len = this.pis.read(b) ; // 读取内容 }catch(IOException e){ e.printStackTrace() ; } try{ this.pis.close() ; // 关闭 }catch(IOException e){ e.printStackTrace() ; } System.out.println("接收的内容为:" + new String(b,0,len)) ; } public PipedInputStream getPis(){ return this.pis ; } }; public class PipedDemo{ public static void main(String args[]){ Send s = new Send() ; Receive r = new Receive() ; try{ s.getPos().connect(r.getPis()) ;// 连接管道 }catch(IOException e){ e.printStackTrace() ; } new Thread(s).start() ; // 启动线程 new Thread(r).start() ; // 启动线程 } };
BufferedReader
import java.io.* ; public class BufferedReaderDemo01{ public static void main(String args[]){ BufferedReader buf = null ; // 声明对象 buf = new BufferedReader(new InputStreamReader(System.in)) ; // 将字节流变为字符流 String str = null ; // 接收输入内容 System.out.print("请输入内容:") ; try{ str = buf.readLine() ;// 读取一行数据 }catch(IOException e){ e.printStackTrace() ; // 输出信息 } System.out.println("输入的内容为:" + str) ; } };
Scanner
import java.util.* ; import java.text.* ; import java.io.* ; public class ScannerDemo05{ public static void main(String args[]){ File f = new File("D:" + File.separator + "test.txt") ; // 指定操作文件 Scanner scan = null ; try{ scan = new Scanner(f) ; // 从键盘接收数据 }catch(Exception e){} StringBuffer str = new StringBuffer() ; while(scan.hasNext()){ str.append(scan.next()).append('\n') ; // 取数据 } System.out.println("文件内容为:" + str) ; } };
数据操作流
DataInputStream
import java.io.DataInputStream ; import java.io.File ; import java.io.FileInputStream ; public class DataInputStreamDemo{ public static void main(String args[]) throws Exception{ // 所有异常抛出 DataInputStream dis = null ; // 声明数据输入流对象 File f = new File("d:" + File.separator + "order.txt") ; // 文件的保存路径 dis = new DataInputStream(new FileInputStream(f)) ; // 实例化数据输入流对象 String name = null ; // 接收名称 float price = 0.0f ; // 接收价格 int num = 0 ; // 接收数量 char temp[] = null ; // 接收商品名称 int len = 0 ; // 保存读取数据的个数 char c = 0 ;// '\u0000' try{ while(true){ temp = new char[200] ;// 开辟空间 len = 0 ; while((c=dis.readChar())!='\t'){// 接收内容 temp[len] = c ; len ++ ; // 读取长度加1 } name = new String(temp,0,len) ; // 将字符数组变为String price = dis.readFloat() ; // 读取价格 dis.readChar() ; // 读取\t num = dis.readInt() ; // 读取int dis.readChar() ; // 读取\n System.out.printf("名称:%s;价格:%5.2f;数量:%d\n",name,price,num) ; } }catch(Exception e){} dis.close() ; } };
DataOutputStream
import java.io.DataOutputStream ; import java.io.File ; import java.io.FileOutputStream ; public class DataOutputStreamDemo{ public static void main(String args[]) throws Exception{ // 所有异常抛出 DataOutputStream dos = null ; // 声明数据输出流对象 File f = new File("d:" + File.separator + "order.txt") ; // 文件的保存路径 dos = new DataOutputStream(new FileOutputStream(f)) ; // 实例化数据输出流对象 String names[] = {"衬衣","手套","围巾"} ; // 商品名称 float prices[] = {98.3f,30.3f,50.5f} ; // 商品价格 int nums[] = {3,2,1} ;// 商品数量 for(int i=0;i dos.writeChars(names[i]) ; // 写入字符串 dos.writeChar('\t') ; // 写入分隔符 dos.writeFloat(prices[i]) ; // 写入价格 dos.writeChar('\t') ; // 写入分隔符 dos.writeInt(nums[i]) ; // 写入数量 dos.writeChar('\n') ; // 换行 } dos.close() ; // 关闭输出流 } };
合并流
import java.io.File ; import java.io.SequenceInputStream ; import java.io.FileInputStream ; import java.io.InputStream ; import java.io.FileOutputStream ; import java.io.OutputStream ; public class SequenceDemo{ public static void main(String args[]) throws Exception { // 所有异常抛出 InputStream is1 = null ; // 输入流1 InputStream is2 = null ; // 输入流1 OutputStream os = null ; // 输出流 SequenceInputStream sis = null ; // 合并流 is1 = new FileInputStream("d:" + File.separator + "a.txt") ; is2 = new FileInputStream("d:" + File.separator + "b.txt") ; os = new FileOutputStream("d:" + File.separator + "ab.txt") ; sis = new SequenceInputStream(is1,is2) ; // 实例化合并流 int temp = 0 ; // 接收内容 while((temp=sis.read())!=-1){ // 循环输出 os.write(temp) ; // 保存内容 } sis.close() ; // 关闭合并流 is1.close() ; // 关闭输入流1` is2.close() ; // 关闭输入流2 os.close() ;// 关闭输出流 } };
压缩流
ZipInputStream
import java.io.File ; import java.io.OutputStream ; import java.io.InputStream ; import java.util.zip.ZipEntry ; import java.util.zip.ZipFile ; import java.util.zip.ZipInputStream ; import java.io.FileInputStream ; import java.io.FileOutputStream ; public class ZipInputStreamDemo02{ public static void main(String args[]) throws Exception{ // 所有异常抛出 File file = new File("d:" + File.separator + "mldndir.zip") ; // 定义压缩文件名称 File outFile = null ; // 输出文件的时候要有文件夹的操作 ZipFile zipFile = new ZipFile(file) ; // 实例化ZipFile对象 ZipInputStream zipInput = null ; // 定义压缩输入流 OutputStream out = null ; // 定义输出流,用于输出每一个实体内容 InputStream input = null ; // 定义输入流,读取每一个ZipEntry ZipEntry entry = null ; // 每一个压缩实体 zipInput = new ZipInputStream(new FileInputStream(file)) ; // 实例化ZIpInputStream while((entry = zipInput.getNextEntry())!=null){ // 得到一个压缩实体 System.out.println("解压缩" + entry.getName() + "文件。") ; outFile = new File("d:" + File.separator + entry.getName()) ; // 定义输出的文件路径 if(!outFile.getParentFile().exists()){ // 如果输出文件夹不存在 outFile.getParentFile().mkdir() ; // 创建文件夹 } if(!outFile.exists()){// 判断输出文件是否存在 outFile.createNewFile() ; // 创建文件 } input = zipFile.getInputStream(entry) ; // 得到每一个实体的输入流 out = new FileOutputStream(outFile) ; // 实例化文件输出流 int temp = 0 ; while((temp=input.read())!=-1){ out.write(temp) ; } input.close() ; // 关闭输入流 out.close() ; // 关闭输出流 } input.close() ; } };
ZipOutputStream
import java.io.File ; import java.io.FileInputStream ; import java.io.InputStream ; import java.util.zip.ZipEntry ; import java.util.zip.ZipOutputStream ; import java.io.FileOutputStream ; public class ZipOutputStreamDemo02{ public static void main(String args[]) throws Exception{ // 所有异常抛出 File file = new File("d:" + File.separator + "mldn") ;// 定义要压缩的文件夹 File zipFile = new File("d:" + File.separator + "mldndir.zip") ;// 定义压缩文件名称 InputStream input = null ; // 定义文件输入流 ZipOutputStream zipOut = null ; // 声明压缩流对象 zipOut = new ZipOutputStream(new FileOutputStream(zipFile)) ; zipOut.setComment("www.mldnjava.cn") ; // 设置注释 int temp = 0 ; if(file.isDirectory()){ // 判断是否是文件夹 File lists[] = file.listFiles() ; // 列出全部文件 for(int i=0;i input = new FileInputStream(lists[i]) ; // 定义文件的输入流 zipOut.putNextEntry(new ZipEntry(file.getName() +File.separator+lists[i].getName())) ; // 设置ZipEntry对象 while((temp=input.read())!=-1){ // 读取内容 zipOut.write(temp) ; // 压缩输出 } input.close() ; // 关闭输入流 } } zipOut.close() ; // 关闭输出流 } };
回退流
import java.io.ByteArrayInputStream ; import java.io.PushbackInputStream ; public class PushInputStreamDemo{ public static void main(String args[]) throws Exception { // 所有异常抛出 String str = "www.mldnjava.cn" ; // 定义字符串 PushbackInputStream push = null ; // 定义回退流对象 ByteArrayInputStream bai = null ; // 定义内存输入流 bai = new ByteArrayInputStream(str.getBytes()) ; // 实例化内存输入流 push = new PushbackInputStream(bai) ; // 从内存中读取数据 System.out.print("读取之后的数据为:") ; int temp = 0 ; while((temp=push.read())!=-1){ // 读取内容 if(temp=='.'){ // 判断是否读取到了“.” push.unread(temp) ; // 放回到缓冲区之中 temp = push.read() ; // 再读一遍 System.out.print("(退回"+(char)temp+")") ; }else{ System.out.print((char)temp) ; // 输出内容 } } } };
对象序列化
import java.io.Serializable ; public class Person implements Serializable{ private String name ; // 声明name属性,但是此属性不被序列化 private int age ; // 声明age属性 public Person(String name,int age){ // 通过构造设置内容 this.name = name ; this.age = age ; } public String toString(){ // 覆写toString()方法 return "姓名:" + this.name + ";年龄:" + this.age ; } }; import java.io.File ; import java.io.IOException ; import java.io.FileOutputStream ; import java.io.OutputStream ; import java.io.ObjectOutputStream ; import java.io.FileInputStream ; import java.io.InputStream ; import java.io.ObjectInputStream ; public class SerDemo05{ public static void main(String args[]) throws Exception{ Person per[] = {new Person("张三",30),new Person("李四",31), new Person("王五",32)} ; ser(per) ; Object o[] = (Object[])dser() ; for(int i=0;i Person p = (Person)o[i] ; System.out.println(p) ; } } public static void ser(Object obj[]) throws Exception { File f = new File("D:" + File.separator + "test.txt") ; // 定义保存路径 ObjectOutputStream oos = null ; // 声明对象输出流 OutputStream out = new FileOutputStream(f) ; // 文件输出流 oos = new ObjectOutputStream(out) ; oos.writeObject(obj) ;// 保存对象 oos.close() ; // 关闭 } public static Object[] dser() throws Exception { File f = new File("D:" + File.separator + "test.txt") ; // 定义保存路径 ObjectInputStream ois = null ; // 声明对象输入流 InputStream input = new FileInputStream(f) ; // 文件输入流 ois = new ObjectInputStream(input) ; // 实例化对象输入流 Object obj[] = (Object[])ois.readObject() ; // 读取对象 ois.close() ; // 关闭 return obj ; } };
对象序列化定义
对象序列化:就是把一个对象变为二进制的数据的一种方法,通过对象序列化可以方便的实现对象的传输或传输 如果一个类的对象想被序列化,则对象所在的类必须实现java.io.serializable接口,此接口定义如下: publicinterfaceSerializable(){}
对象序列化和对象反序列化
ObjectOutputStream(写入)序列化
writeObject
import java.io.File ; import java.io.FileOutputStream ; import java.io.OutputStream ; import java.io.ObjectOutputStream ; public class SerDemo01{ public static void main(String args[]) throws Exception { File f = new File("D:" + File.separator + "test.txt") ; // 定义保存路径 ObjectOutputStream oos = null ; // 声明对象输出流 OutputStream out = new FileOutputStream(f) ; // 文件输出流 oos = new ObjectOutputStream(out) ; oos.writeObject(new Person("张三",30)) ; // 保存对象 oos.close() ; // 关闭 } };
ObjectInputStream(读出)反序列化
readObject
import java.io.File ; import java.io.FileInputStream ; import java.io.InputStream ; import java.io.ObjectInputStream ; public class SerDemo02{ public static void main(String args[]) throws Exception { File f = new File("D:" + File.separator + "test.txt") ; // 定义保存路径 ObjectInputStream ois = null ; // 声明对象输入流 InputStream input = new FileInputStream(f) ; // 文件输入流 ois = new ObjectInputStream(input) ; // 实例化对象输入流 Object obj = ois.readObject() ; // 读取对象 ois.close() ; // 关闭 System.out.println(obj) ; } };
Tranisent
不参与序列化过程 注意:多个对象,必须在一次序列化的过程中完成
File文件
package com.io; import java.io.File ; import java.io.IOException ; public class FileDemo02{ public static void main(String args[]){ File f = new File("D:"+File.separator); print(f); } public static void print(File f){ if(f!=null){ if(f.isDirectory()){ File[] dir = f.listFiles(); if(dir!=null){ for(int i=0;i print(dir[i]); } } } else{ System.out.println(f.getPath()); } } } };
创建文件
package com.io; import java.io.File ; import java.io.IOException ; public class FileDemo01{ public static void main(String args[]){ File dir = new File("d:"+File.separator+"md"); File f = new File("d:"+File.separator+"md"+File.separator+"test.txt") ; // 实例化File类的对象 if(f.exists()){ f.delete(); } if(dir.exists()){ dir.delete(); System.out.println("删除"); }else{ dir.mkdir(); System.out.println("新建"); if(f.exists()){ try{ f.delete(); }catch(Exception e){ e.printStackTrace() ; // 输出异常信息 } }else{ try { f.createNewFile() ; } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } // 创建文件,根据给定的路径创建 } } } };
separator(windows/linux分割符)
createNewFile() 创建文件
delete()删除文件
f.exists()判断文是否存在
list()遍历文件名
package com.io; import java.io.File ; import java.io.IOException ; public class FileDemo02{ public static void main(String args[]){ File dir = new File("d:"+File.separator); String[] str=dir.list(); for (int i = 0; i System.out.println(str[i]); } } };
listFiles()完整路径
package com.io; import java.io.File ; import java.io.IOException ; public class FileDemo02{ public static void main(String args[]){ File dir = new File("d:"+File.separator); File[] str=dir.listFiles(); for (int i = 0; i System.out.println(str[i]); } } };
isDirectory()判断是否是目录
package com.io; import java.io.File ; import java.io.IOException ; public class FileDemo02{ public static void main(String args[]){ File dir = new File("d:"+File.separator); if(dir.isDirectory()){ System.out.println(dir.getPath()+"是目录"); }else{ System.out.println(dir.getPath()+"不是目录"); } } };
创建文件夹
数据传输方向划分
输出流
OutPutStream输出流/写流(所把数据写入到文件中)
FileOutPutStream
package com.io; import java.io.File; importjava.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.OutputStream; publicclass FileOutputStreamDemo1 { publicstaticvoid main(String[] args) throws Exception { File f = new File("D:"+File.separator+"hello.doc"); //new FileOutputStream(f,true); 设置true在后面缀加 OutputStream os = new FileOutputStream(f,true); String str="hello world lihaoran"; byte[] b = str.getBytes(); for (int i = 0; i length; i++) { os.write(b[i]); } //os.write(b); os.close(); } }
write()
Writer输出流/写流(所把数据写入到文件中)
FileWriter
package com.io; import java.io.File; import java.io.FileWriter; import java.io.Writer; publicclass WriterDemo { publicstaticvoid main(String[] args) throws Exception { File f = new File("D:"+File.separator+"hello.doc"); //true缀加 Writer wr = new FileWriter(f,true); String str="liharoan hello world"; wr.write(str); wr.close(); } }
write
输入流
InputStream输入流(从文件中往出读数据)
FileInputStream
package com.io; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.InputStream; public class FileInputStreamDemo { public static void main(String[] args) throws Exception { File f = new File("D:"+File.separator+"hello.doc"); InputStream is = new FileInputStream(f); byte[] b = new byte[is.available()]; int temp=0; int len=0; while((temp=is.read())!=-1){ b[len]=(byte)temp; len++; } System.out.print(new String(b)); is.close(); } } package com.io; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.InputStream; public class FileInputStreamDemo { public static void main(String[] args) throws Exception { File f = new File("D:"+File.separator+"hello.doc"); InputStream is = new FileInputStream(f); byte[] b = new byte[is.available()]; is.read(b); System.out.print(new String(b)); is.close(); } }
available
read
Reader输入流(从文件中往出读数据)
FileReader
package com.io; import java.io.File; import java.io.FileReader; import java.io.Reader; publicclass ReaderDemo { publicstaticvoid main(String[] args) throws Exception { File f = new File("D:"+File.separator+"hello.doc"); //true缀加 Reader r = new FileReader(f); char[] b = newchar[(int) f.length()]; for(int i=0;ilength;i++){ r.read(b); } System.out.println(new String(b)); r.close(); } } package com.io; import java.io.File; import java.io.FileReader; import java.io.Reader; publicclass ReaderDemo { publicstaticvoid main(String[] args) throws Exception { File f = new File("D:"+File.separator+"hello.doc"); //true缀加 Reader r = new FileReader(f); char[] b = newchar[(int) f.length()]; /*for(int i=0;i r.read(b); } System.out.println(new String(b));*/ int temp=0; int len=0; while((temp=r.read())!=-1){ b[len]=(char)temp; len++; } System.out.println(new String(b)); r.close(); } }
read
多线程
进程与线程定义
进程:进程是程序动态执行过程,它历经从代码加载,执行到完毕的一个完整过程,这个过程也是进程从开始,运行,到消亡的过程 多线程:是实现并发机制的一种有效手段,进程和线程一样都是实现并发的基本单位,一个进程是可以并发执行多个线程。
实现方式
Thread类与Runnable接口区别: runnable适合多个相同程序代码的线程去处理同一个资源 可以避免单线继承局限性 增强程序健壮性,代码能够被多个线程共享,代码与数据的独立性;
继承Thread类
设置三个线程案例 class MyThread extends Thread{ private int time ; public MyThread(String name,int time){ super(name) ; // 设置线程名称 this.time = time ; // 设置休眠时间 } public void run(){ try{ Thread.sleep(this.time) ; // 休眠指定的时间 }catch(InterruptedException e){ e.printStackTrace() ; } System.out.println(Thread.currentThread().getName() + "线程,休眠" + this.time + "毫秒。") ; } }; public class ExecDemo01{ public static void main(String args[]){ MyThread mt1 = new MyThread("线程A",10000) ; // 定义线程对象,指定休眠时间 MyThread mt2 = new MyThread("线程B",20000) ; // 定义线程对象,指定休眠时间 MyThread mt3 = new MyThread("线程C",30000) ; // 定义线程对象,指定休眠时间 mt1.start() ; // 启动线程 mt2.start() ; // 启动线程 mt3.start() ; // 启动线程 } };
Thread-->start()启动线程
Thread-->run()运行
Thread-->interrupt()中断线程
class MyThread implements Runnable{ // 实现Runnable接口 public void run(){ // 覆写run()方法 System.out.println("1、进入run()方法") ; try{ Thread.sleep(10000) ; // 线程休眠10秒 System.out.println("2、已经完成了休眠") ; }catch(InterruptedException e){ System.out.println("3、休眠被终止") ; return ; // 返回调用处 } System.out.println("4、run()方法正常结束") ; } }; public class ThreadInterruptDemo{ public static void main(String args[]){ MyThread mt = new MyThread() ; // 实例化Runnable子类对象 Thread t = new Thread(mt,"线程"); // 实例化Thread对象 t.start() ; // 启动线程 try{ Thread.sleep(2000) ; // 线程休眠2秒 }catch(InterruptedException e){ System.out.println("3、休眠被终止") ; } t.interrupt() ; // 中断线程执行 } };
Thread-->sleep(500):使一个正在运行的线程处于睡眠状态,是一个静态方法,调用此方法要捕捉InterruptedException异常。
class MyThread implements Runnable{ // 实现Runnable接口 public void run(){ // 覆写run()方法 for(int i=0;i try{ Thread.sleep(500) ; // 线程休眠 }catch(InterruptedException e){} System.out.println(Thread.currentThread().getName() + "运行,i = " + i) ; // 取得当前线程的名字 } } }; public class ThreadSleepDemo{ public static void main(String args[]){ MyThread mt = new MyThread() ; // 实例化Runnable子类对象 Thread t = new Thread(mt,"线程"); // 实例化Thread对象 t.start() ; // 启动线程 } };
Object-->wait():使一个线程处于等待状态,并且释放所持有的对象的lock。
Object-->notify():唤醒一个处于等待状态的线程,注意的是在调用此方法的时候,并不能确切的唤醒某一个等待状态的线程, 而是由JVM确定唤醒哪个线程,而且不是按优先级。
Object-->notifyAll():唤醒所有处入等待状态的线程,注意并不是给所有唤醒线程一个对象的锁,而是让它们竞争。
实现Runnable接口
class MyThread implements Runnable{ private String name ; private int time ; public MyThread(String name,int time){ this.name = name ; // 设置线程名称 this.time = time ; // 设置休眠时间 } public void run(){ try{ Thread.sleep(this.time) ; // 休眠指定的时间 }catch(InterruptedException e){ e.printStackTrace() ; } System.out.println(this.name + "线程,休眠" + this.time + "毫秒。") ; } }; public class ExecDemo02{ public static void main(String args[]){ MyThread mt1 = new MyThread("线程A",10000) ; // 定义线程对象,指定休眠时间 MyThread mt2 = new MyThread("线程B",20000) ; // 定义线程对象,指定休眠时间 MyThread mt3 = new MyThread("线程C",30000) ; // 定义线程对象,指定休眠时间 new Thread(mt1).start() ; // 启动线程 new Thread(mt2).start() ; // 启动线程 new Thread(mt3).start() ; // 启动线程 } };
生产者与消费者案例
class Info{ // 定义信息类 private String name = "李兴华"; // 定义name属性 private String content = "JAVA讲师" ; // 定义content属性 private boolean flag = false ; // 设置标志位 public synchronized void set(String name,String content){ if(!flag){ try{ super.wait() ; }catch(InterruptedException e){ e.printStackTrace() ; } } this.setName(name) ; // 设置名称 try{ Thread.sleep(300) ; }catch(InterruptedException e){ e.printStackTrace() ; } this.setContent(content) ; // 设置内容 flag = false ; // 改变标志位,表示可以取走 super.notify() ; } public synchronized void get(){ if(flag){ try{ super.wait() ; }catch(InterruptedException e){ e.printStackTrace() ; } } try{ Thread.sleep(300) ; }catch(InterruptedException e){ e.printStackTrace() ; } System.out.println(this.getName() + " --> " + this.getContent()) ; flag = true ; // 改变标志位,表示可以生产 super.notify() ; } public void setName(String name){ this.name = name ; } public void setContent(String content){ this.content = content ; } public String getName(){ return this.name ; } public String getContent(){ return this.content ; } }; class Producer implements Runnable{ // 通过Runnable实现多线程 private Info info = null ; // 保存Info引用 public Producer(Info info){ this.info = info ; } public void run(){ boolean flag = false ;// 定义标记位 for(int i=0;i if(flag){ this.info.set("李兴华","JAVA讲师") ; // 设置名称 flag = false ; }else{ this.info.set("mldn","www.mldnjava.cn") ; // 设置名称 flag = true ; } } } }; class Consumer implements Runnable{ private Info info = null ; public Consumer(Info info){ this.info = info ; } public void run(){ for(int i=0;i this.info.get() ; } } }; public class ThreadCaseDemo03{ public static void main(String args[]){ Info info = new Info(); // 实例化Info对象 Producer pro = new Producer(info) ; // 生产者 Consumer con = new Consumer(info) ; // 消费者 new Thread(pro).start() ; new Thread(con).start() ; } };
定时调度
// 完成具体的任务操作 import java.util.TimerTask ; import java.util.Date ; import java.text.SimpleDateFormat ; class MyTask extends TimerTask{ // 任务调度类都要继承TimerTask public void run(){ SimpleDateFormat sdf = null ; sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS") ; System.out.println("当前系统时间为:" + sdf.format(new Date())) ; } }; import java.util.Timer ; public class TestTask{ public static void main(String args[]){ Timer t = new Timer() ; // 建立Timer类对象 MyTask mytask = new MyTask() ; // 定义任务 t.schedule(mytask,1000,2000) ; // 设置任务的执行,1秒后开始,每2秒重复 } };
线程同步与死锁
1、资源共享时需要进行同步操作 2、程序中过多的同步会产生死锁
synchronized关键字,线程同步
class MyThread implements Runnable{ private int ticket = 5 ; // 假设一共有5张票 public void run(){ for(int i=0;i this.sale() ; // 调用同步方法 } } public synchronized void sale(){// 声明同步方法 if(ticket>0){ // 还有票 try{ Thread.sleep(300) ; // 加入延迟 }catch(InterruptedException e){ e.printStackTrace() ; } System.out.println("卖票:ticket = " + ticket-- ); } } }; public class SyncDemo03{ public static void main(String args[]){ MyThread mt = new MyThread() ; // 定义线程对象 Thread t1 = new Thread(mt) ; // 定义Thread对象 Thread t2 = new Thread(mt) ; // 定义Thread对象 Thread t3 = new Thread(mt) ; // 定义Thread对象 t1.start() ; t2.start() ; t3.start() ; } };
死锁
class Zhangsan{ // 定义张三类 public void say(){ System.out.println("张三对李四说:“你给我画,我就把书给你。”") ; } public void get(){ System.out.println("张三得到画了。") ; } }; class Lisi{ // 定义李四类 public void say(){ System.out.println("李四对张三说:“你给我书,我就把画给你”") ; } public void get(){ System.out.println("李四得到书了。") ; } }; public class ThreadDeadLock implements Runnable{ private static Zhangsan zs = new Zhangsan() ; // 实例化static型对象 private static Lisi ls = new Lisi() ; // 实例化static型对象 private boolean flag = false ; // 声明标志位,判断那个先说话 public void run(){ // 覆写run()方法 if(flag){ synchronized(zs){// 同步张三 zs.say() ; try{ Thread.sleep(500) ; }catch(InterruptedException e){ e.printStackTrace() ; } synchronized(ls){ zs.get() ; } } }else{ synchronized(ls){ ls.say() ; try{ Thread.sleep(500) ; }catch(InterruptedException e){ e.printStackTrace() ; } synchronized(zs){ ls.get() ; } } } } public static void main(String args[]){ ThreadDeadLock t1 = new ThreadDeadLock() ; // 控制张三 ThreadDeadLock t2 = new ThreadDeadLock() ; // 控制李四 t1.flag = true ; t2.flag = false ; Thread thA = new Thread(t1) ; Thread thB = new Thread(t2) ; thA.start() ; thB.start() ; } };
线程运行状态
class MyThread implements Runnable{ private boolean flag = true ; // 定义标志位 public void run(){ int i = 0 ; while(this.flag){ System.out.println(Thread.currentThread().getName() +"运行,i = " + (i++)) ; } } public void stop(){ this.flag = false ; // 修改标志位 } }; public class StopDemo{ public static void main(String args[]){ MyThread my = new MyThread() ; Thread t = new Thread(my,"线程") ; // 建立线程对象 t.start() ; // 启动线程 try{ Thread.sleep(30) ; }catch(Exception e){ } my.stop() ; // 修改标志位,停止运行 } };
object类-->异常处理Throwable类
Error
一般是指JVM出现错误,程序中无法处理,例如内存益出
Exception
IOException检查异常
由编译器进行捕获的异常称为检查型异常(直接由Exception的子类检查型异常)
FileNotFoundException
EOFException
RunTimeException运行期异常
RunTimeExcetpion类型,则不是必须使用try...catch()..处理,一旦出现异常,未捕获则由JVM进行处理, 但未了保证程序的健壮性,建议在有可以出现的异常的地方进行捕获(运行期异常是由解释器捕获的异常)
NullPointerException
空指针引用异
ClassCastException
类型强制转换异常。
IndexOutOfBoundsException
下标越界异常
IllegalArgumentException
传递非法参数异
NumberFormatException
数字格式异常
异常处理
throws
表示本方法不处理异常,将抛出的异常交给调用处进行处理(用在方法头 throws Exception)
throw
抛出异常对象(用在方法里 throw new Exception(),throw 异常类型的对象)
try{}catch(){}finally{处理异常的统一出口}
代理模式
import java.lang.reflect.InvocationHandler ; import java.lang.reflect.Proxy ; import java.lang.reflect.Method ; interface Subject{ public String say(String name,int age) ; // 定义抽象方法say } class RealSubject implements Subject{ // 实现接口 public String say(String name,int age){ return "姓名:" + name + ",年龄:" + age ; } }; class MyInvocationHandler implements InvocationHandler{ private Object obj ; public Object bind(Object obj){ this.obj = obj ; // 真实主题类 return Proxy.newProxyInstance(obj.getClass().getClassLoader(),obj.getClass().getInterfaces(),this) ; } public Object invoke(Object proxy,Method method,Object[] args) throws Throwable{ Object temp = method.invoke(this.obj,args) ; // 调用方法 return temp ; } }; public class DynaProxyDemo{ public static void main(String args[]){ Subject sub = (Subject)new MyInvocationHandler().bind(new RealSubject()) ; String info = sub.say("李兴华",30) ; System.out.println(info) ; } };
被代理接口
package com.bjsxt.proxy; public interface Moveable { void move(); }
被代理类Tank
package com.bjsxt.proxy; import java.util.Random; public class Tank implements Moveable { @Override public void move() { System.out.println("Tank Moving..."); try { Thread.sleep(new Random().nextInt(10000)); } catch (InterruptedException e) { e.printStackTrace(); } } }
InvocationHandler
public voidinvoke(Object o, Method m);
package com.bjsxt.proxy; import java.lang.reflect.Method; public interface InvocationHandler { public void invoke(Object o, Method m); }
TimeHandler
package com.bjsxt.proxy; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; public class TimeHandler implements InvocationHandler{ private Object target; public TimeHandler(Object target) { super(); this.target = target; } @Override public void invoke(Object o, Method m) { long start = System.currentTimeMillis(); System.out.println("starttime:" + start); System.out.println(o.getClass().getName()); try { m.invoke(target); } catch (Exception e) { e.printStackTrace(); } long end = System.currentTimeMillis(); System.out.println("time:" + (end-start)); } }
客户端测试类Client
package com.bjsxt.proxy; public class Client { public static void main(String[] args) throws Exception { Tank t = new Tank(); InvocationHandler h = new TimeHandler(t); Moveable m = (Moveable)Proxy.newProxyInstance(Moveable.class, h); m.move(); } } //可以对任意的对象、任意的接口方法,实现任意的代理 显示结果: class com.bjsxt.proxy.$Proxy1 starttime:1360662860802 com.bjsxt.proxy.$Proxy1 Tank Moving... time:8236
Proxy代理解析类
专门完成代理操作,可以通过此类为一个或多个接口动态生成实现类 newPorxyInstance();
package com.bjsxt.proxy; import java.io.File; import java.io.FileWriter; import java.lang.reflect.Constructor; import java.lang.reflect.Method; import java.net.URL; import java.net.URLClassLoader; import javax.tools.JavaCompiler; import javax.tools.StandardJavaFileManager; import javax.tools.ToolProvider; import javax.tools.JavaCompiler.CompilationTask; public class Proxy { public static Object newProxyInstance(Class infce, InvocationHandler h) throws Exception { //JDK6 Complier API, CGLib, ASM String methodStr = ""; String rt = "\r\n"; Method[] methods = infce.getMethods(); /* for(Method m : methods) { methodStr += "@Override" + rt + "public void " + m.getName() + "() {" + rt + " long start = System.currentTimeMillis();" + rt + " System.out.println(\"starttime:\" + start);" + rt + " t." + m.getName() + "();" + rt + " long end = System.currentTimeMillis();" + rt + " System.out.println(\"time:\" + (end-start));" + rt + "}"; } */ for(Method m : methods) { methodStr += "@Override" + rt + "public void " + m.getName() + "() {" + rt + " try {" + rt + " Method md = " + infce.getName() + ".class.getMethod(\"" + m.getName() + "\");" + rt + " h.invoke(this, md);" + rt + " }catch(Exception e) {e.printStackTrace();}" + rt + "}"; } String src = "package com.bjsxt.proxy;" + rt + "import java.lang.reflect.Method;" + rt + "public class $Proxy1 implements " + infce.getName() + "{" + rt + " public $Proxy1(InvocationHandler h) {" + rt + " this.h = h;" + rt + " }" + rt + " com.bjsxt.proxy.InvocationHandler h;" + rt + methodStr + "}"; String fileName = "d:/src/com/bjsxt/proxy/$Proxy1.java"; File f = new File(fileName); FileWriter fw = new FileWriter(f); fw.write(src); fw.flush(); fw.close(); //compile JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); StandardJavaFileManager fileMgr = compiler.getStandardFileManager(null, null, null); Iterable units = fileMgr.getJavaFileObjects(fileName); CompilationTask t = compiler.getTask(null, fileMgr, null, null, null, units); t.call(); fileMgr.close(); //load into memory and create an instance URL[] urls = new URL[] {new URL("file:/" + "d:/src/")}; URLClassLoader ul = new URLClassLoader(urls); Class c = ul.loadClass("com.bjsxt.proxy.$Proxy1"); System.out.println(c); Constructor ctr = c.getConstructor(InvocationHandler.class); Object m = ctr.newInstance(h); //m.move(); return m; } }
工厂模式
package com.factorys; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.util.Properties; interface Fruit{ void group();//生成 void pick();//采摘 } class Apple implements Fruit{ @Override public void group() { System.out.println("苹果生长....."); } @Override public void pick() { System.out.println("苹果采摘....."); } } class Banana implements Fruit{ @Override public void group() { System.out.println("香蕉在生长......"); } @Override public void pick() { System.out.println("香蕉在采摘...."); } } class Init{ public static Properties getPro(){ Properties pro = new Properties() ; File f = new File("d:\\fruit.properties") ; // 找到属性文件 try{ if(f.exists()){ // 文件存在 pro.load(new FileInputStream(f)) ; // 读取属性 }else{ pro.setProperty("apple","com.factorys.Apple") ; pro.setProperty("banana","com.factorys.Banana") ; pro.store(new FileOutputStream(f),"FRUIT CLASS") ; } }catch(Exception e){} return pro ; } }; //单例工厂 class Factory{ private static Factory factory;//本类声明静态属性 private Factory(){//构造方法私有化 } //声明一个静态方法 用来判断是否三类实实例化过,如果没有则实例化 public static Factory getFactoryInstance(){ if(factory==null){ factory= new Factory(); } return factory; } public Fruit getFruitInstance(String className){ Fruit f = null; try { f =(Fruit)Class.forName(className).newInstance(); } catch (InstantiationException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalAccessException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } return f; } } public class MainsFactoryTest { public static void main(String[] args) { Properties pro = Init.getPro() ; Fruit f = Factory.getFactoryInstance().getFruitInstance(Init.getPro().getProperty("apple")); if(f!=null){ f.group(); f.pick(); } } }
具体实例由工厂方法统一实现
单例模式
1、声明本类静态属性 2、构造方法私有化 3、声明一个静态方法用来判断是否三类实实例化过,如果没有则实例化 4、调用方式:Fruitf=Factory.getFactoryInstance().getFruitInstance(Init.getPro().getProperty("apple"));
//单例工厂 class Factory{ private static Factory factory;//声明本类静态属性 private Factory(){//构造方法私有化 } //声明一个静态方法 用来判断是否三类实实例化过,如果没有则实例化 public static Factory getFactoryInstance(){ if(factory==null){ factory= new Factory(); } return factory; } public Fruit getFruitInstance(String className){ Fruit f = null; try { f =(Fruit)Class.forName(className).newInstance(); } catch (InstantiationException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalAccessException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } return f; } }
Oracle数据库
用户管理
用户创建
--创建用户 hello 密码 lihaoran create user hello identified by lihaoran; --为hello用户 grant 授予登陆权限 grant create session to hello; --连接hello用户 conn hello/lihaoran; --为hello用户分配resource权限 进行crud操作 grant resource to hello; --修改密码 alter user hello identified by lihaoran; --撤消crud权限 revoke resource from hello; --删除hello 用户 及相关的信息 drop user hello cascade;
--案例:lihaoran用户去查询 scott用户下的表 --第一步连接 scott用户 connect scott/tiger --第二步 将 emp表 查询权限赋给lihaoran用户 grant select[update,insert,delete,all] on emp to lihaoran; --第三步 登陆lihaoran 用户查询emp表 带scott用户名 select * from scott.emp; --创建用户hello create user hello identified by hello; grant connect to hello; grant resource to hello; --将liharoan用户下的scott表中的emp权限转让给hello用户 --连接scott用户 Connect scott/tiger --将lihaoran用户下的scott用户下的emp表受对象权限 可转让 grant all on emp to lihaoran with grant option;(必须在scott用户以及权限更新的用户操作) --//将系统权限往下分匹(with admin option) grant select on emp to hello;(lihaoran受权用户能及权限更大的用户操作) --撤消liharoan查询权限 --连接system/ scott用户 connect system/orcl --撤消查询权限 revoke select on scott.emp from lihaoran; --将scott用户上锁 alter user scott account lock;(此用户不可用,但上级用户可以操作该用户的数据(crud)) --将scott用户解锁 alter user scott account unlock;
sql语句
内连接
1、容易产生迪卡尔机,通过外键等唯一性约束 select * from emp e,dept d where e.deptno=d.deptno; 2、完整写法 inner join ...on... select * from emp e inner join dept d on e.deptno=d.deptno;
左右全连接
以联合查询雇员表和部门表为例 1、左连接:left join ... on .... select * from emp e left join dept d on e.deptno=d.deptno; 方法二右(+) select * from emp e,dept d where e.deptno=d.deptno(+); 2、右连接:right join..on... select * from emp e right join dept d on e.deptno=d.deptno; 方法二左(+) select * from emp e,dept d where e.deptno(+)=d.deptno; 3、全连接 select * from emp e full join dept d on e.deptno=d.deptno;
自连接
查询雇员的上级领导 select * from emp e1,emp e2 where e1.mgr=e2.empno;
Oracle 分页三层嵌套写法
查询雇员表2到10之间的数据 select * from (select e2.*,rownum rn from (select * from emp) e2 where rownum<=10) e1 where rn>=2;
group by(分组)/having(分组后进行过虑)/order by asc、desc(排序)
select avg(sal),max(sal),min(sal),count(*),sum(sal),e.deptno from emp e where to_char(e.hiredate,'yyyy-mm-dd')>'1980-12-20' group by e.deptno having avg(sal)>1000 order by e.deptno;
子查询
--单行子查询 =号来查询 --显示与SMITH同一部门的所有员工 select * from emp e where e.deptno=(select deptno from emp p where p.ename='SMITH'); --多行子查询 in 来查询 --显示与10号部门 job 职位相同的雇员信息 select * from emp e where e.job in(select distinct p.job from emp p where p.deptno=10); --比30部门员工工资都高的员工信息max,all select * from emp e where e.sal>(select max(sal) from emp p where p.deptno=30); select * from emp e where e.sal>all(select sal from emp p where p.deptno=30); --查询比30部门员工任意工资高的雇员信息min、any select * from emp e where e.sal>(select min(sal) from emp p where p.deptno=30); select * from emp e where e.sal>any(select sal from emp p where p.deptno=30); --多列子查询 --查询与SMITH同一部门同一岗位的员工 --方法一 select * from emp e where e.deptno=(select deptno from emp where ename='SMITH') and e.job=(select job from emp where ename='SMITH'); --方法二(deptno,job)=(select deptno,job from emp where ename='SMITH'); select * from emp where (deptno,job)=(select deptno,job from emp where ename='SMITH'); --在from 子句中使用子查询 --显示高于自己部门平均工资的员工信息 --方法一 --把(select avg(sal) deptno from emp group by deptno当作一个临时表) select e.deptno,e.ename,e.deptno,avgs from emp e,(select avg(sal) avgs,deptno from emp group by deptno) p where e.deptno=p.deptno and e.sal>avgs; --方法二(缺陷 不能查询平均工资) select * from emp e where e.sal>(select avg(sal) from emp p where p.deptno=e.deptno); --查找每个部门工资最高的人的详细信息 SQL> select * from emp e,(select max(sal) maxs,deptno from emp group by deptno) p where e.deptno=p.deptno and e.sal=maxs; --显示每个部门的信息(编号、名称、)和人员数量 select d.deptno,d.dname,counts from dept d,(select count(*) as counts,deptno from emp group by deptno) t where d.deptno=t.deptno(+);
序列sequence
--从1开始,每次自增1,最大值 99999999999,之后又循环从1开始 create sequence my_lihaoran--创建序列 start with 1 --从一开始自增 increment by 1 --每次自增1 maxvalue 99999999999 --NOMAXVALUE(不设置最大值) --最大值 minvalue 1 --最小值 cycle --cycle 表示当前序列增加到99999999999 从新从1开始,如果nocycle就停止; nocache --//nocache表示不缓存,【cache:10】 表示一次产生10个号供你使用,优点提高效率,缺点可以产生跳号 --创建表 create table lihaoran(id number primary key,name varchar2(100)); --添加序列 insert into lihaoran values(my_lihaoran.nextval,'lihaoran'); --显示当前序列值 select my_lihaoran.currval from dual; --删除序列 drop sequence my_lihaoran --sqlserver自增长identity create table sqlserver( id int primary key identity(1,1)); --mysql auto_increment create table mysql( id int primary key auto_increment);
大对象
Blog(4g)
存储二进制数据,例如电影,音乐,图片等
Clob(4g)
存储大文本对象,少量文字
函数
Upper(行,列)字符串转大写 Lower(行,列)字符串转小写返回 Initcap()开关首字母大写 Length()取字符串长度 Replace()替换 Substr(列,开始点,结束点)字符串截取
范例-转大写 select Upper('hello world') from dual;-- 1 HELLO WORLD select * from emp e where e.ename=upper('smith') EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO 1 7369 SMITH CLERK 7902 1980/12/17 800.00 20 范例—转小写 select Lower(ename) from emp; 范例-首字母大写 select initcap(ename) from emp; 范例-字段长度 select e.ename,length(e.ename) from emp e; 范例-字段姓名长度为5的字段 select e.ename,length(e.ename) from emp e where length(e.ename)=5 范例-字段中含有‘A’换成’_’ select replace(e.ename,'A','_') as ename from emp e; 范例-截取姓名后三位 select substr(e.ename,length(e.ename)-2,length(e.ename)) from emp e; select substr(e.ename,-3)from emp e; 请问substring截取是从0开始截取,还是从1开始的? Oracle数据库中从0或1都可以 Substr也可以设置负数;表示从后面设置起始点;
视图/索引
--创建视图 create view lihaoran_view as select e.ename,e.deptno,d.dname from emp e,dept d where e.deptno=d.deptno with readonly; --with read only 只可读不可修改 create view lihaoran_view as select e.ename,e.deptno,d.dname from emp e,dept d where e.deptno=d.deptno with read only; --or replace create or replace view lihaoran_view as select e.ename,e.deptno,d.dname from emp e,dept d where e.deptno=d.deptno with read only; --删除视图 drop view lihaoran_view; --索引 CREATE UNIQUE CLUSTERED INDEX index_viewFoo ON viewFoo(id)
存储过程-plsql编程
pl/sql是标准sql语句基础是扩展的一种对Oracle数据库进行编程的语句,可以定义变量,常量,而且可以进行条件语句和循环
可以编写客户端(sqlplus/developer),使用plsql编写储存过程
create or replace procedure fenyePro1 ( v_in_table in varchar2,v_in_pagesize in number, v_in_pagenow in number,v_out_result out pack1.my_cursor,v_out_rows out number, v_out_pagecount out number number ) is --定义变量 v_sql varchar2(2000); v_start number; v_end number; begin --执行代码 --回忆分页语句 --计算v_start 和v_end 是多少 v_start:=v_in_pagesize*(v_in_pagenow-1)+1; v_end:=v_in_pagesize*v_in_pagenow; v_sql:='select t2.* from(select t1.*,rownum rn from (select * from '||v _in_table||') t1 where rownum<='||v_end||') t2 where rn>='||v_start; --打开游标,让游标指向结果集 open v_out_result for v_sql; --查询共有多少条记录 select count(*) into v_out_rows from emp; if mod(v_out_rows,v_in_pagesize)=0 then v_out_pagecount:=v_out_rows/v_in_pagesize; else v_out_pagecount:=v_out_rows/v_in_pagesize+1; end if; end; procedure created;
处发器
create or replace trigger salary_trigger --当向table_a表中插入一行或修改一行后激活触发器。 before insert or update of num_col on table_a for each row begin --如果插入值或修改值大于10000时,报告应插入值 --并产生异常,退出该触发器。 if:new.num_col>10000 then raise_application_error(-200060,'插入值应小于10000!'); end if; end salary_trigger;