Hibernate完成单表数据库操作

2024-08-31 13:18

本文主要是介绍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里建立与数据库的连接

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



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



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方法

映射文件:

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



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

    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完成单表数据库操作的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1124009

相关文章

Java字符串操作技巧之语法、示例与应用场景分析

《Java字符串操作技巧之语法、示例与应用场景分析》在Java算法题和日常开发中,字符串处理是必备的核心技能,本文全面梳理Java中字符串的常用操作语法,结合代码示例、应用场景和避坑指南,可快速掌握字... 目录引言1. 基础操作1.1 创建字符串1.2 获取长度1.3 访问字符2. 字符串处理2.1 子字

数据库面试必备之MySQL中的乐观锁与悲观锁

《数据库面试必备之MySQL中的乐观锁与悲观锁》:本文主要介绍数据库面试必备之MySQL中乐观锁与悲观锁的相关资料,乐观锁适用于读多写少的场景,通过版本号检查避免冲突,而悲观锁适用于写多读少且对数... 目录一、引言二、乐观锁(一)原理(二)应用场景(三)示例代码三、悲观锁(一)原理(二)应用场景(三)示例

Node.js 数据库 CRUD 项目示例详解(完美解决方案)

《Node.js数据库CRUD项目示例详解(完美解决方案)》:本文主要介绍Node.js数据库CRUD项目示例详解(完美解决方案),本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考... 目录项目结构1. 初始化项目2. 配置数据库连接 (config/db.js)3. 创建模型 (models/

Python 中的 with open文件操作的最佳实践

《Python中的withopen文件操作的最佳实践》在Python中,withopen()提供了一个简洁而安全的方式来处理文件操作,它不仅能确保文件在操作完成后自动关闭,还能处理文件操作中的异... 目录什么是 with open()?为什么使用 with open()?使用 with open() 进行

Linux ls命令操作详解

《Linuxls命令操作详解》通过ls命令,我们可以查看指定目录下的文件和子目录,并结合不同的选项获取详细的文件信息,如权限、大小、修改时间等,:本文主要介绍Linuxls命令详解,需要的朋友可... 目录1. 命令简介2. 命令的基本语法和用法2.1 语法格式2.2 使用示例2.2.1 列出当前目录下的文

Spring Security基于数据库的ABAC属性权限模型实战开发教程

《SpringSecurity基于数据库的ABAC属性权限模型实战开发教程》:本文主要介绍SpringSecurity基于数据库的ABAC属性权限模型实战开发教程,本文给大家介绍的非常详细,对大... 目录1. 前言2. 权限决策依据RBACABAC综合对比3. 数据库表结构说明4. 实战开始5. MyBA

Ubuntu中远程连接Mysql数据库的详细图文教程

《Ubuntu中远程连接Mysql数据库的详细图文教程》Ubuntu是一个以桌面应用为主的Linux发行版操作系统,这篇文章主要为大家详细介绍了Ubuntu中远程连接Mysql数据库的详细图文教程,有... 目录1、版本2、检查有没有mysql2.1 查询是否安装了Mysql包2.2 查看Mysql版本2.

Oracle数据库常见字段类型大全以及超详细解析

《Oracle数据库常见字段类型大全以及超详细解析》在Oracle数据库中查询特定表的字段个数通常需要使用SQL语句来完成,:本文主要介绍Oracle数据库常见字段类型大全以及超详细解析,文中通过... 目录前言一、字符类型(Character)1、CHAR:定长字符数据类型2、VARCHAR2:变长字符数

Win11安装PostgreSQL数据库的两种方式详细步骤

《Win11安装PostgreSQL数据库的两种方式详细步骤》PostgreSQL是备受业界青睐的关系型数据库,尤其是在地理空间和移动领域,:本文主要介绍Win11安装PostgreSQL数据库的... 目录一、exe文件安装 (推荐)下载安装包1. 选择操作系统2. 跳转到EDB(PostgreSQL 的

SpringBoot实现数据库读写分离的3种方法小结

《SpringBoot实现数据库读写分离的3种方法小结》为了提高系统的读写性能和可用性,读写分离是一种经典的数据库架构模式,在SpringBoot应用中,有多种方式可以实现数据库读写分离,本文将介绍三... 目录一、数据库读写分离概述二、方案一:基于AbstractRoutingDataSource实现动态