J2EE--Hibernate基础笔记
因为写的是基础内容,所以在这里,(映射集合、映射组件、复合主键和联合主键,jpa annotation,关联映射,hql等等实用内容)都不会提到~
这里写的就是试用李刚《J2EE实战》那本书里的小demo的时候发生的错误。其实我发现这本书附带的例子真的是各种错误,实在是太水。
所谓Hibernate,实际上就是:PO(持久化类) = POJO(普通、传统java对象) + 映射文件。
下面直接给出书中提供的例子作为问题解析的驱动。
首先我们在Eclipse下新建一个Dynamic Web Project。
先把需要用到的jar包放入到/WebContent/WEB-INF/lib文件夹内,我们可以用Eclipse来加,不过我比较喜欢直接在文件夹中操作,复制粘贴即可,这些包我们可以在hibernate压缩包里面找到。
然后在项目工程的src文件夹内新建和编写如下文件:
其中hibernate.cfg.xml是标准的hibernate配置文件,web应用会首先搜索这个配置文件(其实是先搜索properties文件,搜不到再搜xml),News.hbm.xml文件是我们人为定义的配置文件,用来对应一个POJO类(普通Java类),从而进行数据库持久化操作。
文件夹lee里面有两个类,一个类对应数据库表,一个类有主方法,用于测试。
先看看POJO类:
package lee;
public class News
{
//ID,自增长列
private int id;
//标题
private String title;
//内容
private String content;
//下面是构造函数,以及getter方法和setter方法
public News()
{
}
public void setId(int id)
{
this.id = id;
}
public int getId()
{
return (this.id);
}
public void setTitle(String title)
{
this.title = title;
}
public String getTitle()
{
return (this.title);
}
public void setContent(String content)
{
this.content = content;
}
public String getContent()
{
return (this.content);
}
}
可见,一点持久化操作都不用写,只是一个普通的JavaBean。
那它是怎么对应到数据库的,关键就在于上面两个配置文件的配置,首先看看News.hbm.xml的配置:
<?xml version="1.0" encoding="gb2312"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping package="lee">
<!-- 一个类,对应一个表 -->
<class name="News" table="news_table">
<!--表的主键,自增长ID-->
<id name="id">
<generator class="identity"/>
</id>
<!-- 两个普通属性 -->
<property name="title"/>
<property name="content"/>
</class>
</hibernate-mapping>
然后,配置hibernate.cfg.xml文件,在文件内将News.hbm.xml的配置内容映射进来:
<?xml version="1.0" encoding="GBK"?> <!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"> <hibernate-configuration>
<session-factory>
<!-- 数据库驱动,众所周知 -->
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<!-- 数据库名 -->
<property name="connection.url">jdbc:mysql://localhost/hibernate</property>
<!-- 连接数据库所用的用户名 -->
<property name="connection.username">nero</property>
<!-- 密码 -->
<property name="connection.password">123456</property>
<!-- 最大连接数 -->
<property name="hibernate.c3p0.max_size">20</property>
<!-- 最小连接数-->
<property name="hibernate.c3p0.min_size">1</property>
<!-- 连接超时时长限制 -->
<property name="hibernate.c3p0.timeout">5000</property>
<!-- 指定缓冲池里的陈述数量限制 -->
<property name="hibernate.c3p0.max_statements">100</property>
<property name="hibernate.c3p0.idle_test_period">3000</property>
<property name="hibernate.c3p0.acquire_increment">2</property>
<property name="hibernate.c3p0.validate">true</property>
<!-- 数据库方言 -->
<property name="dialect">org.hibernate.dialect.MySQLInnoDBDialect</property>
<!-- 设置是否自动创建表 -->
<property name="hbm2ddl.auto">create</property> <!-- 映射所有配置文件-->
<mapping resource="News.hbm.xml"/>
</session-factory>
</hibernate-configuration>
然后,在lee包里创建一个有main方法的主类进行测试:
public class NewsManager
{
public static void main(String[] args) throws Exception
{
//自动加载hibernate.cfg.xml
Configuration conf = new Configuration().configure();
//通过Configuration对象获取工厂类对象SessionFactory
SessionFactory sf = conf.buildSessionFactory();
//获取Session
Session sess = sf.openSession();
//获取对话
Transaction tx = sess.beginTransaction();
//存储操作
News n = new News();
n.setTitle("test title");
n.setContent("http://www.crazyjava.org");
sess.save(n);
//提交
tx.commit();
//关闭Session
sess.close();
}
}
可见整个过程是非常简单易懂的,按部就班操作即可。至于想做查询操作什么的,用hql就可以了,这是hibernate提供的查询方式,基本语法规则和标准SQL是相差无几的。这篇笔记不写这个。
看着好像是可以运行了,运行主类,报错。
我们在News.hbm.xml配置文件中不是指定了类对应的数据库表名是'news_table'么,但是执行主类的时候报错如下:
SEVERE: Table 'hibernate.news_table' doesn't exist
也就说这个表不存在,后来呢,我用nero这个账户登录到mysql自行创建了题目要求的数据库和表还是不行,照样报同一个错。
mysql>use hibernate;
mysql>create table news_table (id integer not null auto_increment, title varchar(255), content varchar(255), primary key (id));
编辑器它报错的时候还顺便把错误的sql语句给出来了,我看那个句子大部分是正确的,就直接把正确的部分复制粘贴创建了数据库,是可以正常创建的。
问题记录如下:
Jan 7, 2014 10:17:13 AM org.hibernate.tool.hbm2ddl.SchemaExport create
SEVERE: Unsuccessful: create table news_table (id integer not null auto_increment, title varchar(255), content varchar(255), primary key (id)) type=InnoDB
Jan 7, 2014 10:17:13 AM org.hibernate.tool.hbm2ddl.SchemaExport create
SEVERE: 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 'type=InnoDB' at line 1
Jan 7, 2014 10:17:13 AM org.hibernate.tool.hbm2ddl.SchemaExport execute
可见,具体的问题就出现在粗体字那部分。这个我们没办法改的,因为这个是由hibernate底层自行通过脚本实现的。那怎么办?既然问题出在自动创建数据库,那就找到自动创建数据库的配置内容:
去网上找了下关于属性"hbm2ddl.auto"的配置(当然也可以找hibernate自带的帮助文档,不过直觉觉得直接搜索更快),列出重点内容如下。
它一般有四个属性:
create : 会根据你的model类来生成表,但是每次运行都会删除上一次的表,重新生成表,哪怕2次没有任何改变
create-drop : 根据model类生成表,但是sessionFactory一关闭,表就自动删除
update : 最常用的属性,也根据model类生成表,即使表结构改变了,表中的行仍然存在,不会删除以前的行
validate : 只会和数据库中的表进行比较,不会创建新表,但是会插入新值
所以,因为hibernate它自己生成的脚本有错误,加上"hbm2ddl.auto"属性设置成了create,那么每次运行的时候先把表删除了,问题是hibernate的create表达式又是有错误的,所以每次测试都报错hibernate.news_table表不存在!实际上不是不存在,是被它反复删除。
因此,把里面的属性值改成validate,然后我们自行在数据库中创建对应的数据库和表即可,上面已经给出语法了。
更改完成后,我们再一次执行主类,成功运行后,看看控制台输出了什么信息。学习一个框架,我们不仅要知道怎么用,还要知道它具体是怎么运作的,底层是怎么实现的,对于做应用来说,可能我们不需要去实现底层的东西(效率差),但是知道这些东西对自己肯定是有利无害的,它会让你对这些框架理解得更深刻,运用也更自如。
最后给出控制台的输出信息(当然,这个是成功运行的):
/****************************************************************
第一,读取jar类包
Jan 7, 2014 10:22:32 AM org.hibernate.cfg.Environment <clinit>
INFO: Hibernate 3.2.6
Jan 7, 2014 10:22:32 AM org.hibernate.cfg.Environment <clinit>
INFO: hibernate.properties not found
Jan 7, 2014 10:22:32 AM org.hibernate.cfg.Environment buildBytecodeProvider
INFO: Bytecode provider name : cglib
Jan 7, 2014 10:22:32 AM org.hibernate.cfg.Environment <clinit>
INFO: using JDK 1.4 java.sql.Timestamp handling
*****************************************************************/ /*******************************************************************
第二,1、在第一步中没有找到properties文件,这个时候自动查找hibernate.cfg.xml配置文件
2、将News.hbm.xml映射进来。然后,映射lee.News类和news_table表,这个时候还没有连接数据库,只是做简单的名字映射。
3、加载数据库驱动,连接数据库;
Jan 7, 2014 10:22:32 AM org.hibernate.cfg.Configuration configure
INFO: configuring from resource: /hibernate.cfg.xml
Jan 7, 2014 10:22:32 AM org.hibernate.cfg.Configuration getConfigurationInputStream
INFO: Configuration resource: /hibernate.cfg.xml
Jan 7, 2014 10:22:32 AM org.hibernate.cfg.Configuration addResource
INFO: Reading mappings from resource : News.hbm.xml
Jan 7, 2014 10:22:32 AM org.hibernate.cfg.HbmBinder bindRootPersistentClassCommonValues
INFO: Mapping class: lee.News -> news_table
Jan 7, 2014 10:22:32 AM org.hibernate.cfg.Configuration doConfigure
INFO: Configured SessionFactory: null
Jan 7, 2014 10:22:32 AM org.hibernate.connection.C3P0ConnectionProvider configure
INFO: C3P0 using driver: com.mysql.jdbc.Driver at URL: jdbc:mysql://localhost/hibernate
Jan 7, 2014 10:22:32 AM org.hibernate.connection.C3P0ConnectionProvider configure
INFO: Connection properties: {user=nero, password=****}
Jan 7, 2014 10:22:32 AM org.hibernate.connection.C3P0ConnectionProvider configure
INFO: autocommit mode: false
*********************************************************************/ /***往下我们可以看到,其实大部分工作都是由SessionFactory工厂类来完成****/
/***而最后三行,则由hbm2ddl.TableMetadata类进行操作,检测到数据库存在以后,对数据进行写入操作***/
Jan , :: AM com.mchange.v2.log.MLog <clinit>
INFO: MLog clients using java 1.4+ standard logging.
Jan , :: AM com.mchange.v2.c3p0.C3P0Registry banner
INFO: Initializing c3p0-0.9. [built -January- ::; debug? true; trace: ]
Jan , :: AM com.mchange.v2.c3p0.impl.AbstractPoolBackedDataSource getPoolManager
INFO: Initializing c3p0 pool... com.mchange.v2.c3p0.PoolBackedDataSource@945bcac [ connectionPoolDataSource -> com.mchange.v2.c3p0.WrapperConnectionPoolDataSource@d9eed013 [ acquireIncrement -> , acquireRetryAttempts -> , acquireRetryDelay -> , autoCommitOnClose -> false, automaticTestTable -> null, breakAfterAcquireFailure -> false, checkoutTimeout -> , connectionCustomizerClassName -> null, connectionTesterClassName -> com.mchange.v2.c3p0.impl.DefaultConnectionTester, debugUnreturnedConnectionStackTraces -> false, factoryClassLocation -> null, forceIgnoreUnresolvedTransactions -> false, identityToken -> z8kfsx8ztjvt8c8eui08|a98932, idleConnectionTestPeriod -> , initialPoolSize -> , maxAdministrativeTaskTime -> , maxConnectionAge -> , maxIdleTime -> , maxIdleTimeExcessConnections -> , maxPoolSize -> , maxStatements -> , maxStatementsPerConnection -> , minPoolSize -> , nestedDataSource -> com.mchange.v2.c3p0.DriverManagerDataSource@60480c6 [ description -> null, driverClass -> null, factoryClassLocation -> null, identityToken -> z8kfsx8ztjvt8c8eui08|1d1e730, jdbcUrl -> jdbc:mysql://localhost/hibernate, properties -> {user=******, password=******} ], preferredTestQuery -> null, propertyCycle -> 0, testConnectionOnCheckin -> false, testConnectionOnCheckout -> false, unreturnedConnectionTimeout -> 0, usesTraditionalReflectiveProxies -> false; userOverrides: {} ], dataSourceName -> null, factoryClassLocation -> null, identityToken -> z8kfsx8ztjvt8c8eui08|1b4a74b, numHelperThreads -> 3 ]
Jan , :: AM org.hibernate.cfg.SettingsFactory buildSettings
INFO: RDBMS: MySQL, version: 5.5.-0ubuntu0.12.04.
Jan , :: AM org.hibernate.cfg.SettingsFactory buildSettings
INFO: JDBC driver: MySQL-AB JDBC Driver, version: mysql-connector-java-5.1. ( Revision: ${svn.Revision} )
Jan , :: AM org.hibernate.dialect.Dialect <init>
INFO: Using dialect: org.hibernate.dialect.MySQLInnoDBDialect
Jan , :: AM org.hibernate.transaction.TransactionFactoryFactory buildTransactionFactory
INFO: Using default transaction strategy (direct JDBC transactions)
Jan , :: AM org.hibernate.transaction.TransactionManagerLookupFactory getTransactionManagerLookup
INFO: No TransactionManagerLookup configured (in JTA environment, use of read-write or transactional second-level cache is not recommended)
Jan , :: AM org.hibernate.cfg.SettingsFactory buildSettings
INFO: Automatic flush during beforeCompletion(): disabled
Jan , :: AM org.hibernate.cfg.SettingsFactory buildSettings
INFO: Automatic session close at end of transaction: disabled
Jan , :: AM org.hibernate.cfg.SettingsFactory buildSettings
INFO: JDBC batch size:
Jan , :: AM org.hibernate.cfg.SettingsFactory buildSettings
INFO: JDBC batch updates for versioned data: disabled
Jan , :: AM org.hibernate.cfg.SettingsFactory buildSettings
INFO: Scrollable result sets: enabled
Jan , :: AM org.hibernate.cfg.SettingsFactory buildSettings
INFO: JDBC3 getGeneratedKeys(): enabled
Jan , :: AM org.hibernate.cfg.SettingsFactory buildSettings
INFO: Connection release mode: auto
Jan , :: AM org.hibernate.cfg.SettingsFactory buildSettings
INFO: Maximum outer join fetch depth:
Jan , :: AM org.hibernate.cfg.SettingsFactory buildSettings
INFO: Default batch fetch size:
Jan , :: AM org.hibernate.cfg.SettingsFactory buildSettings
INFO: Generate SQL with comments: disabled
Jan , :: AM org.hibernate.cfg.SettingsFactory buildSettings
INFO: Order SQL updates by primary key: disabled
Jan , :: AM org.hibernate.cfg.SettingsFactory buildSettings
INFO: Order SQL inserts for batching: disabled
Jan , :: AM org.hibernate.cfg.SettingsFactory createQueryTranslatorFactory
INFO: Query translator: org.hibernate.hql.ast.ASTQueryTranslatorFactory
Jan , :: AM org.hibernate.hql.ast.ASTQueryTranslatorFactory <init>
INFO: Using ASTQueryTranslatorFactory
Jan , :: AM org.hibernate.cfg.SettingsFactory buildSettings
INFO: Query language substitutions: {}
Jan , :: AM org.hibernate.cfg.SettingsFactory buildSettings
INFO: JPA-QL strict compliance: disabled
Jan , :: AM org.hibernate.cfg.SettingsFactory buildSettings
INFO: Second-level cache: enabled
Jan , :: AM org.hibernate.cfg.SettingsFactory buildSettings
INFO: Query cache: disabled
Jan , :: AM org.hibernate.cfg.SettingsFactory createCacheProvider
INFO: Cache provider: org.hibernate.cache.NoCacheProvider
Jan , :: AM org.hibernate.cfg.SettingsFactory buildSettings
INFO: Optimize cache for minimal puts: disabled
Jan , :: AM org.hibernate.cfg.SettingsFactory buildSettings
INFO: Structured second-level cache entries: disabled
Jan , :: AM org.hibernate.cfg.SettingsFactory buildSettings
INFO: Statistics: disabled
Jan , :: AM org.hibernate.cfg.SettingsFactory buildSettings
INFO: Deleted entity synthetic identifier rollback: disabled
Jan , :: AM org.hibernate.cfg.SettingsFactory buildSettings
INFO: Default entity-mode: pojo
Jan , :: AM org.hibernate.cfg.SettingsFactory buildSettings
INFO: Named query checking : enabled
Jan , :: AM org.hibernate.impl.SessionFactoryImpl <init>
INFO: building session factory
Jan , :: AM org.hibernate.impl.SessionFactoryObjectFactory addInstance
INFO: Not binding factory to JNDI, no JNDI name configured
Jan , :: AM org.hibernate.tool.hbm2ddl.SchemaValidator validate
INFO: Running schema validator
Jan , :: AM org.hibernate.tool.hbm2ddl.SchemaValidator validate
INFO: fetching database metadata
Jan , :: AM org.hibernate.tool.hbm2ddl.TableMetadata <init>
INFO: table found: hibernate.news_table
Jan , :: AM org.hibernate.tool.hbm2ddl.TableMetadata <init>
INFO: columns: [content, id, title]
那我们如果操作的是有复合主键的数据库(两个或多个数据库关联)怎么办?分析上面的问题,这个是hibernate它自己提供的jar类包里面的实现出现了错误,所以你可以更换为新版本的类包试试,另一种方法就自行去设计两个(或多个)数据库的关联关系,当然这种方式是比较原始的。
没有所谓的哪种更好,看具体情况而定。
hibernate基础学习笔记暂时就是这些。实际上在企业应用中似乎jpa应用得更多,因为管理一个文件就可以了。
jpa = POJO + @Annotation
有时间会写一写。
J2EE--Hibernate基础笔记的更多相关文章
- Hibernate学习笔记2.1(Hibernate基础配置)
Hibernate基础配置 1.<property name="hbm2ddl.auto">update</property> 在SessionFactor ...
- hibernate学习笔记(1)基础配置与jar包
下载hibernate基础jar包,并解压hibernate-core-4.2.4.final 在myeclipse中添加hibernate的dtd支持: location为D:\学习\imooc-h ...
- Hibernate学习笔记(一)
2016/4/18 19:58:58 Hibernate学习笔记(一) 1.Hibernate框架的概述: 就是一个持久层的ORM框架. ORM:对象关系映射.将Java中实体对象与关系型数据库中表建 ...
- Hibernate学习笔记
一.Hibernate基础 1.Hibernate简介 Hibernate是一种对象关系映射(ORM)框架,是实现持久化存储的一种解决方案.Java包括Java类到数据库表的映射和数据查询及获取的方法 ...
- Hibernate学习笔记-Hibernate HQL查询
Session是持久层操作的基础,相当于JDBC中的Connection,通过Session会话来保存.更新.查找数据.session是Hibernate运作的中心,对象的生命周期.事务的管理.数据库 ...
- hibernate基础dao类
此文章是基于 搭建SpringMVC+Spring+Hibernate平台 功能:数据库的保存.更新.删除:sql.hql查询:分页查询:调用存储过程 创建hibernate基础dao类: BaseD ...
- hibernate关联关系笔记
Hibernate关联关系笔记 单向N:1 * 有连接表:在N方使用<join>/<many-to-one>.1方无需配置与之关联的持久化类. * 没有连接表:在N方使用& ...
- Hibernate学习笔记(二)
2016/4/22 23:19:44 Hibernate学习笔记(二) 1.1 Hibernate的持久化类状态 1.1.1 Hibernate的持久化类状态 持久化:就是一个实体类与数据库表建立了映 ...
- Hibernate 学习笔记一
Hibernate 学习笔记一 今天学习了hibernate的一点入门知识,主要是配置domain对象和表的关系映射,hibernate的一些常用的配置,以及对应的一个向数据库插入数据的小例子.期间碰 ...
随机推荐
- 第10步:DBCA创建实例
注意,创建磁盘组时需要以oracle用户身份执行,在那之前可能需要以root身份执行xhost+,即命令: 代码1 [root@sgdb1~]# xhost+ [root@sgdb1~]# su - ...
- 修改了JS代码,刷新网页后,加载的JS还是原来旧的?
本地修改JS脚本后,刷新网页看一下修改后的执行效果,结果调试显示加载的JS还是原来旧的,反复刷新均无效,郁闷! 解决办法:清理一下浏览器缓存(长经验了!) Ctrl+Shift+Del 清除G ...
- DIV高度设置全屏
<div class="full"></div> .full{ height:100%; position:fixed; } 使用position的fixe ...
- Duilib教程-非DUI控件
DUILIB并不是真正的DUI,至少有部分控件不是完全DUI的.其实包括: 1.EDIT. 它的实现原理是,CEditUI包含一个窗口CEditWnd,流程如下: 1)鼠标单击,创建窗口见 EditU ...
- linux的%用法
转自:http://blog.csdn.net/wu020708/article/details/52387473 linux (%和%%)(#和##)贪婪匹配规则 先看一个案例,提取文件名: fil ...
- mac下面安装多个JDK
JDK8 GA之后,小伙伴们喜大普奔,纷纷跃跃欲试,想体验一下Java8的Lambda等新特性,可是目前Java企业级应用的主打版本还是JDK6, JDK7.因此,我需要在我的电脑上同时有JDK8,J ...
- Jupyter Notebook远程服务器配置
首先要生成密码,打开python终端. In [1]: from IPython.lib import passwd In [2]: passwd() Enter password: Verify p ...
- mysql 获取id最大值
数据库表中id列不为自动增加,需要程序来增加id的SQL SELECTCASE IFNULL(MAX(id),1)WHEN 1 THEN 1ELSE MAX(id) + 1END AS newmaxi ...
- 7.javascript如何调试代码
http://www.cnblogs.com/youring2/archive/2012/08/08/2624093.html
- Java 语言基础之数组常见操作
对数组操作最基本的动作: 存和取 核心思想: 就是对角标的操作 数组常见操作: 1, 遍历 2, 获取最大值和最小值 3, 排序 4, 查找 5, 折半查找 // 1. 遍历 int[] arr = ...