Hibernate完成单表数据库操作

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里建立与数据库的连接

Hibernate完成单表数据库操作

找到DBBrowser 右键new ,选择建立一个新的数据库连接

Hibernate完成单表数据库操作


2、可以开始建立项目:

Hibernate完成单表数据库操作

Hibernate完成单表数据库操作

选择copy checkedLibrary jars to project folder

Hibernate完成单表数据库操作

点next 

加入Hibernate核心配置文件

Hibernate完成单表数据库操作

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

public class HibernateSessionFactory {

 

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

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

 

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

    private static final ThreadLocal<Session> threadLocal = new ThreadLocal<Session>();

    // 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和映射文件:

Hibernate完成单表数据库操作

Hibernate完成单表数据库操作

id generator 选择assigned


Hibernate完成单表数据库操作



生成的pojo对象:

public class News implements java.io.Serializable {

 

    private Integer id;

    private String title;

    private String content;

    private Date pubDate;

 以及getter/setter方法

映射文件:

<?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>

    <!--

        News类和SUNXUN用户下的NEWS表映射.

    -->

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

    <!--

        类中的Integer类型的id对应表中的主键

    -->

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

        <!--

            表中主键字段为ID

        -->

            <column name="ID" precision="8" scale="0" />

            <!--

              主键生成方式

            -->

            <generator class="assigned" />

        </id>

        <!--

        类中的String类型的title属性与表中的TITLE字段对应,长度是50,不允许为空

        -->

        <property name="title" type="java.lang.String">

            <column name="TITLE" length="50" not-null="true" />

        </property>

        <property name="content" type="java.lang.String">

            <column name="CONTENT" length="500" not-null="true" />

        </property>

        <property name="pubDate" type="java.util.Date">

            <column name="PUB_DATE" length="7" not-null="true" />

        </property>

    </class>

</hibernate-mapping>


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

/**

 * 公共接口

 *

 * @param<K>

 *            主键类型

 * @param<V>

 *            Vo对象的类型

 */

public interface IDAO<K, V> {

 

    public void doCreate(V vo) throws Exception;

 

    public void doUpdate(V vo) throws Exception;

 

    public void doRemove(K id) throws Exception;

 

    public List<V> findAll() throws Exception;

 

    public V findById(K id) throws Exception;

 

    /**

     * 分页查询方法

     * @param pageNo 当前页号

     * @param pageSize 每页记录数

     * @param keyword 关键字

     * @param column 查询的字段名

     * @return

     * @throws Exception

     */

    public List<V> 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<Integer, News> {

 

}

建立实现类对象:

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<News> findAll() throws Exception {

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

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

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

        String hql = "FROM News";

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

        return query.list();

    }

 

    public List<News> 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<String, Object> 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<String, Object> list(int pageNo, int pageSize, String keyword,

            String column) throws Exception {

        Map<String, Object> map = new HashMap<String, Object>();

        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

Hibernate完成单表数据库操作


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

    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<String, Object> map = ServiceFactory.getINewsServiceInstance()

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

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

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

 

    }

 

}


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

1)  increment:

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

        <!--

            表中主键字段为ID

        -->

            <column name="ID" precision="8" scale="0" />

            <!--

              主键生成方式

            -->

            <generator class="increment" />

        </id>

1)  sequence:

      先建立好序列

CREATE SEQUENCE news_seq;

修改配置文件

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

            <!--

            表中主键字段为ID

        -->

            <column name="ID" precision="8" scale="0" />

            <!--

              主键生成方式

            -->

            <generator class="sequence">

                <param name="sequence">news_seq</param>

            </generator>

        </id>




Hibernate完成单表数据库操作,布布扣,bubuko.com

Hibernate完成单表数据库操作

上一篇:SQLITE笔记


下一篇:Photoshop创意平面设计之商场VIP卡的制作教程