Hibernate 数据库操作实例


毛晓彤


参考博客:http://blog.csdn.net/fxdaniel/article/details/42420779

Hibernate 数据库操作示例

版本信息

Hibernate版本 4.3.11
Tomcat 8.0
JDK 1.8
Eclipse版本 Neon.1a Release (4.6.1)
Eclipse插件JBoss Tools 4.4.1
数据库 MySQL

数据库部分,自己新建一个数据库,我这里建的sh2,自己不用建表。

C:\Users\Peng>mysql -uroot -proot
mysql> create database sh2;

这里写图片描述

Jar 包使用 lib\required目录下的包就行,此外还需要一个数据库连接的包。需要包的直接下源码。
导入Junit 直接在项目的 Java Bulid Path 中 Add Library找到Junit
源码下载

hibernate-release-4.3.11.Final\lib\required

源码

这里写图片描述

首先是创建 hibernate.cfg.xml,配置Hibernate数据库的配置信息,然后创建POJO类(JavaBean持久化对象),然后创建对应的对象-关系映射文件(安装了JBOSS 可以自动创建),XXX.hbm.xml,然后创建Hibernate数据库连接的工具类HibernateUtil.java,随后就是dao层,dao.impl层,最后在junit.test包中写测试类。
下面的代码按照包分类

src目录

hibernate.cfg.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
    <session-factory>
        <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="hibernate.connection.password">root</property>
        <property name="hibernate.connection.url">jdbc:mysql://127.0.0.1:3306/sh2?useUnicod=true&amp;characterEncoding=utf8</property>
        <property name="hibernate.connection.username">root</property>
        <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>

        <property name="show_sql">true</property>
        <property name="format_sql">true</property>
        <property name="hbm2ddl.auto">update</property>

        <mapping resource="jxust/model/User.hbm.xml"/>
    </session-factory>
</hibernate-configuration>

jxust.model 包

User.java

package jxust.model;

public class User {

    private int id;// 持久化类的标识属性,映射到数据表中的主键列
    private String name;
    private String password;
    private String type;

    //getter and setter
    @Override
    public String toString() {
        return "User [id=" + id + ", name=" + name + ", password=" + password + ", type=" + type + "]";
    }
}

User.hbm.xml

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated 2016-11-18 22:14:41 by Hibernate Tools 3.5.0.Final -->
<hibernate-mapping>
<!-- name 持久化类的类名,table 数据表的表名,MySQL不区分大小写 --> 
    <class name="jxust.model.User" table="USER" lazy="false">
     <!-- 将User类中的id属性映射为数据表USER中的主键列ID --> 
        <id name="id" type="int">
            <column name="ID" />
            <generator class="native" />
        </id>
         <!-- 映射User类的name属性 --> 
        <property name="name" type="java.lang.String">
            <column name="NAME" length="20"/>
        </property>
         <!-- 映射User类的password属性 --> 
        <property name="password" type="java.lang.String">
            <column name="PASSWORD" length="12"/>
        </property>
        <!-- 映射User类的type属性 -->  
        <property name="type" type="java.lang.String">
            <column name="TYPE" length="6"/>
        </property>
    </class>
</hibernate-mapping>

HibernateUtil.java

package jxust.model;

import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;

public class HibernateUtil {

    private static SessionFactory sessionFactory;
    // 创建线程局部变量threadLocal,用来保存Hibernate的Session
    private static final ThreadLocal<Session> threadLocal = new ThreadLocal<Session>();
    // 使用静态代码块初始化Hibernate
    static {
        try {
            // 读取配置文件
            Configuration cfg = new Configuration().configure();
            // 创建服务注册对象
            StandardServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder()
                    .applySettings(cfg.getProperties()).build();
            // 创建会话工厂对象SessionFactory
            sessionFactory = cfg.buildSessionFactory(serviceRegistry);
        } catch (Throwable ex) {
            throw new ExceptionInInitializerError(ex);
        }
    }

    // 获得SessionFactory的实例
    public static SessionFactory getsSessionFactory() {
        return sessionFactory;
    }

    // 获得ThreadLocal对象管理的Session
    public static Session getsSession() throws HibernateException {
        Session session = (Session) threadLocal.get();
        if (session == null || !session.isOpen()) {
            if (sessionFactory == null) {
                rebuildSessionFactory();
            }
            // 通过SessionFactory对象创建Session对象
            session = (sessionFactory != null) ? sessionFactory.openSession() : null;
            // 将Session对象保存到线程局部变量threadLocal中
            threadLocal.set(session);
        }
        return session;
    }

    // 关闭Session实例
    public static void closeSession() {
        // 从线程局部变量threadLocal中获取之前存入的Session实例
        Session session = (Session) threadLocal.get();
        threadLocal.set(null);
        if (session != null) {
            session.close();
        }
    }

    // 重建SessionFactory
    public static void rebuildSessionFactory() {
        Configuration configuration = new Configuration();  
        configuration.configure("/hibernate.cfg.xml");
        StandardServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder()
                .applySettings(configuration.getProperties()).build();
        sessionFactory = configuration.buildSessionFactory(serviceRegistry);
    }

    // 关闭缓存和连接池
    public static void shutdown() {
        getsSessionFactory().close();
    }
}

jxust.dao 包

UserDAO.java

package jxust.dao;

import java.util.List;

import jxust.model.User;

public interface UserDAO {

    public void save(User user);

    public User findByIdGet(int id);

    public User findByIdLoad(int id);

    public List<User>  findByHQL(String hql);

    public void delete(User user);

    public void update(User user);
}

jxust.dao.impl

UserDaoImpl.java

package jxust.dao.impl;

import java.util.ArrayList;
import java.util.List;

import org.hibernate.Session;
import org.hibernate.Transaction;

import jxust.dao.UserDAO;
import jxust.model.HibernateUtil;
import jxust.model.User;

public class UserDaoImpl implements UserDAO {

    // 添加用户,需要事务管理
    @Override
    public void save(User user) {
        // 创建Session实例
        Session session = HibernateUtil.getsSession();
        // 创建Transaction实例
        Transaction tx = session.beginTransaction();

        try {
            // 使用Session的save方法将持久化对象保存到数据库
            session.save(user);
            // 提交事务
            tx.commit();
        } catch (Exception e) {
            e.printStackTrace();
            // 出现异常,回滚事务
            tx.rollback();
        } finally {
            // 关闭Session连接
            HibernateUtil.closeSession();
        }

    }

    // 根据id查找用户 ,可以不需要事务管理 Get方式
    @Override
    public User findByIdGet(int id) {
        User user = null;
        Session session = HibernateUtil.getsSession();
        // 使用session的get方法获取指定id的用户
        user = (User) session.get(User.class, id);
        if (user == null || "".equals(user)) {
            System.out.println("查询id为:" + id + "无结果....");
        }
        session.close();
        return user;
    }

    // 根据id查找用户 ,可以不需要事务管理 Load方式
    @Override
    public User findByIdLoad(int id) {
        User user = null;
        Session session = HibernateUtil.getsSession();
        // 使用session的方法获取指定id的用户
        user = (User) session.load(User.class, id);
        if (user == null || "".equals(user)) {
            System.out.println("查询id为:" + id + "无结果....");
        }
        session.close();
        return user;
    }

    // 根据HQl语句查询
    @Override
    public List<User> findByHQL(String hql) {
        List<User> list = new ArrayList<>();
        Session session = HibernateUtil.getsSession();
        list = session.createQuery(hql).list();
        session.close();
        return list;
    }

    // 删除用户 ,需要事务管理
    @Override
    public void delete(User user) {
        Session session = HibernateUtil.getsSession();
        Transaction tx = session.beginTransaction();
        try {
            session.delete(user);
            tx.commit();
        } catch (Exception e) {
            e.printStackTrace();
            tx.rollback();
        } finally {
            HibernateUtil.closeSession();
        }
    }

    // 修改用户
    @Override
    public void update(User user) {
        Session session = HibernateUtil.getsSession();
        Transaction tx = session.beginTransaction();
        try {
            session.update(user);
            tx.commit();
        } catch (Exception e) {
            e.printStackTrace();
            tx.rollback();
        } finally {
            HibernateUtil.closeSession();
        }
    }
}

junit.test

UserDaoTest.java

package junit.test;

import java.util.List;

import org.junit.Test;

import jxust.dao.impl.UserDaoImpl;
import jxust.model.User;

public class UserDaoTest {
    @Test
    public void testsave() {
        UserDaoImpl udi = new UserDaoImpl();
        User user = new User();
        user.setId(12);// 主键设置为native 自增,这里设置无效
        user.setName("夜阑1");
        user.setPassword("yeye");
        user.setType("admin");
        udi.save(user);
    }

    @Test
    public void testfindByIdGet() {
        UserDaoImpl udi = new UserDaoImpl();
        User user = udi.findByIdGet(1);
        System.out.println(user.toString());
    }

    @Test
    public void testfindByIdLoad() {
        UserDaoImpl udi = new UserDaoImpl();
        User user = udi.findByIdLoad(2);
        System.out.println(user.toString());
        // 必须在User.hbm.xml文件的class中设置lazy="false",不使用代理对象,否则有异常
    }

    @Test
    public void testfindByHQL() {
        List<User> list = null;
        UserDaoImpl udi = new UserDaoImpl();
        /**
         * 关键字最好大写,这里为了方便 
         * 因为返回的要是User对象集合,查询内容要相对应
         */
        // 1 String hql="FROM User";
        // 2 String hql="from User where type='admin'";
        String hql = "from User where name like '%夜%'";
        list = udi.findByHQL(hql);
        for (User s : list) {
            System.out.println(s.toString());
        }
    }

    @Test
    public void testdelete() {
        UserDaoImpl udi = new UserDaoImpl();
        User user = new User();
        user.setId(5);// 根据主键删除,必须设置
        /**
         * 如果主键设置了,其他键也设置
         * 其他键的数据要与数据库相同 否则不能删除成功,发生异常
         */
        user.setName("夜阑2");// 数据库中id为5的name值为夜阑1,有异常,删除不成功
        // user.setPassword("yeye234");
        udi.delete(user);
    }

    @Test
    public void testupdate() {
        UserDaoImpl udi = new UserDaoImpl();
        User user = new User();
        user.setId(6);// 主键必须设置,修改id为6的项
        user.setName("我不是夜阑1");// 其他属性未设置则为空
        udi.update(user);
    }
}

测试添加的数据

我一开始通过testsave方法添加的4条数据

mysql> select* from user;
+----+----------+----------+-------+
| ID | NAME     | PASSWORD | TYPE  |
+----+----------+----------+-------+
|  1 | 陈奕迅   | chenchen | admin |
|  2 | 风平浪静 | pingping | admin |
|  3 | 夜阑     | yeye     | admin |
|  4 | 夜阑1    | yeye     | admin |
+----+----------+----------+-------+
4 rows in set (0.00 sec)

测试删除数据

删除时session.delete(User user)
根据 user 对象的id值删除数据,(因为主键是唯一标识,候选码不知道可不可以)
如果设置其他属性
user.setName("夜阑2");(数据库信息为夜阑1,所以不能删除成功)
如果和数据库的信息匹配则可以删除成功,否则不能删除成功
下面是删除过后,再次添加数据,id自增变为了5

mysql> select* from user;
+----+----------+----------+-------+
| ID | NAME     | PASSWORD | TYPE  |
+----+----------+----------+-------+
|  1 | 陈奕迅   | chenchen | admin |
|  2 | 风平浪静 | pingping | admin |
|  3 | 夜阑     | yeye     | admin |
|  5 | 夜阑1    | yeye     | admin |
+----+----------+----------+-------+
4 rows in set (0.00 sec)

测试更新

user.setId(6);// 主键必须设置,修改id为6的项
user.setName("我不是夜阑1");// 其他属性未设置则为空
udi.update(user);

没有指定修改的PASSWORD 和TYPE属性,则为null

mysql> select* from user;
+----+-------------+----------+-------+
| ID | NAME        | PASSWORD | TYPE  |
+----+-------------+----------+-------+
|  1 | 陈奕迅      | chenchen | admin |
|  2 | 风平浪静    | pingping | admin |
|  3 | 夜阑        | yeye     | admin |
|  6 | 我不是夜阑1 | NULL     | NULL  |
+----+-------------+----------+-------+
4 rows in set (0.05 sec)

更多Hibernate查询,HQL语句查看:http://blog.csdn.net/peng_hong_fu/article/details/53229170

执行测试时,控制台输出的一些代码和异常

控制台Hibernate输出语句.txt


保存数据
Hibernate: 
    insert 
    into
        USER
        (NAME, PASSWORD, TYPE) 
    values
        (?, ?, ?)

 ********************************       
根据id查询get方式
Hibernate: 
    select
        user0_.ID as ID1_0_0_,
        user0_.NAME as NAME2_0_0_,
        user0_.PASSWORD as PASSWORD3_0_0_,
        user0_.TYPE as TYPE4_0_0_ 
    from
        USER user0_ 
    where
        user0_.ID=?
查询没有的id,出现NullPointerException
java.lang.NullPointerException
********************************       
根据id查询load方式        
Hibernate: 
    select
        user0_.ID as ID1_0_0_,
        user0_.NAME as NAME2_0_0_,
        user0_.PASSWORD as PASSWORD3_0_0_,
        user0_.TYPE as TYPE4_0_0_ 
    from
        USER user0_ 
    where
        user0_.ID=?
没有设置   lazy="false",会出现以下异常
java.lang.ClassCastException: jxust.model.User_$$_javassist_0 cannot be cast to javassist.util.proxy.Proxy
查询没有的id,出现ObjectNotFoundException
org.hibernate.ObjectNotFoundException: No row with the given identifier exists: [jxust.model.User#7]
******************************** 
HQL方式查询所有 "from User"
Hibernate: 
    select
        user0_.ID as ID1_0_,
        user0_.NAME as NAME2_0_,
        user0_.PASSWORD as PASSWORD3_0_,
        user0_.TYPE as TYPE4_0_ 
    from
        USER user0_ 

HQL方式 模糊查询"from User where name like '%夜%'"
Hibernate: 
    select
        user0_.ID as ID1_0_,
        user0_.NAME as NAME2_0_,
        user0_.PASSWORD as PASSWORD3_0_,
        user0_.TYPE as TYPE4_0_ 
    from
        USER user0_ 
    where
        user0_.NAME like '%夜%'
******************************** 
删除
Hibernate: 
    delete 
    from
        USER 
    where
        ID=?
单独主键外的值,删除无效
 如果主键设置了,其他键也设置
 其他键的数据要与数据库相同
 否则发生异常     
org.hibernate.StaleStateException: Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1
******************************** 
更新数据
Hibernate: 
    update
        USER 
    set
        NAME=?,
        PASSWORD=?,
        TYPE=? 
    where
        ID=?
******************************** 

cmd端,记录的信息

C:\Users\Peng>mysql -uroot -proot
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 160
Server version: 5.7.12-log MySQL Community Server (GPL)

Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> user sh2;
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'user sh2' at line 1
mysql> use sh2;
Database changed
mysql> show tables;
Empty set (0.00 sec)

mysql> show tables;
+---------------+
| Tables_in_sh2 |
+---------------+
| user          |
+---------------+
1 row in set (0.00 sec)

mysql> select* from user;
+----+--------+----------+-------+
| ID | NAME   | PASSWORD | TYPE  |
+----+--------+----------+-------+
|  1 | 陈奕迅 | chenchen | admin |
+----+--------+----------+-------+
1 row in set (0.00 sec)

mysql> select* from user;
+----+----------+----------+-------+
| ID | NAME     | PASSWORD | TYPE  |
+----+----------+----------+-------+
|  1 | 陈奕迅   | chenchen | admin |
|  2 | 风平浪静 | pingping | admin |
+----+----------+----------+-------+
2 rows in set (0.06 sec)

mysql> select* from user;
+----+----------+----------+-------+
| ID | NAME     | PASSWORD | TYPE  |
+----+----------+----------+-------+
|  1 | 陈奕迅   | chenchen | admin |
|  2 | 风平浪静 | pingping | admin |
|  3 | 夜阑     | yeye     | admin |
+----+----------+----------+-------+
3 rows in set (0.00 sec)

mysql> select* from user;
+----+----------+----------+-------+
| ID | NAME     | PASSWORD | TYPE  |
+----+----------+----------+-------+
|  1 | 陈奕迅   | chenchen | admin |
|  2 | 风平浪静 | pingping | admin |
|  3 | 夜阑     | yeye     | admin |
|  4 | 夜阑1    | yeye     | admin |
+----+----------+----------+-------+
4 rows in set (0.00 sec)

mysql> select* from user;
+----+----------+----------+-------+
| ID | NAME     | PASSWORD | TYPE  |
+----+----------+----------+-------+
|  1 | 陈奕迅   | chenchen | admin |
|  2 | 风平浪静 | pingping | admin |
|  3 | 夜阑     | yeye     | admin |
|  4 | 夜阑1    | yeye     | admin |
+----+----------+----------+-------+
4 rows in set (0.00 sec)

mysql> select* from user;
+----+----------+----------+-------+
| ID | NAME     | PASSWORD | TYPE  |
+----+----------+----------+-------+
|  1 | 陈奕迅   | chenchen | admin |
|  2 | 风平浪静 | pingping | admin |
|  3 | 夜阑     | yeye     | admin |
|  4 | 夜阑1    | yeye     | admin |
+----+----------+----------+-------+
4 rows in set (0.00 sec)

mysql> select* from user;
+----+----------+----------+-------+
| ID | NAME     | PASSWORD | TYPE  |
+----+----------+----------+-------+
|  1 | 陈奕迅   | chenchen | admin |
|  2 | 风平浪静 | pingping | admin |
|  3 | 夜阑     | yeye     | admin |
+----+----------+----------+-------+
3 rows in set (0.00 sec)

mysql> select* from user;
+----+----------+----------+-------+
| ID | NAME     | PASSWORD | TYPE  |
+----+----------+----------+-------+
|  1 | 陈奕迅   | chenchen | admin |
|  2 | 风平浪静 | pingping | admin |
|  3 | 夜阑     | yeye     | admin |
|  5 | 夜阑1    | yeye     | admin |
+----+----------+----------+-------+
4 rows in set (0.00 sec)

mysql> select* from user;
+----+----------+----------+-------+
| ID | NAME     | PASSWORD | TYPE  |
+----+----------+----------+-------+
|  1 | 陈奕迅   | chenchen | admin |
|  2 | 风平浪静 | pingping | admin |
|  3 | 夜阑     | yeye     | admin |
+----+----------+----------+-------+
3 rows in set (0.00 sec)

mysql> select* from user;
+----+----------+----------+-------+
| ID | NAME     | PASSWORD | TYPE  |
+----+----------+----------+-------+
|  1 | 陈奕迅   | chenchen | admin |
|  2 | 风平浪静 | pingping | admin |
|  3 | 夜阑     | yeye     | admin |
|  6 | 夜阑1    | yeye     | admin |
+----+----------+----------+-------+
4 rows in set (0.00 sec)

mysql> select* from user;
+----+----------+----------+-------+
| ID | NAME     | PASSWORD | TYPE  |
+----+----------+----------+-------+
|  1 | 陈奕迅   | chenchen | admin |
|  2 | 风平浪静 | pingping | admin |
|  3 | 夜阑     | yeye     | admin |
|  6 | 夜阑1    | yeye     | admin |
+----+----------+----------+-------+
4 rows in set (0.00 sec)

mysql> select* from user;
+----+----------+----------+-------+
| ID | NAME     | PASSWORD | TYPE  |
+----+----------+----------+-------+
|  1 | 陈奕迅   | chenchen | admin |
|  2 | 风平浪静 | pingping | admin |
|  3 | 夜阑     | yeye     | admin |
|  6 | 夜阑1    | yeye     | admin |
+----+----------+----------+-------+
4 rows in set (0.00 sec)

mysql> select* from user;
+----+----------+----------+-------+
| ID | NAME     | PASSWORD | TYPE  |
+----+----------+----------+-------+
|  1 | 陈奕迅   | chenchen | admin |
|  2 | 风平浪静 | pingping | admin |
|  3 | 夜阑     | yeye     | admin |
|  6 | 夜阑1    | yeye     | admin |
+----+----------+----------+-------+
4 rows in set (0.00 sec)

mysql> select* from user;
+----+-------------+----------+-------+
| ID | NAME        | PASSWORD | TYPE  |
+----+-------------+----------+-------+
|  1 | 陈奕迅      | chenchen | admin |
|  2 | 风平浪静    | pingping | admin |
|  3 | 夜阑        | yeye     | admin |
|  6 | 我不是夜阑1 | NULL     | NULL  |
+----+-------------+----------+-------+
4 rows in set (0.05 sec)

mysql> select* from user;
+----+-------------+----------+-------+
| ID | NAME        | PASSWORD | TYPE  |
+----+-------------+----------+-------+
|  1 | 陈奕迅      | chenchen | admin |
|  2 | 风平浪静    | pingping | admin |
|  3 | 夜阑        | yeye     | admin |
|  6 | 我不是夜阑1 | NULL     | NULL  |
+----+-------------+----------+-------+
4 rows in set (0.00 sec)

mysql> desc user;
+----------+-------------+------+-----+---------+----------------+
| Field    | Type        | Null | Key | Default | Extra          |
+----------+-------------+------+-----+---------+----------------+
| ID       | int(11)     | NO   | PRI | NULL    | auto_increment |
| NAME     | varchar(20) | YES  |     | NULL    |                |
| PASSWORD | varchar(12) | YES  |     | NULL    |                |
| TYPE     | varchar(6)  | YES  |     | NULL    |                |
+----------+-------------+------+-----+---------+----------------+
4 rows in set (0.00 sec)

mysql>

源码下载

http://download.csdn.net/detail/peng_hong_fu/9687346

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值