JSP教学
很长时间没有贴代码了,虽然一直在写代码.这次,贴一下昨天的代码片断.
任务:图书馆新进了一批图书,数量是500多本,图书馆已经根据书商提高的书目,进行初步加工,补上了简单的编目,加入了出版年份之类,以符合图书馆系统书目记录的核心字段。要求用程序自动导入到图书馆系统。
原文是excel格式。
图书馆系统的后台数据库是oracle 10g。初步考虑有2种方案,第一种是将数据导入到文本文件,由oracle的数据导入功能实现导入。这种办法,前几年就使用过。第二种方法,提高java文件读写功能,读入各条记录,用java文件通过图书馆系统写入后台数据库。
由于第二种方法,以前还没有使用过,觉得有必要补充这一块的知识,因此采用了第二种方法。
首先,将excel文件中的数据另存到文本文件,以默认的制表符分隔字段。book2005.txt条目如下:
书架号 序号 书 名 作者 类别 索书号 ISBN 出版社 价格 出版年份
102 110 关贸总协定和世贸组织的法理(第二版) 杰克森(Jackson) 经济 F743-53/102 7-04-011672-3 高等教育 40.00 2002
102 139 沃顿创业第1书 约翰·拉斯克 经济 F270/102 7-04-015906-6 高等教育 25.00 2004.11
102 140 持?煜? 凯文·肯尼迪 经济 F276.6/102 7-04-015821-3 高等教育 32.00 2004.11
102 143 十倍速可持续成长 周仲庚 经济 F276.6/102 7-04-015953-8 高等教育 35.00 2004.1
.......
每条记录,共10个字段,其中前2个字段不需要。
其次,代码编写。考虑方法是通过java io将数据读入,每条记录读入到一个长度为10的String[],所有的记录合成String[][]。最后,提过原有的Spring+Hibernate代码导入到数据库。
为了快速,编码直接在Junit测试文件上进行。
package elib.dao;
import java.util.List;
import junit.framework.TestCase;
import java.math.BigDecimal;
import elib.service.*;
import elib.FileUtil;
import java.io.IOException;
import java.io.*;
import elib.DigitUtil;
import elib.ElibUtil;
// added by hofman on 2005-12-06
/* BaseDAOTest.java 是Junit TestCase文件的扩展文件,初始化了对Spring调度的各种beans的调用能力。
*/
public class FileTest extends BaseDAOTest {
public void testReadFile() throws IOException {
String filename = "/upload/book2005.txt";
File file = new File(filename);
BufferedReader br = new BufferedReader(new FileReader(file));
StringBuffer sb = new StringBuffer();
String line = null;
int i= 0;
String[][] recs = new String[535][10];
String[] rec = null;
while ((line = br.readLine()) != null) {
// 每行是一条记录,一条记录的各个字段由tab分隔。
rec = line.split("\\t");
// 将单条记录导入记录集合
for(int j=0; j<10;j++) {
recs<i>[j] = rec[j];
}
i++;
if(i == 535) break;
}
br.close();
//数据读入验证
//if(recs.length < 535) return;
//assertEquals(535, i);
// assertEquals("文学", recs[2][4]);
//assertEquals("2003.4", recs[299][9]);
Book book;
BigDecimal bid = new BigDecimal("82000");
String cdate = ElibUtil.getDate();
int k;
for( k=0;k<241;k++) {
book = new Book();
bid = bid.add(oneVal);
book.setBookid(bid);
book.setBookname(recs[k][2]);
book.setAuthor(recs[k][3]);
book.setSubject(recs[k][4]);
book.setCheckout(recs[k][5]);
book.setIsbn(recs[k][6]);
book.setPublisher(recs[k][7]);
// price是BigDecimal类型,此处进行验证
String sprice = recs[k][8];
BigDecimal price = DigitUtil.stringToBigDecimal(sprice);
// 跳过不合格的记录
if(price == null) continue;
book.setPrice(price);
book.setCopyyear(recs[k][9]);
book.setCdate(cdate);
book.setMdate(cdate);
// 调用service相关代码,导入数据
bMgr.addBook(book);
}
assertEquals(535, k);
}
protected void setUp() throws Exception {
super.setUp();
}
protected void tearDown() throws Exception {
super.tearDown();
}
public static void main(String[] args) {
junit.swingui.TestRunner.run(FileTest.class);
}
}
任务:图书馆新进了一批图书,数量是500多本,图书馆已经根据书商提高的书目,进行初步加工,补上了简单的编目,加入了出版年份之类,以符合图书馆系统书目记录的核心字段。要求用程序自动导入到图书馆系统。
原文是excel格式。
图书馆系统的后台数据库是oracle 10g。初步考虑有2种方案,第一种是将数据导入到文本文件,由oracle的数据导入功能实现导入。这种办法,前几年就使用过。第二种方法,提高java文件读写功能,读入各条记录,用java文件通过图书馆系统写入后台数据库。
由于第二种方法,以前还没有使用过,觉得有必要补充这一块的知识,因此采用了第二种方法。
首先,将excel文件中的数据另存到文本文件,以默认的制表符分隔字段。book2005.txt条目如下:
书架号 序号 书 名 作者 类别 索书号 ISBN 出版社 价格 出版年份
102 110 关贸总协定和世贸组织的法理(第二版) 杰克森(Jackson) 经济 F743-53/102 7-04-011672-3 高等教育 40.00 2002
102 139 沃顿创业第1书 约翰·拉斯克 经济 F270/102 7-04-015906-6 高等教育 25.00 2004.11
102 140 持?煜? 凯文·肯尼迪 经济 F276.6/102 7-04-015821-3 高等教育 32.00 2004.11
102 143 十倍速可持续成长 周仲庚 经济 F276.6/102 7-04-015953-8 高等教育 35.00 2004.1
.......
每条记录,共10个字段,其中前2个字段不需要。
其次,代码编写。考虑方法是通过java io将数据读入,每条记录读入到一个长度为10的String[],所有的记录合成String[][]。最后,提过原有的Spring+Hibernate代码导入到数据库。
为了快速,编码直接在Junit测试文件上进行。
package elib.dao;
import java.util.List;
import junit.framework.TestCase;
import java.math.BigDecimal;
import elib.service.*;
import elib.FileUtil;
import java.io.IOException;
import java.io.*;
import elib.DigitUtil;
import elib.ElibUtil;
// added by hofman on 2005-12-06
/* BaseDAOTest.java 是Junit TestCase文件的扩展文件,初始化了对Spring调度的各种beans的调用能力。
*/
public class FileTest extends BaseDAOTest {
public void testReadFile() throws IOException {
String filename = "/upload/book2005.txt";
File file = new File(filename);
BufferedReader br = new BufferedReader(new FileReader(file));
StringBuffer sb = new StringBuffer();
String line = null;
int i= 0;
String[][] recs = new String[535][10];
String[] rec = null;
while ((line = br.readLine()) != null) {
// 每行是一条记录,一条记录的各个字段由tab分隔。
rec = line.split("\\t");
// 将单条记录导入记录集合
for(int j=0; j<10;j++) {
recs<i>[j] = rec[j];
}
i++;
if(i == 535) break;
}
br.close();
//数据读入验证
//if(recs.length < 535) return;
//assertEquals(535, i);
// assertEquals("文学", recs[2][4]);
//assertEquals("2003.4", recs[299][9]);
Book book;
BigDecimal bid = new BigDecimal("82000");
String cdate = ElibUtil.getDate();
int k;
for( k=0;k<241;k++) {
book = new Book();
bid = bid.add(oneVal);
book.setBookid(bid);
book.setBookname(recs[k][2]);
book.setAuthor(recs[k][3]);
book.setSubject(recs[k][4]);
book.setCheckout(recs[k][5]);
book.setIsbn(recs[k][6]);
book.setPublisher(recs[k][7]);
// price是BigDecimal类型,此处进行验证
String sprice = recs[k][8];
BigDecimal price = DigitUtil.stringToBigDecimal(sprice);
// 跳过不合格的记录
if(price == null) continue;
book.setPrice(price);
book.setCopyyear(recs[k][9]);
book.setCdate(cdate);
book.setMdate(cdate);
// 调用service相关代码,导入数据
bMgr.addBook(book);
}
assertEquals(535, k);
}
protected void setUp() throws Exception {
super.setUp();
}
protected void tearDown() throws Exception {
super.tearDown();
}
public static void main(String[] args) {
junit.swingui.TestRunner.run(FileTest.class);
}
}
hofman
2005-12-06 16:06:49
阅读:5262
评论:0
引用:0
一年前,就计划学习Spring,但初步了解一下,发现还是有些庞大,就知难而退了。最近反思一年来开发进展迟缓的原因,发现技术学习上比较保守,是重要原因。学习主流的开发技术,虽然有学习成本,但会有开发效率的提升。
第一个目标:用Spring+Hibernate完成对持久层的改造,这是Spring最迷人的应用之一吧。
Spring比较复杂,有七大部分,比如ORM/MVC/WEB等等,我想,应该分步学习,有些部分可能我以后也不打算学习,比如其MVC部分。
首先,作一点理论准备。SpringFramework的官方站点查阅资料,初步了解一下IOC,AOP这些SpringFramework力推的核心概念。阅读了官方手册,以及《Spring In Action》的部分内容,以及Martin Fowler谈IOC(Dependency Injection)的文章。
其次,寻找可用的入门教程,最后锁定了IBM developworks上的一篇文章,以及SpringFramework自带的petclinic作为实战材料。
Object-relation mapping without the container-Develop a transactional persistence layer using Hibernate and Spring这篇文章非常符合我的目标。透明思考称该文的作法是:“Spring结合Hibernate的标准做法”。
我的开发环境是:Jbuilder X+Oracle 8i +Jboss 3.27,操作系统是TurboLinux Server 8.0。
下载Richard HighTower 的源代码。
让这个例子运行起来,居然费了我一整天的时间。HighTower的例子,其数据库用的是Mysql,而我的是Oracle 8i,单单这个差别,就浪费了我一天的时间,因为Dbunit操作Mysql 与Oracle有些细节地方不同,就会导致运行失败。
为了让和我一样的初学者少走点弯路,下面给出我改造过的例子,尽可能的简化再简化,因此本例特地只使用一个数据库表:hofman_user。
1. 建立数据表
create table hofman_user (pk_user_id number(8),
vc_email varchar2(50),
vc_password varchar2(80),
primary key(pk_user_id));
2. 建立hofman_user表主键pk_user_id使用的序列
create sequence hofmanid_seq;
3. 一个数据表对应一个POJO:
package hofman;
import java.util.ArrayList;
import java.util.List;
public class User {
private Long id = new Long(-1);
private String email;
private String password;
public Long getId() {
return id;
}
public void setId(Long long1) {
id = long1;
}
public String getEmail() {
return email;
}
public String getPassword() {
return password;
}
public void setEmail(String string) {
email = string;
}
public void setPassword(String string) {
password = string;
}
}
4. 对应的hibernate 的映射文件:User_hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 2.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">
<hibernate-mapping>
<class
name="hofman.User"
table="HOFMAN_USER"
dynamic-update="false"
dynamic-insert="false"
discriminator-value="2"
>
<id
name="id"
column="PK_USER_ID"
type="java.lang.Long"
unsaved-value="-1"
>
<generator class="sequence">
<param name="sequence">hofmanid_seq</param>
</generator>
</id>
<property
name="email"
type="string"
update="false"
insert="true"
column="VC_EMAIL"
length="82"
not-null="true"
unique="true"
/>
<property
name="password"
type="string"
update="false"
insert="true"
column="VC_PASSWORD"
length="20"
not-null="true"
unique="true"
/>
</class>
<query name="AllUsers"><![CDATA[
from User user order by user.email asc
]]></query>
</hibernate-mapping>
5. UserDAO的interface文件:UserDAO.java
package hofman;
import java.util.List;
public interface UserDAO {
public List getUsers();
public void addUser(User user);
public User findUserByEmail(String email);
public void removeUser(String email);
}
6. UserDAO的实现文件:UserDAOImpl.java
package hofman;
import java.sql.SQLException;
import java.util.Iterator;
import java.util.List;
import net.sf.hibernate.HibernateException;
import net.sf.hibernate.Session;
import net.sf.hibernate.Query;
import org.springframework.orm.hibernate.HibernateCallback;
import org.springframework.orm.hibernate.support.HibernateDaoSupport;
public class UserDAOImpl extends HibernateDaoSupport implements UserDAO{
public List getUsers(){
return getHibernateTemplate().findByNamedQuery("AllUsers");
}
public User findUserByEmail(String email) {
return (User) getHibernateTemplate().find("from User u where u.email=?",email).get(0);
}
public void addUser(User user){
getHibernateTemplate().save(user);
}
public void removeUser (String email) {
User user = findUserByEmail(email);
this.getHibernateTemplate().delete(user);
}
}
7.SpringFramework的配置文件:. ApplicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<!--
- Application context definition for Express on Hibernate.
-->
<beans>
<!--
<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName">
<value>java:/comp/env/jdbc/OracleDs</value>
</property>
</bean>
-->
<!-- Datasource that works in any application server
You could easily use J2EE data source instead if this were
running inside of a J2EE container.
-->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName"><value>oracle.jdbc.driver.OracleDriver</value></property>
<property name="url"><value>jdbc:oracle:thin:@192.168.1.2:1521:yulog</value></property>
<property name="username"><value>hofman</value></property>
<property name="password"><value>topSecret</value></property>
</bean>
<!-- Hibernate SessionFactory -->
<bean id="sessionFactory" class="org.springframework.orm.hibernate.LocalSessionFactoryBean">
<property name="dataSource"><ref local="dataSource"/></property>
<!-- Must references all OR mapping files. -->
<property name="mappingResources">
<list>
<value>/hofman/User.hbm.xml</value>
</list>
</property>
<!-- Set the type of database; changing this one property will port this to Oracle,
MS SQL etc. -->
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">net.sf.hibernate.dialect.OracleDialect</prop>
</props>
</property>
</bean>
<!-- Pass the session factory to our UserDAO -->
<bean id="userDAOTarget" class="hofman.UserDAOImpl">
<property name="sessionFactory"><ref local="sessionFactory"/></property>
</bean>
<bean id="transactionManager" class="org.springframework.orm.hibernate.HibernateTransactionManager">
<property name="sessionFactory"><ref bean="sessionFactory"/></property>
</bean>
<bean id="userDAO"
class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="transactionManager"><ref local="transactionManager"/></property>
<property name="target"><ref local="userDAOTarget"/></property>
<property name="transactionAttributes">
<props>
<prop key="addUser">PROPAGATION_REQUIRED</prop>
</props>
</property>
</bean>
</beans>
7. 调用SrpingFramework的文件:ApplicationContextFactory.xml
package hofman;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* @author Richard Hightower
* ArcMind Inc. http://www.arc-mind.com
*/
public class ApplicationContextFactory {
private static Log log = LogFactory.getLog(ApplicationContextFactory.class);
private static Object initObj = null;
private static int count = 0;
public static void init(Object o){
if (count > 0){
log.error("Can't initialize the application context twice: THIS SHOULD ONLY HAPPEN DURING TESTING");
}
initObj=o;
count++;
}
public static ApplicationContext getApplicationContext(){
if (initObj == null){
throw new IllegalStateException("Application context not initialized");
}
// else if (initObj instanceof ServletContext){
// ServletContext servletContext = (ServletContext) initObj;
// return WebApplicationContextUtils.getRequiredWebApplicationContext(servletContext);
//
// }
else if (initObj instanceof String){
String contextResourceLocation = (String) initObj;
return new ClassPathXmlApplicationContext(contextResourceLocation);
} else {
//throw new IllegalStateException("You must initialize the context with a String or ServletContext");
throw new IllegalStateException("You must initialize the context with a String");
}
}
}
8. Junit的测试用例:UserDAOTest.java
package hofman;
import java.util.List;
import junit.framework.TestCase;
// added by hofman on 2005-07-22
public class UserDAOTest extends TestCase {
private UserDAO userDAO;
static {
ApplicationContextFactory.init("/hofman/applicationContext.xml");
}
public void testAddUser(){
User user = new User();
String email = "hofman@zhuoda.org";
user.setEmail(email);
user.setPassword("fakePass");
userDAO.addUser(user);
email = "s@s.com";
user.setEmail(email);
user.setPassword("topSecret");
userDAO.addUser(user);
User user2 = userDAO.findUserByEmail(email);
assertEquals(email, user2.getEmail());
}
public void testFindUserByEmail(){
User user = userDAO.findUserByEmail("hofman@zhuoda.org");
assertNotNull(user);
}
public void testKillUser()throws Exception{
String email = "s@s.com";
userDAO.removeUser(email);
}
protected void setUp() throws Exception {
super.setUp();
userDAO = (UserDAO) ApplicationContextFactory.getApplicationContext().getBean("userDAO");
}
protected void tearDown() throws Exception {
super.tearDown();
}
public static void main(String[] args) {
junit.swingui.TestRunner.run(UserDAOTest.class);
}
}
9. 调用UserDAO的jsp文件:getPass.jsp
<%@ page contentType="text/html; charset=GBK" %>
<%@ page import="hofman.*" %>
<%
UserDAO userDAO;
String password;
ApplicationContextFactory.init("/hofman/applicationContext.xml");
userDAO = (UserDAO) ApplicationContextFactory.getApplicationContext().getBean("userDAO");
User user = userDAO.findUserByEmail("hofman@zhuoda.org");
password = user.getPassword();
%>
<html>
<head><title>Get Password</title></head>
<body bgcolor="#ffffff">
<h1>hofman's password:<%=password %></h1>
</body>
</html>
10.完整的代码下载
[url=ftp://ftp.zhuoda.org/incoming/SpringInAction/helloSpring.tgz]helloSring.tgz[/url]
说明:
源代码很伟大,但适合新手阅读的源代码的文档很难找。我就是从HighTower的代码基础上开始起步,但编译时,首先就遇到一出错误,getHibernate.creatQuery()不存在,可能原作所使用的SpringFramework的版本比较老,我用的是写作本文时最新的1.2.2,注释掉相关部分,算是通过了,但UserDAOTest.java无法运行,Dbunit出问题了,费了老大劲,也未完全搞定,只不过,可用继续运行。
今天才发现,就本例,其实用junit就可用了,没有必要使用dbunit。Dbunit很伟大,如果数据库用的是Mysql的话,如果象我一样,数据库用oracle的话,也许有不少麻烦。
让Jbuider X支撑最新的SpringFramework很简单,Tools/Configure Libraries建立一个spring库,把spring发行包里面dist目录里面的jar加进去,就可用了。
支持Dbunit的方法类似。
前后化了一个星期的时间,终于可用使用被大吹特吹的Spring+Hibernate的持久层方案了,总算学会了用Junit调试连接数据库的DAO程序。
当然,这只是第一步。不过,目前,我并不想完全放弃我比较熟悉的J2EE开发模式,不管怎么说,引入新的持久层开发模式、特别是高效地调试模式,对提升开发效率无疑有好处。
hofman
2005-07-22 20:44:35
阅读:6048
评论:5
引用:0
这是实战JSP进阶编程之三。
今天花了几个小时,终于将机房里面的Tomcat+Hibernate的开发、学习环境配置好了。
应用场景:Tomcat 5.5, Hibernate 2.1.7, Mysql 3.23.43, Mysql Driver:3.0.14, JDK: 1.4.2 OS: TurboLinux Server 8.0
用户环境:普通学生帐户--j2ee,位置: /home/j2ee/public_html
为了方便初学者,本教程特意作了简化处理。
1。将hibernate2.jar,dom4j,ehcache,cglib等Hibernate手册上说的那些jar copy 到 WEB-INF/lib里面。
2。将hibernate.cfg.xml copy 到WEB-INF里面。
内网用户只要直接从/home/j2ee/public_html/WEB-INF中copy就可以了。
外面的读者也只需要在hibernate.cfg.xml中改改MySQL的参数就可以了。
3. 本例对通行的Cat例子,进行了进一步的简化,只有2个字段:
CAT_ID varchar(50), name varchar(50)。
4. WEB-INF/hb中有如下文件:
Cat.java
Cat.hbm.xml
HibernateUtil.java
5. 2个用于测试的jsp文件:
addCat.jsp
getCats.jsp
具体文件如下:
第一个文件:hibernate.cfg.xml
<?xml version="1.0" encoding="GB2312" ?>
<!DOCTYPE hibernate-configuration (View Source for full doctype...)>
- <hibernate-configuration>
- <session-factory>
<property name="hibernate.connection.driver_class"]com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url"]jdbc:mysql://localhost/joke</property>
<property name="hibernate.connection.username"]root</property>
<property name="hibernate.connection.password"]
<property name="show_sql"]false</property>
<property name="dialect"]net.sf.hibernate.dialect.MySQLDialect</property>
<mapping resource="hb/Cat.hbm.xml"]
</session-factory>
</hibernate-configuration>
第二个文件:Cat.java
package hb;
public class Cat {
private String id;
private String name;
public Cat() {
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String toString() {
String strCat = new StringBuffer()
.append(this.getId()).append(", ")
.append(this.getName()).append(", ")
.toString();
return strCat;
}
}
第三个文件:Cat.hbm.xml
<?xml version="1.0" ?>
<!DOCTYPE hibernate-mapping (View Source for full doctype...)>
- <hibernate-mapping default-cascade="none" default-access="property" auto-import="true"]
- <class name="hb.Cat" table="cat" mutable="true" polymorphism="implicit" dynamic-update="false" dynamic-insert="false" batch-size="1" select-before-update="false" optimistic-lock="version"]
- <id name="id" type="java.lang.String" unsaved-value="null"]
<column name="CAT_ID" sql-type="varchar(32)" not-null="true"]
<generator class="uuid.hex"]
</id>
- <property name="name" not-null="false" unique="false" update="true" insert="true"]
<column name="NAME" sql-type="varchar(20)" not-null="true"]
</property>
</class>
</hibernate-mapping>
第四个文件:HibernateUtil.java
package hb;
import net.sf.hibernate.*;
import net.sf.hibernate.cfg.*;
public class HibernateUtil {
private static final SessionFactory sessionFactory;
static {
try {
sessionFactory = new Configuration().configure().buildSessionFactory();
} catch (HibernateException ex) {
throw new RuntimeException("Exception building SessionFactory: "
+ ex.getMessage(), ex);
}
}
public static final ThreadLocal session = new ThreadLocal();
public static Session currentSession() throws HibernateException {
// Session s;
Session s = (Session) session.get();
// Open a new Session, if this Thread has none yet
if (s == null) {
s = sessionFactory.openSession();
session.set(s);
}
return s;
}
public static void closeSession() throws HibernateException {
Session s = (Session) session.get();
session.set(null);
if (s != null)
s.close();
}
}
第五个文件: addCat.jsp
<%@ page contentType="text/html; charset=GB18030" %>
<%@ page import="hb.*, net.sf.hibernate.*" %>
<html>
<head>
<title>test</title>
</head>
<body bgcolor="#ffffff"]
<h1>Test Hibernate</h1>
<a href="getCats.jsp"]View Cats[/url]<br>
<%
if(request.getParameter("Go") != null) {
String name = request.getParameter("name");
if(name == null || name.length() < 1) {
out.println("Name can not be empty!");
return;
}
SessionFactory sessionFactory;
net.sf.hibernate.Session hsession = HibernateUtil.currentSession();
Transaction tx = hsession.beginTransaction();
Cat c;
c = new Cat();
c.setName(name);
hsession.save(c);
hsession.flush();
tx.commit();
HibernateUtil.closeSession();
out.println("Done.");
}
%>
Add New Cats:<br>
<form method=post action=addCat.jsp>
Name:<input name=name><br>
<input type=submit name='Go' value='Add'><br>
</form>
</body>
</html>
第六个文件: getCats.jsp
<%@ page contentType="text/html; charset=GB18030" %>
<%@ page import="hb.*, net.sf.hibernate.*,
java.util.*" %>
<html>
<head>
<title>Hibernate Test</title>
</head>
<body bgcolor="#ffffff"]
<h1>Test Hibernate</h1>
<a href=addCat.jsp>Add Cat[/url]<br>
<p> ID Name </p>
<%
SessionFactory sessionFactory;
net.sf.hibernate.Session hsession;
hsession = HibernateUtil.currentSession();
Transaction tx = hsession.beginTransaction();
Query query = hsession.createQuery ("select cat from Cat as cat ");
for (Iterator it = query.iterate(); it.hasNext();) {
Cat cat = (Cat) it.next();
out.println(cat.getId()+" " + cat.getName() + "<br>");
}
tx.commit();
HibernateUtil.closeSession();
out.println("Done.");
%>
</body>
</html>
说明:
1.对HibernateUtil.java的编译:
javac -classpath ../lib/hibernate2.jar HibernateUtil.java
有2个警告,可以忽略之。
2.
内网观测点
今天花了几个小时,终于将机房里面的Tomcat+Hibernate的开发、学习环境配置好了。
应用场景:Tomcat 5.5, Hibernate 2.1.7, Mysql 3.23.43, Mysql Driver:3.0.14, JDK: 1.4.2 OS: TurboLinux Server 8.0
用户环境:普通学生帐户--j2ee,位置: /home/j2ee/public_html
为了方便初学者,本教程特意作了简化处理。
1。将hibernate2.jar,dom4j,ehcache,cglib等Hibernate手册上说的那些jar copy 到 WEB-INF/lib里面。
2。将hibernate.cfg.xml copy 到WEB-INF里面。
内网用户只要直接从/home/j2ee/public_html/WEB-INF中copy就可以了。
外面的读者也只需要在hibernate.cfg.xml中改改MySQL的参数就可以了。
3. 本例对通行的Cat例子,进行了进一步的简化,只有2个字段:
CAT_ID varchar(50), name varchar(50)。
4. WEB-INF/hb中有如下文件:
Cat.java
Cat.hbm.xml
HibernateUtil.java
5. 2个用于测试的jsp文件:
addCat.jsp
getCats.jsp
具体文件如下:
第一个文件:hibernate.cfg.xml
<?xml version="1.0" encoding="GB2312" ?>
<!DOCTYPE hibernate-configuration (View Source for full doctype...)>
- <hibernate-configuration>
- <session-factory>
<property name="hibernate.connection.driver_class"]com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url"]jdbc:mysql://localhost/joke</property>
<property name="hibernate.connection.username"]root</property>
<property name="hibernate.connection.password"]
<property name="show_sql"]false</property>
<property name="dialect"]net.sf.hibernate.dialect.MySQLDialect</property>
<mapping resource="hb/Cat.hbm.xml"]
</session-factory>
</hibernate-configuration>
第二个文件:Cat.java
package hb;
public class Cat {
private String id;
private String name;
public Cat() {
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String toString() {
String strCat = new StringBuffer()
.append(this.getId()).append(", ")
.append(this.getName()).append(", ")
.toString();
return strCat;
}
}
第三个文件:Cat.hbm.xml
<?xml version="1.0" ?>
<!DOCTYPE hibernate-mapping (View Source for full doctype...)>
- <hibernate-mapping default-cascade="none" default-access="property" auto-import="true"]
- <class name="hb.Cat" table="cat" mutable="true" polymorphism="implicit" dynamic-update="false" dynamic-insert="false" batch-size="1" select-before-update="false" optimistic-lock="version"]
- <id name="id" type="java.lang.String" unsaved-value="null"]
<column name="CAT_ID" sql-type="varchar(32)" not-null="true"]
<generator class="uuid.hex"]
</id>
- <property name="name" not-null="false" unique="false" update="true" insert="true"]
<column name="NAME" sql-type="varchar(20)" not-null="true"]
</property>
</class>
</hibernate-mapping>
第四个文件:HibernateUtil.java
package hb;
import net.sf.hibernate.*;
import net.sf.hibernate.cfg.*;
public class HibernateUtil {
private static final SessionFactory sessionFactory;
static {
try {
sessionFactory = new Configuration().configure().buildSessionFactory();
} catch (HibernateException ex) {
throw new RuntimeException("Exception building SessionFactory: "
+ ex.getMessage(), ex);
}
}
public static final ThreadLocal session = new ThreadLocal();
public static Session currentSession() throws HibernateException {
// Session s;
Session s = (Session) session.get();
// Open a new Session, if this Thread has none yet
if (s == null) {
s = sessionFactory.openSession();
session.set(s);
}
return s;
}
public static void closeSession() throws HibernateException {
Session s = (Session) session.get();
session.set(null);
if (s != null)
s.close();
}
}
第五个文件: addCat.jsp
<%@ page contentType="text/html; charset=GB18030" %>
<%@ page import="hb.*, net.sf.hibernate.*" %>
<html>
<head>
<title>test</title>
</head>
<body bgcolor="#ffffff"]
<h1>Test Hibernate</h1>
<a href="getCats.jsp"]View Cats[/url]<br>
<%
if(request.getParameter("Go") != null) {
String name = request.getParameter("name");
if(name == null || name.length() < 1) {
out.println("Name can not be empty!");
return;
}
SessionFactory sessionFactory;
net.sf.hibernate.Session hsession = HibernateUtil.currentSession();
Transaction tx = hsession.beginTransaction();
Cat c;
c = new Cat();
c.setName(name);
hsession.save(c);
hsession.flush();
tx.commit();
HibernateUtil.closeSession();
out.println("Done.");
}
%>
Add New Cats:<br>
<form method=post action=addCat.jsp>
Name:<input name=name><br>
<input type=submit name='Go' value='Add'><br>
</form>
</body>
</html>
第六个文件: getCats.jsp
<%@ page contentType="text/html; charset=GB18030" %>
<%@ page import="hb.*, net.sf.hibernate.*,
java.util.*" %>
<html>
<head>
<title>Hibernate Test</title>
</head>
<body bgcolor="#ffffff"]
<h1>Test Hibernate</h1>
<a href=addCat.jsp>Add Cat[/url]<br>
<p> ID Name </p>
<%
SessionFactory sessionFactory;
net.sf.hibernate.Session hsession;
hsession = HibernateUtil.currentSession();
Transaction tx = hsession.beginTransaction();
Query query = hsession.createQuery ("select cat from Cat as cat ");
for (Iterator it = query.iterate(); it.hasNext();) {
Cat cat = (Cat) it.next();
out.println(cat.getId()+" " + cat.getName() + "<br>");
}
tx.commit();
HibernateUtil.closeSession();
out.println("Done.");
%>
</body>
</html>
说明:
1.对HibernateUtil.java的编译:
javac -classpath ../lib/hibernate2.jar HibernateUtil.java
有2个警告,可以忽略之。
2.
内网观测点
hofman
2005-04-04 02:05:07
阅读:4361
评论:8
引用:0
我们的第一个例子是简化的DAO方式,主要是在编程中引入了oop概念。
这次,我们将DAO补齐,但仍然保持最简单的形式,以便初学者学习。
简单的DAO模式构成:
1 interface
2. Factory
3 Implements
4. caller
第一个例子中的主程序NewsDAO.java代码没有改动,只是改了个名字,
成为implements.
package news;
import java.sql.*;
public class NewsDAOMySQL implements NewsDAO
{
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
String url="jdbc:mysql://localhost:3306/joke?user=root";
public NewsDAOMySQL()
{
try {
Class.forName ("com.mysql.jdbc.Driver");
}
catch (java.lang.ClassNotFoundException e) {
System.err.println("joke():"+e.getMessage());
}
}
public News getNewsByPrimaryKey(int newsid) throws SQLException
{
Connection conn=null;
Statement stmt;
ResultSet rs;
News news = null;
String sql="select newsid,title,content from news2"+
" where newsid="+newsid+"";
conn = getConnection();
stmt = conn.createStatement();
rs=stmt.executeQuery(sql);
if(rs.next())
{
news = new News(rs.getInt(1), rs.getString(2),rs.getString(3));
}
rs.close();
stmt.close();
conn.close();
return news;
}
private Connection getConnection() throws SQLException
{
Connection conn = null;
conn = DriverManager.getConnection(url);
return conn;
}
}
除了第一句由
public class NewsDAO 变成了
public class NewsDAOMySQL implements NewsDAO
构造方法名称由NewsDAO()变成NewsDAOMySQL(),这个程序与第一个例子并没有区别。
第二个程序是interface,非常简单,因为我们只实现了一个方法,所以这儿也只有一个方法的申明,大家可以很容易地自己补上。
package news;
import java.sql.SQLException;
public interface NewsDAO {
public News getNewsByPrimaryKey(int newsid) throws SQLException;
}
第三个程序是Factory.
我们的环境比较简单,没有使用jndi,
package news;
public class NewsDAOFactory {
public static NewsDAO getDAO() throws Exception {
NewsDAO newsDao = null;
String className = "news.NewsDAOMySQL";
try {
newsDao = (NewsDAO) Class.forName(className).newInstance();
}
catch (Exception se) {
}
return newsDao;
}
}
第四,调用的jsp程序:
<%@page contentType="text/html;charset=gb2312" %>
<%@page import="news.*" %>
<%
// old version on 2004-12-07
// NewsDAO newsDao = new NewsDAO();
// new version on 2004-12-21
NewsDAO newsDao = NewsDAOFactory.getDAO();
News news = newsDao.getNewsByPrimaryKey(1);
if(news != null) {
out.println("Title thru DAO:"+news.getTitle());
out.println("<br>");
out.println("Body:"+news.getContent());
}
else out.println("Failed.");
%>
第五,本例所使用的POJO:News.java,没有任何改动,故不在此重复。
内网观测点:同第一例子。
Real DAO
更完整的例子,大家可以参考petstore 的CatalogDAO.
这次,我们将DAO补齐,但仍然保持最简单的形式,以便初学者学习。
简单的DAO模式构成:
1 interface
2. Factory
3 Implements
4. caller
第一个例子中的主程序NewsDAO.java代码没有改动,只是改了个名字,
成为implements.
package news;
import java.sql.*;
public class NewsDAOMySQL implements NewsDAO
{
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
String url="jdbc:mysql://localhost:3306/joke?user=root";
public NewsDAOMySQL()
{
try {
Class.forName ("com.mysql.jdbc.Driver");
}
catch (java.lang.ClassNotFoundException e) {
System.err.println("joke():"+e.getMessage());
}
}
public News getNewsByPrimaryKey(int newsid) throws SQLException
{
Connection conn=null;
Statement stmt;
ResultSet rs;
News news = null;
String sql="select newsid,title,content from news2"+
" where newsid="+newsid+"";
conn = getConnection();
stmt = conn.createStatement();
rs=stmt.executeQuery(sql);
if(rs.next())
{
news = new News(rs.getInt(1), rs.getString(2),rs.getString(3));
}
rs.close();
stmt.close();
conn.close();
return news;
}
private Connection getConnection() throws SQLException
{
Connection conn = null;
conn = DriverManager.getConnection(url);
return conn;
}
}
除了第一句由
public class NewsDAO 变成了
public class NewsDAOMySQL implements NewsDAO
构造方法名称由NewsDAO()变成NewsDAOMySQL(),这个程序与第一个例子并没有区别。
第二个程序是interface,非常简单,因为我们只实现了一个方法,所以这儿也只有一个方法的申明,大家可以很容易地自己补上。
package news;
import java.sql.SQLException;
public interface NewsDAO {
public News getNewsByPrimaryKey(int newsid) throws SQLException;
}
第三个程序是Factory.
我们的环境比较简单,没有使用jndi,
package news;
public class NewsDAOFactory {
public static NewsDAO getDAO() throws Exception {
NewsDAO newsDao = null;
String className = "news.NewsDAOMySQL";
try {
newsDao = (NewsDAO) Class.forName(className).newInstance();
}
catch (Exception se) {
}
return newsDao;
}
}
第四,调用的jsp程序:
<%@page contentType="text/html;charset=gb2312" %>
<%@page import="news.*" %>
<%
// old version on 2004-12-07
// NewsDAO newsDao = new NewsDAO();
// new version on 2004-12-21
NewsDAO newsDao = NewsDAOFactory.getDAO();
News news = newsDao.getNewsByPrimaryKey(1);
if(news != null) {
out.println("Title thru DAO:"+news.getTitle());
out.println("<br>");
out.println("Body:"+news.getContent());
}
else out.println("Failed.");
%>
第五,本例所使用的POJO:News.java,没有任何改动,故不在此重复。
内网观测点:同第一例子。
Real DAO
更完整的例子,大家可以参考petstore 的CatalogDAO.
hofman
2004-12-21 20:45:24
阅读:3135
评论:0
引用:0
在与EJB开发相同的开发环境下,第一个Hibernate测试小程序通过了。
如果半年前,我能够“勇敢”一点,当时就用Hibernate,就不会为oracle的blob/clob字段
吃尽苦头,徒劳地希望能够这些字段cmp上。
也就不会,这么时间才干了这么一点活,尽管也没有偷懒。
hofman
2004-12-09 11:12:20
阅读:2704
评论:0
引用:0
不少JSP初学者在学会简单的jsp编程后,往往停留在用jsp里面的sql语句调一个javabean进行数据库连接阶段,止步不前了。
这个简单的教程希望能够有助于初学者学会用oop思想进行jsp编程。
场景:一个简单的新闻系统,有2-3个数据表构成。
数据库系统用的是Mysql,当然用其它的也类似。
先看第一个数据表,也是主要的数据表:news
create table news2 (newsid int not null,
userid int,
kwid int, // 关键词外键
title varchar(100),
content text,
hits int,
cdate varchar2(30),
mdate varchar2(30),
primary key(newsid));
再插入一个样本数据:
insert into news2 (newsid, title, content) values (1, 'test title', 'test body');
设计思路:用mvc模式编程,将数据以一个helper class News.java 打包,
并通过NewsDAO.java进行数据库操作。
设计阶段,用UML勾画出系统的object.
...此处省略
NewsDAO的主要方法有:
1. public News getNewsByPrimaryKey(int newsid);
2. public News[] getRecentNews();
3. public News[] getHotNews();
......
News.java的代码如下:
package news;
public class News {
private int newsid;
private int userid;
private int kwid;
private int hits;
private String title;
private String content;
private String cdate;
private String mdate;
public News(){ }
public News(int newsid,int userid,int kwid,int hits,String title,String content,String cdate)
{
this.newsid=newsid;
this.userid=userid;
this.kwid=kwid;
this.hits=hits;
this.title=title;
this.content=content;
this.cdate=cdate;
}
public News(int id, String t, String cnt) {
this.newsid = id;
this.title = t;
this.content = cnt;
}
public int getNewsid()
{
return newsid;
}
public void setNewsid(int newsid)
{
this.newsid=newsid;
}
public int getUserid()
{
return userid;
}
public void setUserid(int userid)
{
this.userid=userid;
}
public int getKwid()
{
return kwid;
}
public void setKwid(int kwid)
{
this.kwid=kwid;
}
public int getHits()
{
return hits;
}
public void setHits(int hits)
{
this.hits=hits;
}
public String getTitle()
{
return title;
}
public void setTitle(String title)
{
this.title=title;
}
public String getContent()
{
return content;
}
public void setContent(String content)
{
this.content=content;
}
public String getCdate()
{
return cdate;
}
public void setCdate(String cdate)
{
this.cdate=cdate;
}
}
说明:这个程序可以用作javabean,作为录入表单的参数携带者(params Holder).
最主要的文件NewsDAO.java代码如下:
package news;
import java.sql.*;
public class NewsDAO
{
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
String url="jdbc:mysql://localhost:3306/joke?user=root";
public NewsDAO()
{
try {
Class.forName ("com.mysql.jdbc.Driver");
}
catch (java.lang.ClassNotFoundException e) {
System.err.println("joke():"+e.getMessage());
}
}
public News getNewsByPrimaryKey(int newsid) throws SQLException
{
Connection conn=null;
Statement stmt;
ResultSet rs;
News news = null;
String sql="select newsid,title,content from news2"+
" where newsid="+newsid+"";
conn = getConnection();
stmt = conn.createStatement();
rs=stmt.executeQuery(sql);
if(rs.next())
{
news = new News(rs.getInt(1), rs.getString(2),rs.getString(3));
}
rs.close();
stmt.close();
conn.close();
return news;
}
private Connection getConnection() throws SQLException
{
Connection conn = null;
conn = DriverManager.getConnection(url);
return conn;
}
}
说明:这个程序作为示例代码,非常简单,没有考虑异常,更主要的method
如getRecentNews()等,大家可以自己参考实现。
简单的jsp调用测试程序:getNews.jsp
<%@page contentType="text/html;charset=gb2312" %>
<%@page import="news.*" %>
<%
NewsDAO newsDao = new NewsDAO();
News news = newsDao.getNewsByPrimaryKey(1);
if(news != null) {
out.println("Title:"+news.getTitle());
out.println("<br>");
out.println("Body:"+news.getContent());
}
else out.println("Failed.");
%>
系统的内网观测网址:OOP News
说明:这个简化实现其实是DAO模式的省略形式,还应该有interface,dao factory的。
有时间的话,可能以后会给出示例,当然,大家在熟悉oop方式之后,也能够
自己补齐。
还有,编译的时候 用 javac news/*.java 就可以了。
如果系统提示找不到News, 那其实是因为你的NewsDAO.java有问题,并非真的是News不在路径上。在同一个包内,一般这样编译就可以的。只不过,编译的错误提示误导人。
这个简单的教程希望能够有助于初学者学会用oop思想进行jsp编程。
场景:一个简单的新闻系统,有2-3个数据表构成。
数据库系统用的是Mysql,当然用其它的也类似。
先看第一个数据表,也是主要的数据表:news
create table news2 (newsid int not null,
userid int,
kwid int, // 关键词外键
title varchar(100),
content text,
hits int,
cdate varchar2(30),
mdate varchar2(30),
primary key(newsid));
再插入一个样本数据:
insert into news2 (newsid, title, content) values (1, 'test title', 'test body');
设计思路:用mvc模式编程,将数据以一个helper class News.java 打包,
并通过NewsDAO.java进行数据库操作。
设计阶段,用UML勾画出系统的object.
...此处省略
NewsDAO的主要方法有:
1. public News getNewsByPrimaryKey(int newsid);
2. public News[] getRecentNews();
3. public News[] getHotNews();
......
News.java的代码如下:
package news;
public class News {
private int newsid;
private int userid;
private int kwid;
private int hits;
private String title;
private String content;
private String cdate;
private String mdate;
public News(){ }
public News(int newsid,int userid,int kwid,int hits,String title,String content,String cdate)
{
this.newsid=newsid;
this.userid=userid;
this.kwid=kwid;
this.hits=hits;
this.title=title;
this.content=content;
this.cdate=cdate;
}
public News(int id, String t, String cnt) {
this.newsid = id;
this.title = t;
this.content = cnt;
}
public int getNewsid()
{
return newsid;
}
public void setNewsid(int newsid)
{
this.newsid=newsid;
}
public int getUserid()
{
return userid;
}
public void setUserid(int userid)
{
this.userid=userid;
}
public int getKwid()
{
return kwid;
}
public void setKwid(int kwid)
{
this.kwid=kwid;
}
public int getHits()
{
return hits;
}
public void setHits(int hits)
{
this.hits=hits;
}
public String getTitle()
{
return title;
}
public void setTitle(String title)
{
this.title=title;
}
public String getContent()
{
return content;
}
public void setContent(String content)
{
this.content=content;
}
public String getCdate()
{
return cdate;
}
public void setCdate(String cdate)
{
this.cdate=cdate;
}
}
说明:这个程序可以用作javabean,作为录入表单的参数携带者(params Holder).
最主要的文件NewsDAO.java代码如下:
package news;
import java.sql.*;
public class NewsDAO
{
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
String url="jdbc:mysql://localhost:3306/joke?user=root";
public NewsDAO()
{
try {
Class.forName ("com.mysql.jdbc.Driver");
}
catch (java.lang.ClassNotFoundException e) {
System.err.println("joke():"+e.getMessage());
}
}
public News getNewsByPrimaryKey(int newsid) throws SQLException
{
Connection conn=null;
Statement stmt;
ResultSet rs;
News news = null;
String sql="select newsid,title,content from news2"+
" where newsid="+newsid+"";
conn = getConnection();
stmt = conn.createStatement();
rs=stmt.executeQuery(sql);
if(rs.next())
{
news = new News(rs.getInt(1), rs.getString(2),rs.getString(3));
}
rs.close();
stmt.close();
conn.close();
return news;
}
private Connection getConnection() throws SQLException
{
Connection conn = null;
conn = DriverManager.getConnection(url);
return conn;
}
}
说明:这个程序作为示例代码,非常简单,没有考虑异常,更主要的method
如getRecentNews()等,大家可以自己参考实现。
简单的jsp调用测试程序:getNews.jsp
<%@page contentType="text/html;charset=gb2312" %>
<%@page import="news.*" %>
<%
NewsDAO newsDao = new NewsDAO();
News news = newsDao.getNewsByPrimaryKey(1);
if(news != null) {
out.println("Title:"+news.getTitle());
out.println("<br>");
out.println("Body:"+news.getContent());
}
else out.println("Failed.");
%>
系统的内网观测网址:OOP News
说明:这个简化实现其实是DAO模式的省略形式,还应该有interface,dao factory的。
有时间的话,可能以后会给出示例,当然,大家在熟悉oop方式之后,也能够
自己补齐。
还有,编译的时候 用 javac news/*.java 就可以了。
如果系统提示找不到News, 那其实是因为你的NewsDAO.java有问题,并非真的是News不在路径上。在同一个包内,一般这样编译就可以的。只不过,编译的错误提示误导人。
hofman
2004-12-07 23:47:26
阅读:2912
评论:2
引用:0
