wasw100's Blog
2012/02/23

Google AD

2009年10月18日

xp下apache+php的环境的安装

想看一下php,在xp下配置了一个apache+php环境。

软件版本:

  1. apache_2.2.14-win32-x86-openssl-0.9.8k.msi
  2. php-5.2.11-Win32.zip(直接解压就可以用)

以上软件都在官方网站下载。

1、安装apache
直接安装(我安装的目录是D:\tools\Apache2.2)
中间有个填写服务器名的地方,可直接填写自己的计算机名,邮件填写自己的邮件。
在浏览器输入http://127.0.0.1/如果输出:

It works!

那么apache服务器就安装成功了。

2、安装php
直接解压即可,我解压到了D:\tools\php-5.2.11-Win32

3、配置
将php目录(D:\tools\php-5.2.11-Win32)下的php.ini-recommended另存为php.ini保存到C:\WINDOWS下(以后配置php就需要修改这个文件)
libmysql.dll(支持MySQL数据库),
php5ts.dll(apache服务器支持php)
复制到C:\WINDOWS\system32(在win2k,nt复制到C:\WINNT\system32下)

剩下的就是修改配置文件了。
开始-》所有程序-》Apache Server 2.2-》Configure Apache Server-》Edit the Apache httpd.conf Configuration File
或者直接用文本编辑器打开:D:\tools\Apache2.2\conf(apache安装目录下conf文件夹)下的httpd.conf

搜索LoadModule,按对应的方式添加上:

LoadModule php5_module D:\tools\php-5.2.11-Win32\php5apache2_2.dll

然后搜索 AddType,在
AddType application/x-compress .Z
AddType application/x-gzip .gz .tgz
后面添上

 AddType application/x-httpd-php .php
 AddType application/x-httpd-php .htm

重启一下服务器,这样服务器就支持php了

4、测试
新建一个文本文件,内容如下

<?php
phpinfo();
?>

保存到apache安装目录下的htdocs文件夹下(我的D:\tools\Apache2.2\htdocs),保存名为:test.php
打开浏览器,输入http://127.0.0.1/test.php
如果成功,就输出一些系统信息,如果失败,应该就原样输出
我也是第一次安装(接触)php,如有问题,请留言,大家共同探讨。

<!–今天(10月19号)做连接MySQL数据库是发现没有成功,下面是解决方法,有问题大家讨论–>
今天发现数据库还是连接不上,一连数据库出现下面的错误(要有错误显示,需要修改c:\windows下php.ini的display_errors = Off改为display_errors = On,负责不显示数据):

Fatal error: Call to undefined function mysql_connect() in D:\tools\Apache2.2\htdocs\connsql.php on line 8

然后Google,最后终于发现了问题的所在,既然apache连接php成功
php连接不上MySQL,那问题出现在php的配置上,而不是apache的配置上,所以继续修改php.ini

在C:\Windows\php.ini下搜索:extension_dir,原来的配置是”.\”,你修改为你php解压到的路径,我的是修改为

extension_dir = "D:\tools\php-5.2.11-Win32\ext"

然后继续搜索extension,把

extension=php_curl.dll
extension=php_dba.dll
……
extension=php_imap.dll
……
extension=php_mysql.dll
extension=php_mysqli.dll

之前的分号去,重启apache服务器,问题解决。

<!– 10月20日更新 WordPress显示问题  –>

今天研究博客数据库的设计,下载了大名鼎鼎的WordPress中文版,安装一切正常,管理界面也正常,但是一访问主页就显示文件列表

修改了一下apache的配置文件(开始-》所有程序-》Apache Server 2.2-》Configure Apache Server-》Edit the Apache httpd.conf Configuration File)

搜索index.html,修改为index.php 问题解决,修改后如下

<IfModule dir_module>
    DirectoryIndex index.php
</IfModule>

重启apache,问题解决

–EOF–

2009年10月14日

jdk1.5新特性总结

面试的时候面试官问我jdk1.5的新特性,居然只回答上两个(泛型,增强for循环),回来一查,其实都接触过,而且好几个特性自己还经常用。

下面就总结一下:1.泛型(Generic) 2.增强for循环(For-Each循环) 3.自动装箱与拆箱(Autoboxing/unboxing) 4.静态导入(static import) 5.格式化打印(formatted print) 6.枚举(Enum) 7.可变参数(varargs)

1、泛型(Generic)
可以在编译的时候检测出类型错误,编译后和没有使用泛型的效果是相同的,但是使用泛型可以让你在编译时就发现错误,例如:

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

public class GenericTest {
	public static void main(String[] args) {
		Collection c = new ArrayList();
		c.add(new Integer(1));
		c.add("123");
		for(Iterator i=c.iterator();i.hasNext();){
			String s = (String) i.next();
			System.out.println(s);
		}
	}
}

运行结果:
Exception in thread "main" java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String
	at GenericTest.main(GenericTest.java:12)

Collection应该只存放String对象,但是我们“不小心”添加了一个Integer类型的对象,编译正常进行,程序在运行时才发现错误。

下面是使用了泛型后的程序

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

public class GenericTest {
	public static void main(String[] args) {
		Collection<String> c = new ArrayList<String>();
		c.add(new Integer(1));
		c.add("123");
		for(Iterator<String> i=c.iterator();i.hasNext();){
			String s = i.next();
			System.out.println(s);
		}
	}
}

运行结果
D:\test>javac GenericTest.java
GenericTest.java:8: 无法将 java.util.Collection<java.lang.String> 中的 add(java.lang.String) 应用于 (java.lang.Integer)
                c.add(new Integer(1));
                 ^
1 错误

D:\test>

使用了泛型之后在编译时就发现了错误,可以增强程序的健壮性,而其i.next();也不用使用强制类型转换了。

2、增强for循环(For-Each)
For-Each的内部是用Iterator实现的,但是使用起来更简单,例如使用For-Each实现1-2如下

import java.util.ArrayList;
import java.util.Collection;

public class GenericTest {
	public static void main(String[] args) {
		Collection<String> c = new ArrayList<String>();
		c.add("aa");
		c.add("bb");
		for(String s:c){
			System.out.println(s);
		}
	}
}
运行结果:
aa
bb

比Integer方便多了吧?可以使程序员更加注重逻辑,而不是代码本身。

3、自动装箱拆箱(Autoboxing/unboxing)

Integer i = new Integer(2);
//i自动拆箱为int类型
System.out.println(i==2);
//3自动装箱为Integer类型
System.out.println(i.equals(3));

4、静态导入(static import)

//静态导入Math的random方法
import static java.lang.Math.random;

public class StaticImportTest {
	public static void main(String[] args){
		//类中生成随机数数可以直接使用静态引入的random方法了,而不用Math.random()这样调用了
		System.out.println(random());
	}
}

5、格式化打印(formatted print)

C语言中printf()风格的格式化输出。

这里只举一个thinking in java的一个例子:

public class SimpleFormat {
	public static void main(String[] args) {
		int x = 5;
		double y = 5.332542;
		//The old way
		System.out.println("Row 1: ["+x+" "+y+"]");
		//The new way
		System.out.format("Row 1: [%d %f]\n", x,y);
		//or
		System.out.printf("Row 1: [%d %f]\n", x, y);
	}
}

运行结果:
Row 1: [5 5.332542]
Row 1: [5 5.332542]
Row 1: [5 5.332542]

可以看到,format和printf是等价的,他们只需要一个简单的格式化字符串,加上一串参数即可,每个参数对应一个格式修饰符

6、枚举(Enum)

当每一类型可取值范围是有限的时候,可以使用枚举,例如每个学生登记只能用ABCD表示,如果直接用E的话,那么编译不会出错,但是却不符合输入要求,而使用枚举增加程序的易读性和健壮性?

public class GradeTest {
	public static void main(String[] args) {
		Student stu = new Student();
		stu.setName("wasw100");
		stu.setGrade(Grade.A);
		//输出学生信息
		System.out.println(stu);
	}
}

/**
 * 枚举:Grader 学生考试等级
 * @author wasw100
 */
enum Grade{
	A,B,C,D
}

class Student {
	private String name;
	private Grade grade;

	//重写toString()方法
	public String toString(){
		return "name:+"+name+"\ngrader:"+grade;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public Grade getGrade() {
		return grade;
	}

	public void setGrade(Grade grade) {
		this.grade = grade;
	}

}

7、可变长参数(varargs)

方法的参数是不固定的我们一般会使用重载或者使用数组参数。重载需要些更多写更多的方法,数组需要在使用时先声明。

可能参数是一个不错的解决方案。

下面是网上一个 唐僧 给 悟空 将佛经的例子

public class VarargsTest {
	public void speak(String name, Object... arguments) {
		System.out.print(name+": ");
		for (Object object : arguments) {
			System.out.print(object);
		}
		System.out.println();
	}

	public static void main(String[] args) {
		VarargsTest vt = new VarargsTest();
		vt.speak("悟空", "人和妖精都是妈生的,");
		vt.speak("悟空", "不同的人是人他妈生的,", "妖是妖他妈生的,");
	}
}

运行结果:
悟空: 人和妖精都是妈生的,
悟空: 不同的人是人他妈生的,妖是妖他妈生的,

可变长参数只能作为最后一个参数。

2009年09月26日

Swing中Timer定时器的使用

类名:javax.swing.Timer

构造方法:Timer(int delay, ActionListener listener)
          
创建一个每 delay 毫秒将通知其侦听器的 Timer。

int delay = 1000; //milliseconds
  ActionListener taskPerformer = new ActionListener() {
      public void actionPerformed(ActionEvent evt) {
          //...Perform a task...
      }
  };
  new Timer(delay, taskPerformer).start();

 

该代码创建并启动一个每秒激发一次操作事件的计时器(正如该 Timer 构造方法的第一个参数指定的那样)。该 Timer 构造方法的第二个参数指定一个接收该计时器操作事件的侦听器。

 

上面是API上说明,javax.swing.Timer在 GUI编程在组件内容更新时经常用到Timer,例如JTable、JLabel内容更新。

下面是一个简单的显示时间的GUI程序,可以加深对Timer的使用的理解:

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.Timer;

/**
 * 测试swing中Timer的使用
 * 一个显示时间的GUI程序
 * @author wasw100
 *
 */
public class TimerTest extends JFrame implements ActionListener {
	// 一个显示时间的JLabel
	private JLabel jlTime = new JLabel();
	private Timer timer;

	public TimerTest() {
		setTitle("Timer测试");
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setSize(180, 80);
		add(jlTime);

		//设置Timer定时器,并启动
		timer = new Timer(500, this);
		timer.start();
		setVisible(true);
	}

	/**
	 * 执行Timer要执行的部分,
	 */
	@Override
	public void actionPerformed(ActionEvent e) {
		DateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		Date date = new Date();
		jlTime.setText(format.format(date));

	}

	public static void main(String[] args) {
		new TimerTest();
	}
}

程序说明: 

类实现了ActionListener接口,所以可以直接timer = new Timer(500, this);使用this初始化计时器。

当计时器启动后(timer.start()执行后),每隔500毫秒执行一次实现的 ActionListener 接口中的actionPerformed的方法体

 

这里在补充一点显示时间格式的知识:

DateFormat format = new SimpleDateFormat(“yyyy-MM-dd HH:mm:ss”);

MM表示月份  mm表示分钟   hh:12小时制显示几点  HH:24小时制显示几点 

–EOF–

2009年09月22日

解决ie6 ie7中js不能通过appendChild(tr)添加table行的方法

本机只有ie7,ff3.5,opera10,测试在这三个环境中测试通过。

在标准DOM中添加元素一般使用appendChild();
但用js在table中添加行时却失效了。
网上搜了一下说 ie6,ie7不支持table.appendChild(“tr”)

那在JavaScript中怎么在一个table中添加一行呢?
http://www.w3schools.com/htmldom/dom_obj_table.asp看到w3c文档中HTML DOM Object存在tableObject.insertRow(index)方法。何不在插入行时用这个方法呢,毕竟在html中table比普通的标签有其特殊性,碰到table添加一行时,注意使用insertRow而不是appendChild,这样代码才能使用更多浏览器。看下面一段代码:

<!DOCTYPE html>
<html>
	<head>
		<script type="text/javascript">
		function insRow()
		{
			var tbl = document.getElementById('myTable');
			var row = tbl.insertRow(0);
			var cell = row.insertCell(0);
			cell.innerHTML="new cell";
		}
</script>
	</head>

	<body>
		<table id="myTable" border="1">
			<tr>
				<td>
					cell
				</td>
			</tr>
		</table>
		<br />
		<input type="button" onclick="insRow()" value="Insert row">
	</body>
</html>

比使用标准的DOM还简单,而且也符合w3c标准,但有一点要说明的是:

innerHTML这个方法虽然没有在w3c文档中出现,但是由于使用的广泛性,很多浏览器都进行了支持,添加文本节点(text nodes)时可以用innerHTML,如果非要符合w3c标准,可以用createTextNode(str)方法,本例中在JavaScript最后一行改为:cell.appendChild(document.createTextNode(“new cell”))。

但是上面的例子还有一个与appendChild()不同的地方,就是appendChild值插在原有元素的后面,但是例子中是插在了第一行。怎么插在表格的最后一行,或者插在当前行的后一行或者前一行怎么做呢?
只要实例中把javascript改为:var row = tbl.insertRow(tbl.rows.length);

下面附加一段带有 在最后加一行,本行前前加一行,本行后加一行,删除当前行的html代码

<!DOCTYPE html>
<html>
	<head>
		<meta http-equiv="Content-Type" content="text/htmt;charset=utf-8">
		<script type="text/javascript">
		var i=0;
		function insRow(){
			var tbl = document.getElementById("myTable");
			insRowIndex(tbl.rows.length);
		}
		function insRowIndex(rowIndex){
			var tbl = document.getElementById("myTable");
			var row = tbl.insertRow(rowIndex);
			var cell0 = row.insertCell(0);
			var cell1 = row.insertCell(1);
			cell0.innerHTML = "cell " + i++;
			cell1.innerHTML = "	<input type='button' value='delete' onclick='delRow(this)'>"
								+"<input type='button' value='insBefore' onclick='insBefore(this)'>"
								+"<input type='button' value='insAfter' onclick='insAfter(this)'>";
		}
		function delRow(row){
			var tbl = document.getElementById("myTable");
			var rowIndex =  row.parentNode.parentNode.rowIndex;
			tbl.deleteRow(rowIndex);
		}
		function insBefore(row){
			var rowIndex =  row.parentNode.parentNode.rowIndex;
			insRowIndex(rowIndex)
		}
		function insAfter(row){
			var rowIndex =  row.parentNode.parentNode.rowIndex;
			insRowIndex(rowIndex+1)
		}
</script>
	</head>

	<body>
		<table id="myTable" border="1">
			<tr>
				<td>
					单元格
				</td>
				<td>
					操作
				</td>
			</tr>
		</table>
		<br />
		<input type="button" onclick="insRow()" value="Insert row">
	</body>
</html>

–EOF–

2009年09月19日

hibernate中使用hilo生成主键的原理

hilo是hibernate中最长用的一种生成方式,hibernate给出了hilo 和 seqhilo两种生成器,他们的分别向下面一样配置

<id name="id" type="int" column="id">
        <generator class="hilo">
                <param name="table">wasw100_hilo_tbl</param>
                <param name="column">next_value</param>
                <param name="max_lo">100</param>
        </generator>
</id>

 

seqhilo配置

<id name="id" type="int" column="id">
        <generator class="seqhilo">
                <param name="sequence">hi_value</param>
                <param name="max_lo">100</param>
        </generator>
</id>

 

seqhilo生成器需要数据库对sequence的支持,这里只讨论更通用的hilo生成器。

如果你按照下面的方式配置

<generator class="hilo">
        <param name="max_lo">100</param>
</generator>

 这样的缺省配置对应的数据库表是:hibernate_unique_key,对应的数据库字段是:next_hi。next_hi必须有一条记录否则会出现错误。

 

讨论前先说明几个简写的意义,以最上面那个配置为例:

hi: 高值–从数据库wasw100_hilo_tbl读取的next_value值

lo: 低值–hibe自动维护,从0到max_lo(看下面)

max_lo: 配置文件中<param name=”max_lo”>100</param>的值,这里是100

 

hibernate根据hilo生成器生成主键的过程:

1.读取并记录数据库的wasw100_hilo_tbl表中next_value字段的值,数据库中此字段值加1保存

2.hibernate取得lo值(0到max_lo-1循环,lo到max_lo时,执行步骤1,然后lo继续从0到max_lo循环)

取得hi值和lo值后,根据下面的公式计算主键值:

hi*(max_lo+1)+lo;

 

例如:
hi初始为2,max_lo为3
生成的值依次是:
读取hi为2,写到数据库为3
2*(3+1)+0=8
2*(3+1)+1=9
2*(3+1)+2=10
2*(3+1)+3=11
这有次读写表wasw100_hilo_tbl操作,hi变为3,数据库成为4
3*(3+1)+0=12
3*(3+1)+1=13

关闭数据库,下次打开时,读取hi值为4,数据库变为5
4*(3+1)+0=16

 

但是有一种特殊情况,就是hi是0的时候,那么第一个值不是0*(max_lo+1)+0=0
而是lo跳过0从1开始,直接是1、2、3……

 

那max_lo配置多大合适呢?

这要根据具体情况而定,如果系统一般不重启,而且需要用此表建立大量的主键,可以吧max_lo配置大一点,这样可以减少读取数据表wasw100_hilo_tbl的次数,提高效率;反之,如果服务器经常重启,可以吧max_lo配置小一点,可以避免每次重启主键之间的间隔太大,造成主键值主键不连贯。

java设计模式–单例模式 的简单例子

问题域:

–系统中你需要获得某个类的唯一实例,所有客户端对它的访问都将通过一个公共的访问点获得

–创建一个类并使其:(A)定义一个私有的构造器(B)定义一个私有、静态的变量指向自己(C)定义一个公有、静态的访问方法用于返回该类的一个唯一实例

分为 饿汉式 和 懒汉式

,下面是一个简单的示例代码,应该很容易理解:

1、饿汉式代码

package pattern.singleton.basic;

/**
 * java设计模式:单例模式(饿汉式)
 * @author wasw100
 */
public class Singleton {
	// 提供一个静态私有变量指向自己,属于类
	private static Singleton instance = new Singleton();// 提前消费
	// 提供私有构造器,只有在当前类中可以使用new,外界不能构造该类的对象
	private Singleton() {
	}

	// 对外提供一个公共访问点
	public static Singleton getInstance() {
		return instance;
	}
}

2、懒汉式代码

package pattern.singleton.basic;

/**
 * java设计模式:单例模式(懒汉式)
 * @author wasw100
 */
public class Singleton {
	private static Singleton instance = null;
	private Singleton(){}

	//synchronized避免在访问量比较大的时候 第一个线程的new Singleton还没来得及赋值给instance,第二个线程就来了,还要进行new ……
	public synchronized static Singleton getInstance(){
		if(instance == null){
			instance = new Singleton();
		}
		return instance;
	}
}

测试代码

package pattern.singleton.basic;

public class ClientClass {

	public static void main(String [] args){
		Singleton s1 = Singleton.getInstance();
		Singleton s2 = Singleton.getInstance();
		System.out.println(s1);
		System.out.println(s2);
	}
}

输出结果(地址相同,所以指向同一个对象):
pattern.singleton.basic.Singleton@a90653
pattern.singleton.basic.Singleton@a90653

说明:

  • 构造方法是私有的,外部类不能实例化,只能在类的内部实例化
  • 饿汉式在类加载时实例化,懒汉式在第一次程序第一次执行getInstance()方法时实例化
  • 懒汉式中synchronized避免在访问量比较大的时候 第一个线程的new Singleton还没来得及赋值给instance,第二个线程就来了,还要进行new ……

–EOF–

遍历Map的三种方法

遍历Map的三种方法,直接贴代码:

import java.util.HashMap;
import java.util.Map;

/**
 * Map的遍历
 *
 * @author wasw100
 */
public class MapTest {

	public static void main(String[] args) {
		Map<String, Integer> map = new HashMap<String, Integer>();
		map.put("one", 1);
		map.put("two", 2);

		// 通过Map.keySet取得键的集合
		System.out.println("通过Map.keySet遍历:");
		for (String key : map.keySet()) {
			System.out.println("键:" + key + "\t值:" + map.get(key));
		}

		// 通过Map.entrySet遍历
		System.out.println();
		System.out.println("通过Map.entrySet遍历:");
		for (Map.Entry<String, Integer> s : map.entrySet()) {
			System.out.println("键:" + s.getKey() + "\t值:" + s.getValue());
		}

		// 通过Map.values()遍历所有的值,但是不能遍历键
		System.out.println();
		System.out.println("通过Map.values()遍历所有的值:");
		for (Object o : map.values()) {
			Integer i = (Integer) o;
			System.out.println("值:" + i);
		}

	}
}

运行结果:

通过Map.keySet遍历:
键:two	值:2
键:one	值:1

通过Map.entrySet遍历:
键:two	值:2
键:one	值:1

通过Map.values()遍历所有的值:
值:2
值:1

–EOF–

2009年01月29日

做网站多大宽度合适?—看各大门户页面宽度

做网站时页面多大宽度正好呢?

现在1024*768甚至更高的分辨率已成为主流,所以这里只讨论1024*768的分辨率。
不过非要向下兼容我的意见是760-780,不过我更喜欢用760.

下面讨论1024或更大宽度的情况下,先看下各大网站(如有错误,敬请指正):

新浪: 950 px
网易: 960 px
腾讯: 910 px
搜狐: 950 px

校内网: 960px

csdn: 960 px
javaeye: 950 px
sun: 960 px

通过上面几个不同类型的网站,除腾讯用了910px外,其余的不是950px,就是960px。现在大家心中网站用多款心中大体有数了吧。

这里主要要考虑两个因素:视觉效果和用户体验。

从视觉效果来说,屏幕边缘区域并不是用户的有效视觉区域,也就是说,用户很少去看屏幕的边缘地带的。所以我最近在很多国外的网站看到一些100%宽度设计的网站,两边都会留20px左右的空白(而且这样看起来更加舒服)。

而从用户体验来说,太宽的屏幕,意味着一行会有更多的字,这一点是不好的。大家在看报纸或看书的时候会注意到分栏,比如报纸,无论是对开还是4开的报纸,都会分成几栏来显示,如南方都市报是分5栏,每栏15个5号字,这样就很容易阅读,如果不分栏,那么就相当于一行75个字,只有一两行字的话还行,如有二十几行,谁能读下去?!

现在显示器的屏幕越来越宽,如果网页的宽度也一味的宽下去,用户肯定要纠结了!

所以,我认为950-980的页面宽度是最合适的,如果考虑800*600的显示器,则可以考虑向下兼容的设计(不过,据统计,现在使用800*600分辨率的显示器的不到1%)。

参考:http://www.isparkle.cn/?p=47

–EOF–

2009年01月22日

proxool配置及测试(数据库用的MySQL)

Proxool连接池是sourceforge下的一个开源项目,这个项目提供一个健壮、易用的连接池,最为关键的是这个连接池提供监控的功能,方便易用,便于发现连接泄漏的情况。开源项目地址是:http://proxool.sourceforge.net/ 配置连接池比较的简单:

1.需要用到的jar包:i.proxool的下载地址: http://proxool.sourceforge.net/download.html
需要lib文件夹下的两个jar包(目前的版本是:proxool-0.9.1.jar)ii.commons-logging.jar的下载地址:http://commons.apache.org/downloads/download_logging.cgi
解压后用commons-logging-版本号.jar(目前的版本是commons-logging-1.1.1.jar)iii.相应数据库的驱动程序(我用的是:mysql-connector-java-5.1.6-bin.jar)把这些jar包导入工程

2.在 WEB-INF 下,建立一个文件: proxool.xml,内容如下:

<?xml version="1.0" encoding="UTF-8"?>
<!-- the proxool configuration can be embedded within your own application's.
Anything outside the "proxool" tag is ignored. -->

<something-else-entirely>
<proxool>
<alias>mydata</alias>
<driver-url>
jdbc:mysql://localhost:3306/test
</driver-url>
<driver-class>
org.gjt.mm.mysql.Driver
</driver-class>
<driver-properties>
<property name="user" value="root" />
<property name="password" value="root" />
</driver-properties>
<maximum-connection-count>10</maximum-connection-count>
<house-keeping-test-sql>
select CURRENT_DATE
</house-keeping-test-sql>
</proxool>
</something-else-entirely>

3.修改web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<servlet>
<servlet-name>ServletConfigurator</servlet-name>

<servlet-class>
org.logicalcobwebs.proxool.configuration.ServletConfigurator
</servlet-class>

<init-param>
<param-name>xmlFile</param-name>
<param-value>WEB-INF/proxool.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>

<servlet>
<servlet-name>Admin</servlet-name>
<servlet-class>
org.logicalcobwebs.proxool.admin.servlet.AdminServlet
</servlet-class>
</servlet>

<servlet-mapping>
<servlet-name>Admin</servlet-name>
<url-pattern>/Admin</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>

4.测试的jsp文件

<%@ page import="java.sql.*"%>
<%@ page contentType="text/html;charset=GB2312"%>
<html>
<head>
<title>proxool测试</title>
</head>
<body>
<h2>
使用 Proxool Connection Pool,用xml文件配置
</h2>
<%
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
try {
Class.forName("org.logicalcobwebs.proxool.ProxoolDriver");
conn = DriverManager.getConnection("proxool.mydata");
stmt = conn.createStatement();

out.println("<br />数据库连接成功<br /><br />");

String query = "select now()";
rs = stmt.executeQuery(query);

while (rs.next()) {
out.print(rs.getString(1) + "--OK<br />");
}

stmt.close();
conn.close();
} catch (SQLException sqle) {
out.println("sqle=" + sqle);
out.println("<br />数据库连接失败<br /><br />");
} finally {
if(stmt != null){
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(conn != null){
try {
conn.close();
out.println("<br />数据库关闭成功<br />");
} catch (SQLException e) {
e.printStackTrace();
out.println("数据库关闭失败<br />");
}
}
}
%>
</body>
</html>

5、后台统计与信息
请进入:http://127.0.0.1:8080/testproxool/Admin
(testpxool1应改为你的WEB应用程序名)

参考文章:
1.http://www.java3z.com/cwbwebhome/article/article1a/134.jsp?id=213
2.http://www.blogjava.net/mimi-van/archive/2008/03/21/168754.html
3.http://blog.csdn.net/a_heng/archive/2008/07/04/2611585.aspx

–EOF–

2008年12月10日

绿色版MySQL的安装和使用

以下是自己学习MySQL时整理的笔记,希望对学习MySQL同学有用,避免多走弯路

1.下载绿色版MySQL
到官方网站下载最新版的绿色版MySQL(http://dev.mysql.com/downloads/),然后解压到自己想要安装的目录,在解压后的目录中把my-large.ini另存为my.ini,修改数据库的默认编码为UTF-8。在[mysql]和[mysqld]后面添加
default-character-set=utf8
例如:
port = 3306
socket = /tmp/mysql.sock
之后添加
[mysql]
default-character-set=utf8
然后下面
# The MySQL server
[mysqld]
port = 3306
socket = /tmp/mysql.sock
……
# Try number of CPU’s*2 for thread_concurrency
thread_concurrency = 8
之后添加
default-character-set=utf8

2.安装服务:在命令行切换到bin目录下,执行mysqld -install

3.启动(关闭)服务 net start(stop) mysql

4.卸载服务 mysqld -remove

5.给root用户添加(修改密码)密码manage(root初始密码为空)
在bin命令行下输入:
mysqladmin -uroot -p password manage
输入密码时直接按回车(修改时输入原来密码)

6.登陆MySQL
mysql -uroot -pmanage

7.show databases //显示服务器所有数据库 use test;//使用test数据库

8.show tables;//显示所在数据库下所有的表

9.desc mytable;//显示表的组成

10.显示表空间的字符编码
status;

11.更改表的字符集。
mysql> alter table users character set GBK;

12.清空users表中的数据mysql> truncate table users;

13 . SQL语句运用实例:
–1 建users表
create table users (id int primary key auto_increment,nikename varchar(20) not null
unique,password varchar(100) not null,address varchar(200), reg_date timestamp not null
default CURRENT_TIMESTAMP);
–2 建articles表,在建表时设置外键
create table articles (id int primary key auto_increment,content longtext not null,userid
int,constraint foreign key (userid) references users(id) on delete set null);
–2.1 建articles表,建表时不设置外键
create table articles (id int primary key auto_increment,content longtext not null,userid
int);
–2.2 给articles表设置外键
alter table articles add constraint foreign key (userid) references users(id) on delete
set null;
–3. 向users表中插入数据,同时插入多条
insert into users (id,nikename,password,address) values (1,’lyh1′,’1234′,null),
(10,’lyh22′,’4321′,’湖北武汉’),(null,’lyh333′,’5678′,’北京海淀’);
–4. 向article中插入三条数据
insert into articles (id,content,userid) values (2,’hahahahahaha’,11),
(null,’xixixixixix’,10),(13,’aiaiaiaiaiaiaiaiaiaiaiaia’,1),(14,’hohoahaoaoooooooooo’,10);
–5. 进行多表查询,选择users表中ID=10的用户发布的所有留言及该用户的所有信息
select articles.id,articles.content,users.* from users,articles where users.id=10 and
articles.userid=users.id order by articles.id desc;
–6. 查看数据库引擎类型
show create table users;
–7. 修改数据库引擎类型
alter table users engine=MyISAM; —因为users表中ID被设置成外键,执行此句会出错

14.这样建数据库,默认编码是UTF-8
CREATE DATABASE sq_shiyan default character set utf8;

15.创建本地用户
GRANT ALL PRIVILEGES ON sq_shiyan.* to sq_shiyan@localhost IDENTIFIED BY ‘shiyan’;

16.创建远程用户GRANT ALL PRIVILEGES ON sq_shiyan.* to sq_shiyan@”%” IDENTIFIED BY ‘shiyan’;

17.数据库的备份与还原

MySql的备份可用命令mysqldump ,使用方法很简单,mysqldump -u 用户名 -p (密码) -h 主机名 数据
库名 >路径/备份名.bak;同时也可以是用mysqldump到处数据结构(tablename.sql)和数据
(tablename.txt) mysqldump -u 用户名 -p (密码) -h 主机名 数据库名 tablename1 tablename2 >
back.sql或mysqldump -u 用户名 -p (密码) -h 主机名 数据库名 –tab 路径 –opt 数据库名.
EXA:
mysqldump -u pivot -p pivot news > c:\news.sql

那么还原可以mysql命令,mysql -u 用户名 -p (密码) -h 主机名 –one-database 还原数据库名 <
路径/备份名.bak,–one-database是指定要恢复的数据库.
EXA:
mysql -uroot -proot news < c:\news.sql
(括号表示密码不先输入,在连接时在Enter password;若密码为空可缺省-p参数)

–EOF–

返回顶部