MySQL Installation and Access via JDBC

ABSTRACT: MySQL is a nice compact relational database (SQL) server. It tends to be lean, fast, easy to install and configure, and it has become very popular as the back-end database for many web sites with simple demands. There is a tradeoff for MySQL's lean nature: it is missing some advanced features that make it not quite fully ANSI SQL-92 compatible. It is completely lacking transaction support (commit and rollback) as well as fine-level locking. I do not recommend trying to use MySQL for Enterprise Java Beans which we will cover last in this series. For that we will use PostgreSQL.

Outline

Note: This will be so similar to the article on PostgreSQL that I will be copying large sections between the two. If you've already read the other, skip straight to the installation section.

What is a Relational Database (RDBMS) and what is SQL?

Murray's Rant: It's much easier than you might suspect.

Installation: Offering a little bit of help

Configuration: A Quick Tour to Get You Started

Creating Your First Table

The JDBC driver and your first Hello World.

Murray's Rant: It's much easier than you might suspect.

There is a conspiracy out there. I'm sure of it, although I'm not certain who's behind it—probably all the people who stand to make a lot of money.

Have you ever noticed a level of intrigue and mystery whenever computer people use the term Enterprise? What do you think of when you hear that word? Apart from images of Federation Starship on Star Trek, I always used to think of really complicated things that I couldn't possible hope to master on my own. Just take a look at the versions of some of the major development packages like Visual Studio or Visual Cafe.

There's the intro or Standard version, at an affordable price but missing some vital components. Then it's followed by the Professional version, which has all those pieces you missed in the Standard version. Oh, and don't forget that the price tag goes up at least $100 or $200. Then there's the Enterprise version. What does it have? I always used to imagine it had very complicated libraries that would make it possible to perform true wizardry.

Also remember how much these database applications used to cost! You could support a small Mexican village for years with what it costs to license Oracle 8i on a marginally-powered server.

Just wait for disillusionment to hit. And I promise it's a bitch. I recall the first time I looked at an Enterprise version of a major development package that I'd sunk hundreds of dollars from my own wallet to get. All the extra dollars bought were some generic widgets that placed a very restrictive (and often conter-intuitive) representation of some data on a window. I immediately realized that I could make a better widget in very little time with a marginal amount of experience.

Another piece of the grand conspiracy is the lack of simple introductory books to explain relational databases and SQL. They all seem to make SQL programming and database design about as complicated as the rules to Cricket!

Database design and implementation is best learned by doing. Skim some books, but most importantly, get out MySQL's documentation, start up the interactive client program, create some tables, hand-input some sample data, try out some simple queries. I'm not going to pretend that experience wont help you to design better table layouts, but the first ones you try will probably work just fine.

So stop being intimidated. Get a database or two running. Access it from a JSP or Servlet-driven web site. You've got all the tools you need to design powerful Enterprise applications. In a few months you'll be ready to revise your resume and double your fee.

Installation: Offering a little bit of help

Rather than give you specific instructions for building MySQL, I'm going to point to some links where other people have gone through the effort. Feel free to send me e-mail if you feel one of these links has terrible conceptual procedural flaws. Once you believe you have MySQL up and running, proceed to the next section.

http://homepage.mac.com/dylan_neild/FileSharing.html
This person has created a double-clickable installer to get MySQL up and running. Simplicity is a good thing. I haven't had time to evaluate this installer, but if I get enough positive feedback, I'll drop the other items in this list. Actually, at the moment this is the only safe package I can find. Feel free to e-mail me if you know of a better implementation.

Configuration: A Quick Tour to Get You Started

At this point we're going to assume that you've got MySQL up and running, using whatever means necessary. Let's go through a few steps to make sure that the database is in fact up and running. We'll also create a sample database (which we'll use in later articles) and a sample user account.

Our first command: mysql

Perhaps the most useful utility in the MySQL package is the interactive client program called "mysql". It is invoked (from the command line) with the following structure:

mysql [options] database-name

If you want more specific details about the command and its options, you can use the "--help" option...

[murray@elrod murray]$ mysql --help
mysql  Ver 11.13 Distrib 3.23.36, for redhat-linux-gnu (i386)
Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
This software comes with ABSOLUTELY NO WARRANTY. This is free software,
and you are welcome to modify and redistribute it under the GPL license

Usage: mysql [OPTIONS] [database]

  -?, --help		Display this help and exit.
  -A, --no-auto-rehash  No automatic rehashing. One has to use 'rehash' to
			get table and field completion. This gives a quicker
			start of mysql and disables rehashing on reconnect.
  -B, --batch		Print results with a tab as separator, each row on
			a new line. Doesn't use history file.
  --character-sets-dir=...
                        Directory where character sets are located.
  -C, --compress	Use compression in server/client protocol.
  -D, --database=..	Database to use.
  --default-character-set=...
                        Set the default character set.
  -e, --execute=...     Execute command and quit. (Output like with --batch)
  -E, --vertical        Print the output of a query (rows) vertically.
  -f, --force           Continue even if we get an sql error.
  -g, --no-named-commands
			Named commands are disabled. Use \* form only, or
                        use named commands only in the beginning of a line
                        ending with a semicolon (;) Since version 10.9 the
                        client now starts with this option ENABLED by
                        default! Disable with '-G'. Long format commands
                        still work from the first line.
  -G, --enable-named-commands
                        Named commands are enabled. Opposite to -g.
  -i, --ignore-space	Ignore space after function names.
  -h, --host=...	Connect to host.
  -H, --html		Produce HTML output.
  -L, --skip-line-numbers
                        Don't write line number for errors.
  --no-pager            Disable pager and print to stdout. See interactive
                        help (\h) also.
  --no-tee              Disable outfile. See interactive help (\h) also.
  -n, --unbuffered	Flush buffer after each query.
  -N, --skip-column-names
                        Don't write column names in results.
  -O, --set-variable var=option
			Give a variable an value. --help lists variables.
  -o, --one-database	Only update the default database. This is useful
			for skipping updates to other database in the update
			log.
  --pager[=...]         Pager to use to display results. If you don't supply
                        an option the default pager is taken from your ENV
                        variable PAGER ().
                        Valid pagers are less, more, cat [> filename], etc.
                        See interactive help (\h) also. This option does
                        not work in batch mode.
  -p[password], --password[=...]
			Password to use when connecting to server
			If password is not given it's asked from the tty.

  -P, --port=...	Port number to use for connection.
  -q, --quick		Don't cache result, print it row by row. This may
			slow down the server if the output is suspended.
			Doesn't use history file.
  -r, --raw		Write fields without conversion. Used with --batch
  -s, --silent		Be more silent.
  -S  --socket=...	Socket file to use for connection.
  -t, --table		Output in table format.
  -T, --debug-info	Print some debug info at exit.
  --tee=...             Append everything into outfile. See interactive help
                        (\h) also. Does not work in batch mode.
  -u, --user=#		User for login if not current user.
  -U, --safe-updates[=#], --i-am-a-dummy[=#]
		        Only allow UPDATE and DELETE that uses keys.
  -v, --verbose		Write more. (-v -v -v gives the table output format)
  -V, --version		Output version information and exit.
  -w, --wait		Wait and retry if connection is down.

Default options are read from the following files in the given order:
/etc/my.cnf /var/lib/mysql/my.cnf ~/.my.cnf 
The following groups are read: mysql client
The following options may be given as the first argument:
--print-defaults	Print the program argument list and exit
--no-defaults		Don't read default options from any options file
--defaults-file=#	Only read default options from the given file #
--defaults-extra-file=# Read this file after the global files are read

Possible variables for option --set-variable (-O) are:
connect_timeout       current value: 0
max_allowed_packet    current value: 16777216
net_buffer_length     current value: 16384
select_limit          current value: 1000
max_join_size         current value: 1000000
[murray@elrod murray]$ 

Try the above example. Did it work? If not, you haven't gotten MySQL properly installed yet. A good bet is to find out where the "mysql" program is and make sure its directory is included in your PATH.

Assuming you have the mysql command working, let's try invoking the program. When first installed, MySQL will always have a database called "mysql" where it keeps tables that define user accounts, known hosts and permission tables. The simplest command would thus be

mysql mysql

Where the first instance is the name of the client program and the second "mysql" is the database name. Try it, and don't be surprised if you get an error. Let's list a few of the likely messages you might get...

[murray@elrod murray]$ mysql mysql
ERROR 2002: Can't connect to local MySQL server through socket 
'/var/lib/mysql/mysql.sock' (2)

This message (or something resembling it) is a good indicator that your MySQL database daemon (service) isn't running. Your MySQL installation might have been nice enough to start MySQL up automatically. If not, you might have to manually start it every time you restart your computer.

[murray@elrod murray]$ mysql mysql
ERROR 1044: Access denied for user: '@localhost' to database 'mysql'

You are likely to stare at this message many times in the future. On the bright side, it does indicate that the MySQL service is running. The error just means you don't have permission to connect to the database. Unless you have been logged on as root (or used the "su" command) this is actually expected. When you invoke the mysql command, it sends your current username—mine is "murray"—to the server for authentication. On most installations, MySQL will only be configured to understand the username "root". Let's try that command again, but identify ourselves as root:

[murray@elrod murray]$ mysql mysql -uroot
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 2 to server version: 3.23.36

Type 'help;' or '\h' for help. Type '\c' to clear the buffer

mysql> quit

Isn't that nice? Actually, I'm hoping your eyebrows just raised in concern. We just told MySQL that we were "root" and it happily took our word for it without asking for a password? Can you say "insecure"? Let's take this opportunity to fix things. Quit from the mysql program (see the above example) and let's use our second useful utility: mysqladmin.

Administration with mysqladmin

Again, this program will give you instructions on its use if you invoke it with the "--help" option.

[murray@elrod murray]$ mysqladmin --help
mysqladmin  Ver 8.18 Distrib 3.23.36, for redhat-linux-gnu on i386
Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
This software comes with ABSOLUTELY NO WARRANTY. This is free software,
and you are welcome to modify and redistribute it under the GPL license

Administration program for the mysqld daemon.
Usage: mysqladmin [OPTIONS] command command....

  -#, --debug=...       Output debug log. Often this is 'd:t:o,filename`
  -f, --force		Don't ask for confirmation on drop database; with
			multiple commands, continue even if an error occurs
  -?, --help		Display this help and exit
  --character-sets-dir=...
                        Set the character set directory
  -C, --compress        Use compression in server/client protocol
  -h, --host=#		Connect to host
  -p, --password[=...]	Password to use when connecting to server
			If password is not given it's asked from the tty
  -P  --port=...	Port number to use for connection
  -i, --sleep=sec	Execute commands again and again with a sleep between
  -r, --relative        Show difference between current and previous values
                        when used with -i. Currently works only with
                        extended-status
  -E, --vertical        Print output vertically. Is similar to --relative,
                        but prints output vertically.
  -s, --silent		Silently exit if one can't connect to server
  -S, --socket=...	Socket file to use for connection
  -t, --timeout=...	Timeout for connection to the mysqld server
  -u, --user=#		User for login if not current user
  -v, --verbose         Write more information
  -V, --version		Output version information and exit
  -w, --wait[=retries]  Wait and retry if connection is down

Default options are read from the following files in the given order:
/etc/my.cnf /var/lib/mysql/my.cnf ~/.my.cnf 
The following groups are read: mysqladmin client
The following options may be given as the first argument:
--print-defaults	Print the program argument list and exit
--no-defaults		Don't read default options from any options file
--defaults-file=#	Only read default options from the given file #
--defaults-extra-file=# Read this file after the global files are read

Possible variables for option --set-variable (-O) are:
connect_timeout       current value: 0
shutdown_timeout      current value: 3600

Where command is a one or more of: (Commands may be shortened)
  create databasename	Create a new database
  drop databasename	Delete a database and all its tables
  extended-status       Gives an extended status message from the server
  flush-hosts           Flush all cached hosts
  flush-logs            Flush all logs
  flush-status		Clear status variables
  flush-tables          Flush all tables
  flush-threads         Flush the thread cache
  flush-privileges      Reload grant tables (same as reload)
  kill id,id,...	Kill mysql threads
  password new-password Change old password to new-password
  ping			Check if mysqld is alive
  processlist		Show list of active threads in server
  reload		Reload grant tables
  refresh		Flush all tables and close and open logfiles
  shutdown		Take server down
  status		Gives a short status message from the server
  start-slave		Start slave
  stop-slave		Stop slave
  variables             Prints variables available
  version		Get version info from server
[murray@elrod murray]$ 

Let's use our mysqladmin program to set root's password.

[murray@elrod murray]$ mysqladmin -uroot password Willow

Now, let's try to log in as root again.

[murray@elrod murray]$ mysql mysql -uroot
ERROR 1045: Access denied for user: 'root@localhost' (Using password: NO)

Yea, we were rejected! (Well, occasionally that's a good thing!) Let's now try to log on using our new password (Willow).

[murray@elrod murray]$ mysql mysql -uroot -pWillow
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 5 to server version: 3.23.36

Type 'help;' or '\h' for help. Type '\c' to clear the buffer

mysql>

Now, while we're here, let's create the database which we'll use for later. (You should keep it around, for further articles will build on top of this example.)

mysql> create database videos;
Query OK, 1 row affected (0.01 sec)

Next, we'll create a special user account that will be used to access this new database.

A Quick Tour of the Permission Tables

Now is a good time to find the documentation for MySQL. Why? Because an important part of any database configuration has to do with you permissions and account access is setup. MySQL has a very powerful permissions system that allows you to define what a user can and cannot do to a very fine level of detail. This system involves a set of cascading rules that are clean and powerful, but take some careful study. If you are not ready to read the chapter in the MySQL documentation about this system, at least make a note of where the chapter can be found and commit yourself to reading it within the next week!

All database access is managed though a few small tables located in the "mysql" database. We can examine these tables using the "show tables" command.

mysql> show tables;
+-----------------+
| Tables_in_mysql |
+-----------------+
| columns_priv    |
| db              |
| func            |
| host            |
| tables_priv     |
| user            |
+-----------------+
6 rows in set (0.00 sec)

mysql>

In order to create a new user account, we simply need to add a record (or two) in the user table. We can view the table with the following SQL command:

mysql> select * from user;
+-----------------------+------+------------------+-------------+-------------+-------------+-------------+-------------+-----------+-------------+---------------+--------------+-----------+------------+-----------------+------------+------------+
| Host                  | User | Password         | Select_priv | Insert_priv | Update_priv | Delete_priv | Create_priv | Drop_priv | Reload_priv | Shutdown_priv | Process_priv | File_priv | Grant_priv | References_priv | Index_priv | Alter_priv |
+-----------------------+------+------------------+-------------+-------------+-------------+-------------+-------------+-----------+-------------+---------------+--------------+-----------+------------+-----------------+------------+------------+
| localhost             | root | 49dd0bc003a8d5c5 | Y           | Y           | Y           | Y           | Y           | Y         | Y           | Y             | Y            | Y         | Y          | Y               | Y          | Y          |
| localhost             |      |                  | N           | N           | N           | N           | N           | N         | N           | N             | N            | N         | N          | N               | N          | N          |
+-----------------------+------+------------------+-------------+-------------+-------------+-------------+-------------+-----------+-------------+---------------+--------------+-----------+------------+-----------------+------------+------------+
4 rows in set (0.00 sec)

mysql> 

You can see the root password (Willow) that we set earlier with the mysqladmin command. Actually, you don't see the word "Willow" but rather some fancy encrypted version of the password. Now, we'll create an account called vidadmin with the password Xander which we'll use for all account access.

mysql> insert into user values ('localhost','vidadmin',password('Xander'),'N','N','N','N','N','N','N','N','N','N','N','N','N','N');
Query OK, 1 row affected (0.01 sec)

mysql> select * from user;
+-----------------------+----------+------------------+-------------+-------------+-------------+-------------+-------------+-----------+-------------+---------------+--------------+-----------+------------+-----------------+------------+------------+
| Host                  | User     | Password         | Select_priv | Insert_priv | Update_priv | Delete_priv | Create_priv | Drop_priv | Reload_priv | Shutdown_priv | Process_priv | File_priv | Grant_priv | References_priv | Index_priv | Alter_priv |
+-----------------------+----------+------------------+-------------+-------------+-------------+-------------+-------------+-----------+-------------+---------------+--------------+-----------+------------+-----------------+------------+------------+
| localhost             | root     | 49dd0bc003a8d5c5 | Y           | Y           | Y           | Y           | Y           | Y         | Y           | Y             | Y            | Y         | Y          | Y               | Y          | Y          |
| localhost             |          |                  | N           | N           | N           | N           | N           | N         | N           | N             | N            | N         | N          | N               | N          | N          |
| localhost             | vidadmin | 0c40d4c87112ba73 | N           | N           | N           | N           | N           | N         | N           | N             | N            | N         | N          | N               | N          | N          |
+-----------------------+----------+------------------+-------------+-------------+-------------+-------------+-------------+-----------+-------------+---------------+--------------+-----------+------------+-----------------+------------+------------+
6 rows in set (0.00 sec)

mysql> 

We have just defined a user account, assigned its password, and disabled all default access. This prevents someone who might gain access to the vidadmin password from doing any harm to the entire MySQL system. If we had instead put all "Y" values in the insert command, then vidadmin would basically have root-equivalent access to all databases.

But we want to do something with vidadmin, so it needs some permissions, right? Correct. We'll add a line to the "db" table which will give vidadmin unlimited access but only to the videos database.

mysql> select * from db;
+------+---------+------+-------------+-------------+-------------+-------------+-------------+-----------+------------+-----------------+------------+------------+
| Host | Db      | User | Select_priv | Insert_priv | Update_priv | Delete_priv | Create_priv | Drop_priv | Grant_priv | References_priv | Index_priv | Alter_priv |
+------+---------+------+-------------+-------------+-------------+-------------+-------------+-----------+------------+-----------------+------------+------------+
| %    | test    |      | Y           | Y           | Y           | Y           | Y           | Y         | N          | Y               | Y          | Y          |
| %    | test\_% |      | Y           | Y           | Y           | Y           | Y           | Y         | N          | Y               | Y          | Y          |
+------+---------+------+-------------+-------------+-------------+-------------+-------------+-----------+------------+-----------------+------------+------------+
2 rows in set (0.00 sec)

mysql> insert into db values ('%','videos','vidadmin','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y'); 
Query OK, 1 row affected (0.01 sec)

mysql> select * from db;
+------+---------+----------+-------------+-------------+-------------+-------------+-------------+-----------+------------+-----------------+------------+------------+
| Host | Db      | User     | Select_priv | Insert_priv | Update_priv | Delete_priv | Create_priv | Drop_priv | Grant_priv | References_priv | Index_priv | Alter_priv |
+------+---------+----------+-------------+-------------+-------------+-------------+-------------+-----------+------------+-----------------+------------+------------+
| %    | test    |          | Y           | Y           | Y           | Y           | Y           | Y         | N          | Y               | Y          | Y          |
| %    | test\_% |          | Y           | Y           | Y           | Y           | Y           | Y         | N          | Y               | Y          | Y          |
| %    | videos  | vidadmin | Y           | Y           | Y           | Y           | Y           | Y         | Y          | Y               | Y          | Y          |
+------+---------+----------+-------------+-------------+-------------+-------------+-------------+-----------+------------+-----------------+------------+------------+
4 rows in set (0.00 sec)

mysql> 

We're almost done, but there's one important step left. You see, you can change these tables all you want, but until the MySQL service reloads its permissions, nothing will happen. This is important to remember! I've wasted huge amounts of time trying to tweak with the permissions tables, testing every possible permutation with no result because I would forget to flush the privileges.

mysql> flush privileges;
Query OK, 1 row affected (0.01 sec)

Creating Your First Table

All database applications are not created equal. Despite the fact that standards like ODBC, JDBC and SQL-92 exist, there are some pretty damned massive differences between how any two database applications work. Still, for the most part you can still write programs that will operate almost seamlessly with any major relational database.

One thing that causes me the biggest problems is the creation of new tables. The structure of the CREATE TABLE command is basically standardized, there are all sorts of options and settings that are specific to each database application.

Note: I'm trying to be careful with my terminology. It's important to distinguish between a Database Application and a Database. The Database Application is the large piece of software that stores data (usually) on a hard disk. Examples are MySQL, PostgreSQL, OracleTM, Microsoft SQL ServerTM, IBM DB/2TM, etc. Each Database Application can manage multiple Databases. In this case, we've seen that MySQL manages a default database called "mysql" and our new database called "videos".

I have almost never written a Java program that created a new table through a JDBC call. Instead, I always start up the "mysql" client program and hand build the tables. In fact, I have a very methodical process that I follow, and I suggest you adopt it as your own.

The CREATE TABLE command is always a very long one, filling many lines for a single command. To make matters worse, it always takes me a number of attempts before I can get the command right without errors. Typing the command out manually is a real pain, especially if you have to do it over and over and over...

Instead, I pull up a friendly text editor (like Emacs or vi) and "build" the command in a text file. When I think I have the command right, I try to batch-execute the file. There are many distinct advantages to this:

  1. The obvious advantage of minimizing work, working fastest, etc.
  2. You have a record of how you built the table exactly. You might have to do it again, and it's good to keep a record of all the options and parameters you used.
  3. You have something to look at when you find yourself writing the same CREATE TABLE command for a different Database Application. If you follow the other article on PostgreSQL, you will see how different the tables are.

So, open a second terminal window (Apple-N is a nice shortcut) and make sure that both terminals are set to the same directory. You can work in your home directory right now.

In the second terminal, open a file (I called mine create_table_mysql.txt) in vi or Emacs. Here are the commands to build our first three tables:

CREATE TABLE members (
  name     VARCHAR(32) NOT NULL,
  address  VARCHAR(40) NOT NULL,
  credits  INTEGER NOT NULL DEFAULT 3,
  loaned   INTEGER NOT NULL DEFAULT 0,
  capacity INTEGER NOT NULL DEFAULT 5,
  PRIMARY KEY(name)
);

CREATE TABLE movies (
  title    VARCHAR(20) NOT NULL,
  year     YEAR NULL,
  PRIMARY KEY(title)
);

CREATE TABLE tapes (
  owner    VARCHAR(32) NOT NULL,
  title    VARCHAR(20) NOT NULL,
  borrower VARCHAR(32) NOT NULL,
  due      DATE NULL,
  format   enum("VHS","DVD") NOT NULL DEFAULT "VHS",
  region   INTEGER NULL,
  PRIMARY KEY(owner,title),
  KEY(borrower)
);

To save you time, you might just choose to download my file rather than retype the whole thing. Next, access the videos database as vidadmin via the mysql command.

[murray@elrod murray]$ mysql videos -uvidadmin -pXander;
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 3 to server version: 3.23.36

Type 'help;' or '\h' for help. Type '\c' to clear the buffer

mysql> source create_table_mysql.txt
Query OK, 0 rows affected (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

mysql> show tables;
+------------------+
| Tables_in_videos |
+------------------+
| members          |
| movies           |
| tapes            |
+------------------+
3 rows in set (0.00 sec)

mysql> 

The JDBC driver and your first Hello World

We now have a functional database with its own administrative account and three brand new tables. Now what? Well, just as we've carefully run tests along the way to make sure everything running properly, why don't we make sure the JDBC driver is working properly and that we know the proper connection URL? Trust me: every little test we've done is based on what I've empirically had to do to troubleshoot MySQL and get it running on any new system. This next step is as important as any.

Getting the JDBC driver

Go to the MySQL Web Site's JDBC Page and grab the file called mm.mysql.jdbc-2.0pre5.tar.gz and unpack it somewhere. There are a number of JAR files in that package's root directory. The files starting with mysql_1_* and mysql_both_* can and should be thrown away. The "1" files have JDBC drivers for an outdated Java specification and simply wont work. The "both" files have both old and new protocols, but since the old ones are worthless, it's still a waste of space.

That leaves you with mysql_2_comp.jar and mysql_2_uncomp.jar. The first is a compressed JAR file. The Mac OS X Java virtual machine can handle compressed JAR files just fine, so it doesn't matter. Since I've been working with Java for years, I'm used to old habits which means I would personally use the uncompressed files. It's up to you.

Now place the JAR file somewhere permanent. I'm likely to place it in my /Library/Tomcat/lib directory, in anticipation of using it with Tomcat. If you haven't already installed Tomcat, this isn't going to help you out much, is it?

Next I'm going to set the CLASSPATH environment variable to point to the JAR file.

[murray@elrod murray]$ setenv CLASSPATH ".:/Library/Tomcat/mysql_2_comp.jar"

Don't forget to change "/Library/Tomcat" to the proper location of your driver. Also, you might want to rename the JAR file simply "mysql.jar" or "myjdbc.jar". Personally, I would, but I'm trying to keep the examples simple.

Now it's time to write and execute a Java program. I'm going to start the program very simple and add pieces as I go along. This has always been my personal style for coding when I anticipate some substantial debugging.

Find a friendly directory (like your home directory), open a terminal window, and edit a file. In complete lack of originality, let's call it HelloWorld.java. Let's look at Version 1 of the program:

import java.sql.*;

public class HelloWorld
{
    public static void main(String Args[])
    {

    }
}

Save the file and try to compile and run it.

[murray@elrod devel]$ javac HelloWorld.java
[murray@elrod devel]$ java HelloWorld

Now that we know we've got the java compiler and jvm working, let's start with our first JDBC challenge: loading the proper driver class. For the MySQL JDBC driver, the class is org.gjt.mm.mysql.Driver. Let's add some code to load the driver properly...

import java.sql.*;

public class HelloWorld
{
    public static void main(String Args[])
    {
	try {
	    Class.forName("org.gjt.mm.mysql.Driver").newInstance();
	}
	catch (Exception e) {
	    System.err.println("Unable to load driver.");
	    System.err.println(e);
	    e.printStackTrace();
	    System.exit(-1);
	}
	System.out.println("Driver loaded okay.");
    }
}

Now try to compile and run the program. If you get errors, you probably haven't set your CLASSPATH correctly. Next we actually have to establish a connection to the MySQL database. We'll add the connection code next:

import java.sql.*;

public class HelloWorld
{
    static String ConnectURL="jdbc:mysql:///videos?user=vidadmin&password=Xander";

    public static void main(String Args[])
    {
	try {
	    Class.forName("org.gjt.mm.mysql.Driver").newInstance();
	}
	catch (Exception e) {
	    System.err.println("Unable to load driver.");
	    System.err.println(e);
	    e.printStackTrace();
	}
	System.out.println("Driver loaded okay.");
	try {
	    Connection conn = DriverManager.getConnection(ConnectURL);
        }
	catch (SQLException e) {
	    System.err.println("Driver can't get a connection.");
	    e.printStackTrace();
	    System.err.println("SQLExecption: " + e.getMessage());
	    System.err.println("SQLState:     " + e.getSQLState());
	    System.err.println("VendorError:  " + e.getErrorCode());
	    System.exit(-1);
	}
	System.out.println("We have a connection!");
    }
}

Notice the connection URL that I defined at the beginning of the program. There is some nice documentation in the "docs" directory of the JDBC Driver that you unpacked. It has a very nice description of URL and all its options. (Of course, you can probably infer all that you might need from this example.)

If everything runs without a hitch, you should see...

[murray@elrod devel]$ java HelloWorld
Driver loaded okay.
We have a connection!

If you're getting errors, they should be verbose enough to give you clues to finding the problem. Ask yourself

  1. Is the MySQL service up and running?
  2. Is the user account and its password valid?
  3. Has the database been created?

Congratulations!

If you've made it this far, you should give yourself a pat on the back. You've set up a database under Mac OS X and you've taken the first few steps to making it do something. Here's the point at which I pass that baton on to a more experienced author. Go find yourself some good books on databases and JDBC and have fun. You should have the tools needed to implement almost any examples that your books provide.

Web Links and Mailing Lists

Official Sites:

MySQL Homepage

Mailing Lists:

MySQL Mailing Lists

Mac OS X Installation links:

MySQL Package Installer for OS X

Bibliography

MySQL & mSQL by Randy Jay Yarger, George Reese & Tim King. ©1999 O'Reilly.

Database Programming with JDBC and Java by George Reese. 2nd Edition ©2000 O'Reilly.