有一段时间没用Hibernate了,今天练习Maven的时候用到Hibernate操作数据库,结果很无语。
好多东西都忘了。。。
首先,编写POM.xml,引入Hibernate所需的jar包
只需要制定hibernate-core,Maven就会自动下载hibernate-core.jar,以及hibernate需要的其它jar包
如果没有自动下载其它依赖包,在进行对象保存时,会报错,根据提示再引入对应的jar包即可!
POM.xml
此处引入了junit, hibernate-core, mysql-connector, log4j
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.gc.user</groupId> <artifactId>user-core</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>user-core</name> <url>http://maven.apache.org</url> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.10</version> <scope>test</scope> </dependency> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-core</artifactId> <version>4.2.6.Final</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.26</version> </dependency> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.16</version> </dependency> </dependencies> </project>
使用注解配置了一个实体类User
package com.gc.user.core; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.Table; @Entity @Table(name="t_user") public class User { @Id @GeneratedValue private int id; private String name; private int age; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } }
Hibernate的配置文件时直接从以前的项目中拷贝过来的,由于以前是通过写hbm.xml来配置的
现在是通过注解来配置的,结果就犯迷糊了
出现的问题是:
org.hibernate.MappingException: Unknown entity: com.gc.user.core.User
找不到实体类!
由于SSH项目中,都通过Spring自动对Annotation进行扫描,现在离开了Spring,就犯傻了。
忘了没有Spring时,使用Hibernate需要手动指定实体类的位置!哎。。。
在配置文件中加入User的类路径就OK了
【注意:还有一种可能也会找出Unknown entity,那就是引入Entity包的时候弄错了】
【如果没有使用Spring的包自动扫描,记得要在hibernate的配置文件加入映射<mapping>!】
以下是Hibernate的配置文件,hibernate.cfg.xml
<!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="hibernate.connection.url">jdbc:mysql://localhost/maven</property> <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property> <property name="hibernate.connection.username">root</property> <property name="hibernate.connection.password">root</property> <property name="dialect">org.hibernate.dialect.MySQLDialect</property> <property name="show_sql">true</property> <property name="hibernate.hbm2ddl.auto">update</property> <!--如果使用的是本地事务(jdbc事务) ,此配置将不需要再close session了; getCurrentSession创建的session会和绑定到当前线程,而openSession不会; getCurrentSession创建的线程会在事务回滚或事物提交后自动关闭,而openSession必须手动关闭; --> <property name="current_session_context_class">thread</property> <!-- 如果使用的是全局事务(jta事务) --> <!-- <property name="hibernate.current_session_context_class">jta</property> --> <!-- 指定实体的具体路径,否则hibernate找不到 --> <mapping class="com.gc.user.core.User"/> </session-factory> </hibernate-configuration>
Log4j配置文件
日志信息将保存在项目根目录下的logs目录下,一个记录所有的控制台输出,一个只记录error级别的错误信息
log4j.rootLogger = debug , stdout , A , B log4j.appender.stdout = org.apache.log4j.ConsoleAppender log4j.appender.stdout.Target = System.out log4j.appender.stdout.layout = org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern = %d{ABSOLUTE} %5p :%L - %m%n log4j.appender.A = org.apache.log4j.DailyRollingFileAppender log4j.appender.A.File = logs/log.log log4j.appender.A.Append = true log4j.appender.A.Threshold = DEBUG log4j.appender.A.layout = org.apache.log4j.PatternLayout log4j.appender.A.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [ %p ] %m%n log4j.appender.B = org.apache.log4j.DailyRollingFileAppender log4j.appender.B.File = logs/error.log log4j.appender.B.Append = true log4j.appender.B.Threshold = ERROR log4j.appender.B.layout = org.apache.log4j.PatternLayout log4j.appender.B.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [ %p ] %m%n
以下是测试类
package com.gc.user.core; import junit.framework.TestCase; import org.apache.log4j.Logger; import org.hibernate.Session; import org.junit.Test; import com.gc.util.HibernateUtil; /** * Unit test for simple App. */ public class AppTest extends TestCase { @Test public void testHibernate() { System.out.println("begin..."); User user = new User(); user.setName("lisi"); user.setAge(10); Session session = HibernateUtil.getSession(); try { session.beginTransaction(); session.save(user); assertNotNull(user.getId()); System.out.println("userId="+user.getId()); session.getTransaction().commit(); } catch(Exception e) { e.printStackTrace(); session.getTransaction().rollback(); } //这里不需要手动关闭session了! //因为hibernate配置文件中有这样一个配置:<property name="current_session_context_class">thread</property> } @Test public void testLog4j() { try { System.out.println(1/0); }catch(Exception e) { Logger logger = Logger.getLogger(this.getClass()); logger.error("testLog4j error", e); } } }
简单的Hibernate工具类,没有怎么封装,就返回一个与当前线程绑定的Session
package com.gc.util; import java.util.Map; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.cfg.AnnotationConfiguration; import org.hibernate.cfg.Configuration; import org.hibernate.service.ServiceRegistry; import org.hibernate.service.ServiceRegistryBuilder; public class HibernateUtil { private static SessionFactory factory; private static ServiceRegistry serviceRegistry; static{ Configuration cfg = new Configuration().configure(); Map map = cfg.getProperties(); for(Object key : map.keySet()) { //可以打印出很多系统属性! //System.out.println(key); //System.out.println(map.get(key)); } serviceRegistry = new ServiceRegistryBuilder().applySettings(cfg.getProperties()).buildServiceRegistry(); factory = cfg.buildSessionFactory(serviceRegistry); } public static Session getSession() { return factory.getCurrentSession(); } }