Hibernate完成单表数据库操作

2014-11-24 00:57:51 · 作者: · 浏览: 1
1、

数据库中建立一张数据表,这里建立一个张新闻表(news)

CREATE TABLE news (
id number(8) primary key ,
title varchar2(50) not null,
content varchar2(500) not null,
pub_date date not null
);

在MyEclipse中需要建立项目,并加入Hibernate框架支持。

但在这些之前,建议先在MyEclipse里建立与数据库的连接。

\

找到DBBrowser 右键new ,选择建立一个新的数据库连接< http://www.2cto.com/kf/ware/vc/" target="_blank" class="keylink">vcD4KPHA+PGltZyBzcmM9"" alt="\">


2、可以开始建立项目:

\

\

选择copy checkedLibrary jars to project folder

\

点next

加入Hibernate核心配置文件

\

3、生成的HibernateSessionFactory中,实现了连接池功能:

public class HibernateSessionFactory {

// 配置文件的所在位置和名称

private static String CONFIG_FILE_LOCATION = "/hibernate.cfg.xml";

// 用来实现连接池的,该类类似Map集合。

private static final ThreadLocal threadLocal = new ThreadLocal ();

// Hibernate用来读取配置文件的类

private static Configuration configuration = new Configuration();

// 用来建立连接的,该类就是连接池,使用单例设计模式

private static org.hibernate.SessionFactory sessionFactory;

// 备用的配置文件位置

private static String configFile = CONFIG_FILE_LOCATION;

// 静态块,类加载时最先执行

static {

try {

// 加载配置文件到内存中

configuration.configure(configFile);

// 建立连接池以及里面的连接

sessionFactory = configuration.buildSessionFactory();

} catch (Exception e) {

System.err.println("%%%% Error Creating SessionFactory %%%%");

e.printStackTrace();

}

}

private HibernateSessionFactory() {

}

/**

* 取得数据库连接对象

*

* @return Session

* @throws HibernateException

*/

public static Session getSession() throws HibernateException {

// 先从ThreadLocal中取得连接。

Session session = (Session) threadLocal.get();

// 如果手头没有连接,则取得一个新的连接

if (session == null || !session.isOpen()) {

session = sessionFactory.openSession();

// 把取得出的连接记录到ThreadLocal中,以便下次使用。

threadLocal.set(session);

}

return session;

}

/**

* 连接关闭的方法

*

* @throws HibernateException

*/

public static void closeSession() throws HibernateException {

Session session = (Session) threadLocal.get();

// 将ThreadLocal清空,表示当前线程已经没有连接。

threadLocal.set(null);

// 连接放回到连接池

if (session != null) {

session.close();

}

}

public static Configuration getConfiguration() {

return configuration;

}

}


4、根据表自动生成pojo和映射文件:

\

\

id generator 选择assigned:


\



生成的pojo对象:

public class News implements java.io.Serializable {

private Integer id;

private String title;

private String content;

private Date pubDate;

以及getter/setter方法

映射文件:

"1.0" encoding="utf-8" >

"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

"org.liky.pojo.News" table= "NEWS" schema= "SUNXUN">

"id" type= "java.lang.Integer">

"ID" precision= "8" scale= "0" />

"assigned" />

"title" type= "java.lang.String">

"TITLE" length= "50" not-null= "true" />

"content" type= "java.lang.String">

"CONTENT" length= "500" not-null= "true" />

"pubDate" type= "java.util.Date">

"PUB_DATE" length= "7" not-null= "true" />


接下来写一个公共的DAO接口方法,为了方便使用:

/**

* 公共接口

*

* @param

* 主键类型

* @param

* Vo对象的类型

*/

public interface IDAO {

public void doCreate(V vo) throws Exception;

public void doUpdate(V vo) throws Exception;

public void doRemove(K id) throws Exception;

public List findAll() throws Exception;

public V findById(K id) throws Exception;

/**

* 分页查询方法

* @param pageNo 当前页号

* @param pageSize 每页记录数

* @param keyword 关键字

* @param column 查询的字段名

* @return

* @throws Exception

*/

public List findAll( int pageNo, int pageSize, String keyword,

String column) throws Exception;

/**

* 查询全部记录数,用来计算总页数

* @param keyword

* @param column

* @return

* @throws Exception

*/

public int getAllCount(String keyword, String column) throws Exception;

}


建立新闻的接口,继承公共接口,完成操作:

public interface INewsDAO extends IDAO {

}

建立实现类对象:

public class NewsDAOImpl implements INewsDAO {

public void doCreate(News vo) throws Exception {

HibernateSessionFactory.getSession().save(vo);

}

public void doRemove(Integer id) throws Exception {

// 注意,使用Hibernate删除时,必须先查询对象,再删除.

HibernateSessionFactory.getSession().delete(findById(id));

}

public void doUpdate(News vo) throws Exception {

HibernateSessionFactory.getSession().update(vo);

}

public List findAll() throws Exception {

// 使用HQL语句完成查询功能

// 1.HQL查询的是类,而不是表

// 2.可以不写SELECT关键字

String hql = "FROM News";

Query query = HibernateSessionFactory.getSession().createQuery(hql);

return query.list();

}

public List findAll( int pageNo, int pageSize, String keyword,

String column) throws Exception {

String hql = "FROM News AS n WHERE n." + column + " LIKE ";

Query query = HibernateSessionFactory.getSession().createQuery(hql);

query.setString(0, "%" + keyword + "%");

// 分页处理

query.setFirstResult((pageNo - 1) * pageSize);

query.setMaxResults(pageSize);

return query.list();

}

public News findById(Integer id) throws Exception {

// 根据主键完成查询功能,需要传入类型,以及主键值

return (News) HibernateSessionFactory.getSession().get(News.class, id);

}

public int getAllCount(String keyword, String column) throws Exception {

// 这里由于查询的不再是对象,因此必须写SELECT统计数量

String hql = "SELECT COUNT(n) FROM News AS n WHERE n." + column

+ " LIKE ";

Query query = HibernateSessionFactory.getSession().createQuery(hql);

query.setString(0, "%" + keyword + "%");

return (Integer) query.uniqueResult();

}

}


5、建立DAO工厂类:

public class DAOFactory {

public static INewsDAO getINewsDAOInstance() {

return new NewsDAOImpl();

}

}

编写Service层,这里随意定义几个方法:

public interface INewsService {

public void insert(News news) throws Exception;

public void delete(int id) throws Exception;

public News findById(int id) throws Exception;

// 如果要一次性返回多种类型的数据,可以使用Map集合,这样方便区分.

public Map list( int pageNo, int pageSize, String keyword,

String column) throws Exception;

}

建立实现类

public class NewsServiceImpl implements INewsService {

public void delete(int id) throws Exception {

// 加入事务处理功能

Transaction tx = HibernateSessionFactory.getSession()

.beginTransaction();

try {

DAOFactory.getINewsDAOInstance().doRemove(id);

tx.commit();

} catch (Exception e) {

e.printStackTrace();

tx.rollback();

throw e;

} finally {

HibernateSessionFactory.closeSession();

}

}

public News findById(int id) throws Exception {

News news = null;

try {

news = DAOFactory.getINewsDAOInstance().findById(id);

} catch (Exception e) {

e.printStackTrace();

throw e;

} finally {

HibernateSessionFactory.closeSession();

}

return news;

}

public void insert(News news) throws Exception {

// 加入事务处理功能

Transaction tx = HibernateSessionFactory.getSession()

.beginTransaction();

try {

DAOFactory.getINewsDAOInstance().doCreate(news);

tx.commit();

} catch (Exception e) {

e.printStackTrace();

tx.rollback();

throw e;

} finally {

HibernateSessionFactory.closeSession();

}

}

public Map list( int pageNo, int pageSize, String keyword,

String column) throws Exception {

Map map = new HashMap ();

try {

map.put("allNews", DAOFactory.getINewsDAOInstance().findAll(pageNo,

pageSize, keyword, column));

map.put("allCount", DAOFactory.getINewsDAOInstance().getAllCount(

keyword, column));

} catch (Exception e) {

e.printStackTrace();

throw e;

} finally {

HibernateSessionFactory.closeSession();

}

return map;

}

}

建立service工厂类

public class ServiceFactory {

public static INewsService getINewsServiceInstance() {

return new NewsServiceImpl();

}

}

建立完可以用Juint4测试,新建一个与src文件夹平级的test folder

\


测试时会发现,查询全部记录数方法出错,因为类型转换问题;

public int getAllCount(String keyword, String column) throws Exception {

// 这里由于查询的不再是对象,因此必须写SELECT统计数量

String hql = "SELECT COUNT(n) FROM News AS n WHERE n." + column

+ " LIKE ";

Query query = HibernateSessionFactory.getSession().createQuery(hql);

query.setString(0, "%" + keyword + "%");

// 手工使用拆箱方法,将Long转换为基本数据类型的int.

return ((Long) query.uniqueResult()).intValue();

}

测试代码如下:

public class NewsServiceImplTest {

@Test

public void testDelete() throws Exception {

ServiceFactory.getINewsServiceInstance().delete(2);

}

@Test

public void testFindById() throws Exception {

System.out.println(ServiceFactory.getINewsServiceInstance().findById(2)

.getTitle());

}

@Test

public void testInsert() throws Exception {

News news = new News(3, "测试添加数据032", "测试内容023", new Date());

ServiceFactory.getINewsServiceInstance().insert(news);

}

@Test

public void testList() throws Exception {

Map map = ServiceFactory. getINewsServiceInstance()

.list(1, 2, "添加", "title");

System.out.println(map.get("allCount"));

System.out.println(map.get("allNews"));

}

}


6、如果想使用主键自增长功能,可以使用以下两种方式:

1) increment:

"id" type= "java.lang.Integer">

"ID" precision= "8" scale= "0" />

"increment" />

1) sequence:

先建立好序列

CREATE SEQUENCE news_seq;

修改配置文件

"id" type= "java.lang.Integer">

"ID" precision= "8" scale= "0" />

"sequence">

"sequence">news_seq