22 May 2009

Creating a MySQL Database on an External Drive - Things I will forget [002]

The harddrive on my laptop is filling up and I have a client who's database runs into the gigs (per dataset). So I created a MySQL database on an external harddrive a while ago, but now need to do it again (the harddrive is flaky) and have forgotten how to do it. I seem to be looking in the wrong places, so maybe if I write this blog other people searching for the same thing will find it and be able to use it. I will be able to do it next time without searching too!


Well, its actually quite easy. I first tried to create a separate configuration file like I did the previous occasion, but this means not being able to store the config file on the disk: mysql requires that the config file not be world writeable, but by default the external hardrive is mounted with all files world read/writeable. So rather than mess about with the fstab and change the way it is mounted, I opted for specifying the options on the command line.

So this is what I had to do:


First I created I directory where the MySQL database would reside, all further commands are run from that directory.

I then created a data directory store the databases:

mkdir data

I the ran mysql_install_db to initialize the MySQL database tables:
mysql_install_db --ldata=data

Then I could start the database (remember to shutdown your other mysql database if it is running, else specify a different port for this databse to run on):

mysqld --pid-file=./mysqld.pid --socket=./mysqld.sock --datadir=./data

I put this into a 'start.sh' script.

The socket file will be created in the data directory (data/mysqld.sock.
You can then connect to the database like this:

mysql --user=root --socket=./data/mysqld.sock

If you want access to the MYSQL tables use --user=root, else create your own users etc. If you want to use the MySWL Administrator and MySQL Query Browser graphical front ends, make sure you specify the socket file:


Shutdown the database using the following command:

sudo mysqladmin shutdown -S ./data/mysqld.sock

It bothers me that I have to shut it down using sudo, I'll look for a work around when it starts to really irritate me.

Now to wait for the 8 Gig of data to load.

On a side note: I don't think Acid Mothers Temple is the best band to listen to while programming, my brother might disagree..

 <<Blog as memory>>

06 May 2009

Creating a JEE application in Netbeans 6.5

This is the first thing I do when giving a course on JEE: I open up Netbeans, create a JEE project, create a JavaDB database, create a JPA persistance unit, create an entity bean, create a session bean, create a servlet, create a JSP page and create a cutsom tag (all associated with the entity bean created).

This is a great help to the students as it gives them the overview of what we will be working with and shows them how quick and easy it is to create a JEE application in Netbeans - It takes the complexity fear out of them (to a certain extent).

I thought it would be a great help if this were available as a blog for others to follow. Comments will be most welcome, but not that this is pretty much off the cuff and bares no relevence to a real application.

I'll provide a time line to give you an idea of speed, my slow laptop and making it up as I go along should handicap my normal coding dexterity :)

10:51 - music selection, hmm, Black Keys, Brian Eno and David Byrne, Cake.
Ahh, Thickfreakness!


10:55 - Project creation
New Project -> Java EE -> Enterprise Application
I'm calling it BooksDemo
Using the defaults: Glassfish V2, Java EE 5, Create EJB Module, Create Web Application Module

This will create three projects - BooksDemo 'containing' BooksDemo-ejb and BooksDemo-war

11:02 - Create the Datastore

Under Databases in your 'services' tag, right click on 'Java DB' and select 'Create Database' and create a database called 'BooksDemo' with username and password set to 'books' (I've found it doesn't work so well to not have username and password - go figure).

The creation will also start the database, if you go back to the services tab, you will be able to open and view the database.

Back to the project tab: select 'BooksDemo-ejb', right click -> new -> other -> Persistance -> Persistence Unit - > Next
I use the default unit name (BooksDemo-ejbPU) and for datasource select 'New Data Source' at the bottom of the dropdown. Then select the BooksDemo database you created earlier and make the JNDI name 'jdbc/booksDemo', leave the rest as default and finish.

Now for the Entity Object:
Back to the project tab: select 'BooksDemo-ejb', right click -> new -> other -> Persistance -> Entity Class -> Next

Classname 'Book', package 'com.example.book.model' the rest default and finish.

In the Book class, create a new field 'name' as a String field: <alt>INSERT -> Add Property: make the name 'name' and select OK.

11:15 - Create the SessionBean

(Brian Eno is a genius)

In the project tab: select 'BooksDemo-ejb', right click -> new -> other ->Java EE -> Session Bean -> Next

Call it 'BookService', package 'com.example.book.service', the rest default.

Now we are going to create two 'business' methods: getAll and add for retrieving all books and add a book to the datastore.

<ALT>INSERT -> Add Business Method with name 'getAll' with return type 'List<Book>'

<ALT>INSERT -> Add Business Method with name 'add' and add a parameters called 'book' of type 'Book'.

Next fix the imports - <CTRL>-<SHIFT>-I (in the interface as well)


Next we need a handle on the persistance unit: Right click in the BookServiceBean -> Persistence -> Use Entity Manager

You will now have something like the diagram above.

Now we need to use the EntityManager to store and retrieve the books: for the getAll method:

return em.createQuery("select b from Book b").getResultList();

for the add method:

em.persist(book);

11:31 - The Web

We are going to edit the index.jsp ading a form to add a book and retrieve a list of books.

hmm, we need a Servlet to act as the action storing the book first:

On the 'BooksDemo-war' (note its 'war', dammit) right click -> new -> other -> Web -> Servlet -> Next

Class Name: 'BookAdd'
package: 'com.example.book.web.action'

the rest is default, click 'next' and 'finish' (note that the servlet will be called using '/BookAdd' in the URL.

Add the SessionBean by <ALT>-INSERT (in the servlet class) -> Call Enterprise Bean and select the BookServiceBean and OK.

Edit the 'processRequest' method, take everything out and replace it with the following:

Book book = new Book();
book.setName(request.getParameter("name"));
bookServiceBean.add(book);
response.sendRedirect("index.jsp");

We can see if we are on the right track so far: in the project tab, select the 'BooksDemo' projec, right click and 'Run'

This took me 1 min 6 sec..

You should see 'Hello World!' in your browser, this is the index.jsp we haven't edited yet.

Add 'BookAdd?name=test' to the URL in the browser navigation thingy, you should be redirected to the index page, so you will not see anything of value in the browser. this is good. if you see stack traces, bummer.

Go to the Services tab, select Database, select the BooksDemo database, Tables, Book -> right click -> View Data, you should see a record in the table with the name 'test', Hurrah!

11:50 - The index.jsp



Under 'Web Pages' in the 'BooksDemo-war' project you will find the index.jsp page, open it and add the following code after '<h1>Hello World!</h1>':

<form method="post" action="BookAdd">
<input name="name"/>
<button type="submit">add</button>
</form>

Save it, reload your browser and you should see a form with one input field and an 'add' button, enter a name for a new book and press 'add'. Check that you have a new record in the database.


Custom Tag

On the 'BooksDemo-war' right click -> new -> other -> Web -> Tag Library Descriptor -> next

TLD Name: books
default for the rest and click 'finish'
On the 'BooksDemo-war' right click -> new -> other -> Web ->Tag Handler -> Next

Class Name: BookTag
Package: com.example.book.web.tag
default for the rest and click 'Next'

TLD File: WEB-INF/tlds/books.tld (browse to it)
Tag Name: book
default for the rest and click 'finish'

In the BookTag class, <ALT>-INSERT -> Call Enterprise Bean and select BookServiceBean.

Next, remove everything from the 'doTag' method and add the following:

BookServiceLocal bookServiceBean = lookupBookServiceBean();
List<Book> books = bookServiceBean.getAll();
for(Book book: books){
getJspContext().setAttribute("book", book);
getJspBody().invoke(null);
}

You will also need to throw the IOException.

Back to index.jsp,at the top of the page add the following directive:

under the '<%@page' directive,
<%@taglib uri="/WEB-INF/tlds/books" prefix="b"%>

Note: you can <CTRL>-SPACE to auto complete the uri.

(sheep go to heaven, goats go to hell)

Then add the following under the form:

<hr/>
<table>
<tr>
<th>name</th>
</tr>
<b:book>
<tr>
<td>${book.name}</td>
</tr>
</b:book>
</table>


If you reload your browser you should have a list of your book under the form:
And at 12:09, thats a wrap.
At just under two hours, I don't think its that bad for getting a trivial application up and running (bear in mind I did not prepare for this, so some time was spent thinking each step through), if you had to do it by hand it would be more of a headache. Netbeans adds a lot of value to creating these applications.

The project seems to slow down once we reach the web side of things, but maybe one day we'll have a better way of creating web applications :)