按照視頻教程上教的,寫個代碼,結果一直報hibernate mapping exception的錯誤,查找各種資料配置,沒有解決。最終發現,還是在sesstionfactory中,增加addClass(User.class);或者直接使用configuration.configure().buildSessionFactory();解決的。
容易錯的地方,都標紅加粗了。
hibernate版本:5.1.0. final。 jdk 1.8,myeclipse 2016 ci。
目錄結構
一、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">
<!-- Generated by MyEclipse Hibernate Tools. -->
<hibernate-configuration>
<session-factory>
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="connection.password">a</property>
<property name="connection.username">a</property>
<property name="connection.url">jdbc:mysql://localhost:3306/myhib</property>
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="myeclipse.connection.profile">mysql</property>
<property name="hibernate.show_sql">true</property>
<property name="hibernate.hbm2ddl.auto">update</property>
<mapping resource="com/model/User.hbm.xml" />
</session-factory>
</hibernate-configuration>
二、user.hbm.xml (hibernate映射文件的配置)
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.model.User" table="t_login">
<id name="id" type="int">
<column name="Id"/>
<generator class="native"/>
</id>
<property name="username" type="string" column="username"></property>
<property name="userpass" type="string" column="userpass"></property>
</class>
</hibernate-mapping>
三、HibernateSessionFactory的代碼 (封裝好的hiber操作)
package com.model;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;
public class HibernateSessionFactory {
private static String CONFIG_FILE_LOCATION = "/hibernate.cfg.xml";
private static final ThreadLocal<Session> sessionThreadLocal = new ThreadLocal<Session>();//創建一個ThreadLocal<Session>對象用來存放當前Session對象
private static org.hibernate.cfg.Configuration configuration = new Configuration();
private static SessionFactory sessionFactory;
private static String configFile = CONFIG_FILE_LOCATION;
static
{
try{
configuration.configure();//讀取並解析hibernate.cfg.xml文件
//1.第一種方法
sessionFactory=configuration.configure().buildSessionFactory();
//2.第二種方法
//configuration.addClass(User.class);
//在Hibernate4.x後會使用註冊機來解析映射信息,所以會先創建ServiceRegistry對象
//org.hibernate.service.ServiceRegistry svcreg=new org.hibernate.boot.registry.StandardServiceRegistryBuilder().applySettings(configuration.getProperties()).build();
//ServiceRegister對象作爲參數,使用configuration對象創建sessionFactory對象,即將configuration對象裏的信息copy到sessionFactory緩存中
//sessionFactory = configuration.buildSessionFactory(svcreg);
}catch(Exception e){
e.printStackTrace();
}
}
//聲明一個私有無參構造函數
private HibernateSessionFactory(){}
public static SessionFactory getSessionFactory(){
return sessionFactory;
}
public static void rebuildSessionFactory(){
synchronized(sessionFactory){
try{
configuration.configure(configFile);
//configuration.addClass(User.class);
ServiceRegistry svcreg = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties()).build();
sessionFactory = configuration.buildSessionFactory(svcreg);
//sessionFactory=configuration.configure().buildSessionFactory();
}catch(Exception e){
e.printStackTrace();
}
}
}
//打開session
public static Session getSession(){
//獲取當前線程的session對象
Session session = sessionThreadLocal.get();
try{
if(session == null || !session.isOpen()){
if(sessionFactory == null){//如果sessionFactory爲null,創建一個
rebuildSessionFactory();
}
//如果session沒有打開,就用sessionFactory打開
session = (sessionFactory!=null)?sessionFactory.openSession():null;
//將session對象放到ThreadLocal對象裏,以便使用
sessionThreadLocal.set(session);
}
}catch(Exception e){
e.printStackTrace();
}
return session;
}
public static void closeSession(){
Session session = sessionThreadLocal.get();
sessionThreadLocal.set(null);
try{
if(session != null && session.isOpen()){
session.close();
}
}catch(Exception e){
e.printStackTrace();
}
}
public static void setConfigFile(String configFile){
HibernateSessionFactory.configFile = configFile;
sessionFactory = null;
}
public static Configuration getConfiguration(){
return configuration;
}
}
另外,爲項目添加hibernate能力的時候,會自動創建sessionfactory的代碼,可參考。
下面是後來又一次參照視頻,調用hibernate,插入數據庫,實驗成功的代碼。hibernate也是用的5.1版本,myeclipse 2016。
public class UserTest {
public static void main(String[] args) {
Configuration cfg=new Configuration();
cfg.configure("/hibernate.cfg.xml"); //不要的話,會報錯 'hibernate.dialect' not set
ServiceRegistry svr=new StandardServiceRegistryBuilder().applySettings(cfg.getProperties()).build();
SessionFactory sf=cfg.buildSessionFactory();
Session ss=null;
try {
ss=sf.openSession();
ss.beginTransaction();
User user=new User();
user.setUsername("zhangsan");
user.setUserpass("000000");
user.setNickname("張三");
user.setBorn(new Date());
ss.save(user);
ss.getTransaction().commit();
} catch (HibernateException e) {
if(ss!=null) ss.getTransaction().rollback();
e.printStackTrace();
}finally {
if(ss!=null) ss.close();
}
}
}
成功結果:
Hibernate: create table t_user (id integer not null auto_increment, username varchar(255), userpass varchar(255), nickname varchar(255), born datetime, primary key (id))
Hibernate: insert into t_user (username, userpass, nickname, born) values (?, ?, ?, ?)
四、User實體類的代碼
package com.model;
import javax.persistence.Entity;
import javax.persistence.EntityListeners;
@Entity
@javax.persistence.Table(name="_User")
public class User {
private int id;
private String username;
private String userpass;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getUserpass() {
return userpass;
}
public void setUserpass(String userpass) {
this.userpass = userpass;
}
}
五、測試運行的代碼testUser.java
package com.java;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import com.model.HibernateSessionFactory;
import com.model.User;
public class testUser {
public static void main(String[] a){
try {
System.out.println("1111111111111111........................");
SessionFactory sf=null;
sf=HibernateSessionFactory.getSessionFactory();
Session ss=sf.openSession();
System.out.println("222222222222222........................");
Transaction tran=ss.beginTransaction();
User u=new User();
u.setId(1);
u.setUsername("jxq");
u.setUserpass("123456");
System.out.println("33333333333333333........................");
ss.save(u);
System.out.println("44444444444444444444........................");
tran.commit();
//
System.out.println("66666........................");
ss.close();
sf.close();
} catch (HibernateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("asdfad");
}
}
六、運行成功的結果
1111111111111111........................
三月 04, 2019 11:25:20 上午 org.hibernate.Version logVersion
INFO: HHH000412: Hibernate Core {5.1.0.Final}
三月 04, 2019 11:25:20 上午 org.hibernate.cfg.Environment <clinit>
INFO: HHH000206: hibernate.properties not found
三月 04, 2019 11:25:20 上午 org.hibernate.cfg.Environment buildBytecodeProvider
INFO: HHH000021: Bytecode provider name : javassist
三月 04, 2019 11:25:20 上午 org.hibernate.annotations.common.reflection.java.JavaReflectionManager <clinit>
INFO: HCANN000001: Hibernate Commons Annotations {5.0.1.Final}
三月 04, 2019 11:25:20 上午 org.hibernate.boot.jaxb.internal.stax.LocalXmlResourceResolver resolveEntity
WARN: HHH90000012: Recognized obsolete hibernate namespace http://hibernate.sourceforge.net/hibernate-mapping. Use namespace http://www.hibernate.org/dtd/hibernate-mapping instead. Support for obsolete DTD/XSD namespaces may be removed at any time.
三月 04, 2019 11:25:20 上午 org.hibernate.boot.jaxb.internal.stax.LocalXmlResourceResolver resolveEntity
WARN: HHH90000012: Recognized obsolete hibernate namespace http://hibernate.sourceforge.net/hibernate-mapping. Use namespace http://www.hibernate.org/dtd/hibernate-mapping instead. Support for obsolete DTD/XSD namespaces may be removed at any time.
三月 04, 2019 11:25:20 上午 org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl configure
WARN: HHH10001002: Using Hibernate built-in connection pool (not for production use!)
三月 04, 2019 11:25:20 上午 org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator
INFO: HHH10001005: using driver [com.mysql.jdbc.Driver] at URL [jdbc:mysql://localhost:3306/myhib]
三月 04, 2019 11:25:20 上午 org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator
INFO: HHH10001001: Connection properties: {user=a, password=****}
三月 04, 2019 11:25:20 上午 org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator
INFO: HHH10001003: Autocommit mode: false
三月 04, 2019 11:25:20 上午 org.hibernate.engine.jdbc.connections.internal.PooledConnections <init>
INFO: HHH000115: Hibernate connection pool size: 20 (min=1)
三月 04, 2019 11:25:21 上午 org.hibernate.dialect.Dialect <init>
INFO: HHH000400: Using dialect: org.hibernate.dialect.MySQLDialect
三月 04, 2019 11:25:21 上午 org.hibernate.validator.internal.util.Version <clinit>
INFO: HV000001: Hibernate Validator 5.2.4.Final
222222222222222........................
33333333333333333........................
Hibernate: insert into t_login (username, userpass) values (?, ?)
44444444444444444444........................
66666........................
三月 04, 2019 11:25:21 上午 org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl stop
INFO: HHH10001008: Cleaning up connection pool [jdbc:mysql://localhost:3306/myhib]
asdfad