hibernate数据类型与java和sql的对应关系,参见4中的图:
创建一个含有多种数据类型的JavaBean:
import java.sql.Date;
import java.sql.Timestamp;
public class People
{
private Long id;
private String username;
private String password;
private int telphone;
private char gender; //'M','F'
private boolean graduation;
private Date birthday;
private Timestamp marrrTime;
private byte[] file;
public Long getId()
{
return id;
}
public void setId(Long id)
{
this.id = id;
}
public String getUsername()
{
return username;
}
public void setUsername(String username)
{
this.username = username;
}
public String getPassword()
{
return password;
}
public void setPassword(String password)
{
this.password = password;
}
public int getTelphone()
{
return telphone;
}
public void setTelphone(int telphone)
{
this.telphone = telphone;
}
public char getGender()
{
return gender;
}
public void setGender(char gender)
{
this.gender = gender;
}
public boolean isGraduation()
{
return graduation;
}
public void setGraduation(boolean graduation)
{
this.graduation = graduation;
}
public Date getBirthday()
{
return birthday;
}
public void setBirthday(Date birthday)
{
this.birthday = birthday;
}
public Timestamp getMarrrTime()
{
return marrrTime;
}
public void setMarrrTime(Timestamp marrrTime)
{
this.marrrTime = marrrTime;
}
public byte[] getFile()
{
return file;
}
public void setFile(byte[] file)
{
this.file = file;
}
}
编写相应的hbm.xml文件:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.cdtax.model.People" table="people">
<id name="id" column="id" type="long">
<generator class="increment"></generator>
</id>
<property name="username" column="username" type="string"></property>
<property name="password" column="password" type="string"></property>
<property name="telphone" column="telphone" type="int"></property>
<property name="gender" column="gender" type="character"></property>
<property name="graduation" column="graduation" type="boolean"></property>
<property name="birthday" column="birthday" type="date"></property>
<property name="marryTime" column="marryTime" type="timestamp"></property>
<property name="file" column="file" type="binary"></property>
</class>
</hibernate-mapping>
这个文件中的type属性值表示数据类型,这里写的是hibernate的数据类型,也可以写java的数据类型
创建数据库表:
CREATE TABLE `people` (
`id` bigint(20) NOT NULL default '0',
`username` varchar(50) default NULL,
`password` varchar(20) default NULL,
`telphone` int(11) default NULL,
`gender` char(1) default NULL,
`graduation` bit(1) default NULL,
`birthday` date default NULL,
`marryTime` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
`file` blob,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
注意表、JavaBean和People.hbm.xml中三者之间数据类型的对应关系。
有了hbm.xml文件,可以自动产生JavaBean,做法是:
右键单击People.hbm.xml文件,点击MyEclipse——>generate POJOs
在MyEclipse的数据库视图中连接数据库后,可以通过数据库表,直接生成hbm.xml文件,作法:
在相关表上右键单击:Hibernate Reverse Engineering,在此可以选择四种不同的生成类别,选在第一项:create POLO <>DB Table mappinginformation,生成的hbm.xml如下:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!--
Mapping file autogenerated by MyEclipse Persistence Tools
-->
<hibernate-mapping>
<class name="com.cdtax.People" table="people" catalog="hibernate">
<id name="id" type="java.lang.Long">
<column name="id" />
<generator class="assigned" />
</id>
<property name="username" type="java.lang.String">
<column name="username" length="50" />
</property>
<property name="password" type="java.lang.String">
<column name="password" length="20" />
</property>
<property name="telphone" type="java.lang.Integer">
<column name="telphone" />
</property>
<property name="gender" type="java.lang.String">
<column name="gender" length="1" />
</property>
<property name="graduation" type="java.lang.Boolean">
<column name="graduation" />
</property>
<property name="birthday" type="java.util.Date">
<column name="birthday" length="0" />
</property>
<property name="marryTime" type="java.sql.Timestamp">
<column name="marryTime" length="0" />
</property>
<property name="file" type="java.lang.String">
<column name="file" />
</property>
</class>
</hibernate-mapping>
可以看出这里的type使用的是Java类型。
写一个测试类:
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.sql.Timestamp;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
public class HibernateTest
{
private static SessionFactory sessionFactory;
static
{
try
{
sessionFactory = new Configuration().configure().buildSessionFactory();
}
catch(Exception ex)
{
ex.printStackTrace();
}
}
public static void main(String[] args) throws Exception
{
People people = new People();
people.setUsername("zhangsan");
people.setPassword("123456");
people.setGender('F');
people.setBirthday(new java.sql.Date(new java.util.Date().getTime()));
people.setGraduation(true);
people.setTelphone(1234);
people.setMarryTime(new Timestamp(new java.util.Date().getTime()));
InputStream is = new FileInputStream("c:/222.ppt");
int length = is.available();
byte[] buffer = new byte[length];
is.read(buffer);
people.setFile(buffer);
Session session = sessionFactory.openSession();
Transaction tx = null;
try
{
tx = session.beginTransaction();
session.save(people);
tx.commit();
}
catch(Exception ex)
{
if(null != tx)
{
tx.rollback();
}
}
finally
{
session.close();
}
}
}
对于mysql,有一个max_allowed_packet参数,如果设置过小,在插入blob数据数有可能异常。
查询数据库数据并显示结果将main方法修改如下:
Session session = sessionFactory.openSession();
Transaction tx = null;
try
{
tx = session.beginTransaction();
Query query = session.createQuery("from People as p order by p.username");
List<People> list = (List<People>)query.list();
for(Iterator<People> iter = list.iterator();iter.hasNext();)
{
People people = iter.next();
System.out.println(people.getUsername());
System.out.println(people.getPassword());
System.out.println(people.getTelphone());
System.out.println(people.getBirthday());
System.out.println(people.getId());
System.out.println(people.getMarryTime());
System.out.println(people.getGender());
System.out.println(people.isGraduation());
System.out.println("---------");
byte[] buffer = people.getFile();
OutputStream os = new FileOutputStream("c:/" + people.getId() + ".ppt");
os.write(buffer);
os.close();
}
}
catch(Exception ex)
{
System.out.println("yichang");
ex.printStackTrace();
if(null != tx)
{
tx.rollback();
}
}
finally
{
session.close();
}
}
对于分页操作来说,需要知道如下一些信息:当前正在操作的是第几页、每一页显示多少条记录数。
修改query为:
Query query = session.createQuery("from People as p order by p.id asc").setFirstResult(0).setMaxResults(20);
setFirstResult()设置显示的第一条记录从结果集中开始的位置,setMaxResults(20)设置每页最多显示多少记录
更新操作:
修改main方法:
Session session = sessionFactory.openSession();
Transaction tx = null;
try
{
tx = session.beginTransaction();
People people = (People)session.load(People.class, new Long(1));
people.setUsername("xiugai111");
people.setGender('M');
people.setUsername("xiugai2222");
people.setGender('F');
people.setUsername("world");
session.update(people);
tx.commit();
}
catch(Exception ex)
{
if(null != tx)
{
tx.rollback();
}
}
finally
{
session.close();
}
更新操作涉及两个步骤,先是查询出要修改的记录,使用load方法,然后修改值,最后update方法更新。对于中间多次修改对象属性值,以最后一次为准。程序运行执行两条sql语句,一个是select,一个是update,如果将session.update(people);注释掉,结果一样,也是两条sql语句,更新也被执行了,如果将tx.commit();也注释掉,则只会执行一条select语句,不会执行update语句,不能更新数据库记录。
删除操作:
Session session = sessionFactory.openSession();
Transaction tx = null;
try
{
tx = session.beginTransaction();
Query query = session.createQuery("from People");
Iterator<People> iter = (Iterator<People>)query.iterate();
while(iter.hasNext())
{
session.delete(iter.next());
}
tx.commit();
}
catch(Exception ex)
{
if(null != tx)
{
tx.rollback();
}
}
finally
{
session.close();
}
执行的结果是:
Hibernate: select people0_.id as col_0_0_ from people people0_
Hibernate: select people0_.id as id0_0_, people0_.username as username0_0_, people0_.password as password0_0_, people0_.telphone as telphone0_0_, people0_.gender as gender0_0_, people0_.graduation as graduation0_0_, people0_.birthday as birthday0_0_, people0_.marryTime as marryTime0_0_, people0_.file as file0_0_ from people people0_ where people0_.id=?
Hibernate: select people0_.id as id0_0_, people0_.username as username0_0_, people0_.password as password0_0_, people0_.telphone as telphone0_0_, people0_.gender as gender0_0_, people0_.graduation as graduation0_0_, people0_.birthday as birthday0_0_, people0_.marryTime as marryTime0_0_, people0_.file as file0_0_ from people people0_ where people0_.id=?
Hibernate: select people0_.id as id0_0_, people0_.username as username0_0_, people0_.password as password0_0_, people0_.telphone as telphone0_0_, people0_.gender as gender0_0_, people0_.graduation as graduation0_0_, people0_.birthday as birthday0_0_, people0_.marryTime as marryTime0_0_, people0_.file as file0_0_ from people people0_ where people0_.id=?
Hibernate: select people0_.id as id0_0_, people0_.username as username0_0_, people0_.password as password0_0_, people0_.telphone as telphone0_0_, people0_.gender as gender0_0_, people0_.graduation as graduation0_0_, people0_.birthday as birthday0_0_, people0_.marryTime as marryTime0_0_, people0_.file as file0_0_ from people people0_ where people0_.id=?
Hibernate: select people0_.id as id0_0_, people0_.username as username0_0_, people0_.password as password0_0_, people0_.telphone as telphone0_0_, people0_.gender as gender0_0_, people0_.graduation as graduation0_0_, people0_.birthday as birthday0_0_, people0_.marryTime as marryTime0_0_, people0_.file as file0_0_ from people people0_ where people0_.id=?
Hibernate: delete from people where id=?
Hibernate: delete from people where id=?
Hibernate: delete from people where id=?
Hibernate: delete from people where id=?
Hibernate: delete from people where id=?
如果将程序修改一下:
Session session = sessionFactory.openSession();
Transaction tx = null;
try
{
tx = session.beginTransaction();
Query query = session.createQuery("from People");
/*
Iterator<People> iter = (Iterator<People>)query.iterate();
while(iter.hasNext())
{
session.delete(iter.next());
}
*/
List<People> list = query.list();
for(Iterator<People> iter = list.iterator();iter.hasNext();)
{
session.delete(iter.next());
}
tx.commit();
}
catch(Exception ex)
{
if(null != tx)
{
tx.rollback();
}
}
finally
{
session.close();
}
执行结果就是:
Hibernate: select people0_.id as id0_, people0_.username as username0_, people0_.password as password0_, people0_.telphone as telphone0_, people0_.gender as gender0_, people0_.graduation as graduation0_, people0_.birthday as birthday0_, people0_.marryTime as marryTime0_, people0_.file as file0_ from people people0_
Hibernate: delete from people where id=?
Hibernate: delete from people where id=?
Hibernate: delete from people where id=?
Hibernate: delete from people where id=?
Hibernate: delete from people where id=?
差别:
对于Query接口的list()方法与iterator()方法来说,都可以实现获取查询的对象,但是list()方法返回的每个对象都是完整的(对象中的每个属性都被表中的字段填充上了),而iterator()方法所返回的对象中仅包含了主键值(标示符),只有当你对iterator()中的对象进行操作时,hibernate才会向数据库再次发送SQL语句来获取该对象的属性值。
修改程序:
Session session = sessionFactory.openSession();
Transaction tx = null;
List<People> list = null;
try
{
tx = session.beginTransaction();
Query query = session.createQuery("from People");
// Iterator<People> iter = (Iterator<People>)query.iterate();
//
// while(iter.hasNext())
// {
// session.delete(iter.next());
// }
list = query.list();
for(Iterator<People> iter = list.iterator();iter.hasNext();)
{
session.delete(iter.next());
}
tx.commit();
}
catch(Exception ex)
{
if(null != tx)
{
tx.rollback();
}
}
finally
{
session.close();
}
for(People people : list)
{
System.out.println(people.getUsername());
}
}
执行结果:
Hibernate: select people0_.id as id0_, people0_.username as username0_, people0_.password as password0_, people0_.telphone as telphone0_, people0_.gender as gender0_, people0_.graduation as graduation0_, people0_.birthday as birthday0_, people0_.marryTime as marryTime0_, people0_.file as file0_ from people people0_
Hibernate: delete from people where id=?
Hibernate: delete from people where id=?
Hibernate: delete from people where id=?
zhang
zhang
zhan33
再次修改程序:
Session session = sessionFactory.openSession();
Transaction tx = null;
// List<People> list = null;
Iterator<People> iter = null;
try
{
tx = session.beginTransaction();
Query query = session.createQuery("from People");
// Iterator<People> iter = (Iterator<People>)query.iterate();
//
// while(iter.hasNext())
// {
// session.delete(iter.next());
// }
// list = query.list();
iter = (Iterator<People>)query.iterate();
// for(Iterator<People> iter = list.iterator();iter.hasNext();)
// {
// session.delete(iter.next());
// }
tx.commit();
}
catch(Exception ex)
{
ex.printStackTrace();
if(null != tx)
{
tx.rollback();
}
}
finally
{
session.close();
}
// for(People people : list)
// {
// System.out.println(people.getUsername());
// }
while(iter.hasNext())
{
System.out.println(iter.next().getId());
}
}
执行结果:
Hibernate: select people0_.id as col_0_0_ from people people0_
Exception in thread "main" org.hibernate.SessionException: Session is closed!
at org.hibernate.impl.AbstractSessionImpl.errorIfClosed(AbstractSessionImpl.java:72)
at org.hibernate.impl.SessionImpl.getPersistenceContext(SessionImpl.java:1835)
at org.hibernate.type.ManyToOneType.scheduleBatchLoadIfNeeded(ManyToOneType.java:142)
at org.hibernate.type.ManyToOneType.hydrate(ManyToOneType.java:128)
at org.hibernate.type.EntityType.nullSafeGet(EntityType.java:227)
at org.hibernate.impl.IteratorImpl.next(IteratorImpl.java:135)
at com.cdtax.hibernate.HibernateTest.main(HibernateTest.java:257)
出现了异常
这就是iterator和list的差别,这是hibernate的延迟加载机制造成的,对于iterator,是延迟加载。只有在使用到时再加载对象。
对于MyEclipse的几个视图,可在hibernate视图下进行逆向工程。