dljd_(011-020)_hibernate中配置文件详解
一、新建java项目、导入所需jar包
二、新建实体类及实体类到数据库表的映射关系
2.1新建实体类(Student)
package edu.aeon.beans; /** * [说明]:学生实体(bean)类 * @author aeon * */ public class Student { /**用户id*/ private Integer stuId; /**用户名*/ private String stuName; /**用户年龄*/ private int stuAge; /**用户分数*/ private double stuScore; /**空构造器*/ public Student() { super(); } /**带惨构造、没有stuId是因为最后这个用户id我们自动生成*/ public Student(String stuName, int stuAge, double stuScore) { super(); this.stuName = stuName; this.stuAge = stuAge; this.stuScore = stuScore; } /**setter/getter*/ public Integer getStuId() { return stuId; } public void setStuId(Integer stuId) { this.stuId = stuId; } public String getStuName() { return stuName; } public void setStuName(String stuName) { this.stuName = stuName; } public int getStuAge() { return stuAge; } public void setStuAge(int stuAge) { this.stuAge = stuAge; } public double getStuScore() { return stuScore; } public void setStuScore(double stuScore) { this.stuScore = stuScore; } /**重写toString方法*/ @Override public String toString() { return "Student [stuId=" + stuId + ", stuName=" + stuName + ", stuAge=" + stuAge + ", stuScore=" + stuScore + "]"; } }
2.2配置实体类Student到数据库t_student的映射关系
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <hibernate-mapping package="edu.aeon.beans"> <!-- 1.配置实体类(Student)到数据库表(t_student)的关系 --> <class name="Student" table="t_student"> <!-- 2.配置实体类属性到数据库表字段的关系 --> <!-- 实体类属性stuId和数据库表字段的映射关系 --> <id name="stuId"> <!-- 实体类属性stuId映射到数据库字段t_stuid sql-type:指定该字段在数据库中的类型 --> <column name="t_stuid" sql-type="int(3)"/> <!-- 主键生成策略:native:自动增长 --> <generator class="native" /> </id> <!-- 实体类属性stuName和数据库表字段的映射关系 --> <property name="stuName"> <!-- 实体类属性stuName映射到数据库字段t_stuname length指定该字段在数据库字段的长度--> <column name="t_stuname" sql-type="varchar(16)" /> </property> <!-- 实体类属性stuAge和数据库表字段的映射关系 --> <property name="stuAge"> <column name="t_stuage" sql-type="int(3)"/> </property> <!-- 实体类属性stuScore和数据库表字段的映射关系 --> <property name="stuScore"> <column name="t_stuscore" sql-type="double(6,2)" /> </property> </class> </hibernate-mapping>
三、配置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工厂 --> <session-factory> <!-- 1.配置连接数据库要素(驱动、用户名、用户密码数据库方言、数据库连接池、自动生成表、注册当前session上下文、输出/格式化sql...) --> <property name="hibernate.connection.driver">com.mysql.jdbc.Driver</property> <property name="hibernate.connection.url">jdbc:mysql:///db_test</property> <property name="hibernate.connection.username">root</property> <property name="hibernate.connection.password">root</property> <property name="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</property> <property name="hibernate.connection.provider_class">org.hibernate.c3p0.internal.C3P0ConnectionProvider</property> <property name="hibernate.hbm2ddl.auto">true</property> <property name="hibernate.current_session_context_class">thread</property> <property name="hibernate.show_sql">true</property> <property name="hibernate.format_sql">true</property>
<!-- 2.注册映射文件 --> <mapping resource="edu/aeon/beans/Student.hbm.xml"/> </session-factory> </hibernate-configuration>
hibernate.cfg.xml配置
1、配置db连接四要素
2、配置数据库方言
3、配置数据源c3p0:数据库连接池
4、注册当前session上下文:目的为了保证同一个线程中取到的session是同一个session
5、配置自动建表
6、配置显示sql
7、配置格式化sql
8、注册映射文件
四、编写测试类
package edu.aeon.hibernate.test; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.Transaction; import org.hibernate.boot.MetadataSources; import org.hibernate.boot.registry.StandardServiceRegistryBuilder; import org.hibernate.boot.spi.MetadataImplementor; import org.hibernate.cfg.Configuration; import org.hibernate.service.ServiceRegistry; import org.hibernate.tool.hbm2ddl.SchemaExport; import edu.aeon.beans.Student; /** * [说明]:测试hibernate根据配置文件所配置的信息创建表及数据的保存 * @author aeon * */ public class Test { /** * 测试创建表 */ public static void testCreateTable() { ServiceRegistry serviceRegistry = (ServiceRegistry) new StandardServiceRegistryBuilder().configure().build(); MetadataImplementor metadataImplementor = (MetadataImplementor) new MetadataSources(serviceRegistry).buildMetadata(); SchemaExport export = new SchemaExport(serviceRegistry, metadataImplementor); /**第一个boolean参数代表:否覆盖原有的数据库 第二个boolean参数代表:是否新建数据库*/ export.create(true, true); } /** * 保存学生对象 */ public static void testSaveStudent() { Configuration configuration=new Configuration().configure(); SessionFactory sessionFactory=configuration.buildSessionFactory(); Transaction transaction=null; Session session = sessionFactory.getCurrentSession(); try { transaction=session.beginTransaction(); Student student = new Student("zhangsan", 23, 99.8); session.save(student); transaction.commit(); } catch (Exception e) { if(null!=transaction){ transaction.rollback(); } } } public static void main(String[] args) { testCreateTable(); testSaveStudent(); } }
测试结果:
数据库信息截图:
五、重点总结
SessionFactory是重量级对象(系统开销大)、单例的、线程安全的。
按理说、单例对象一定是被共享的,线程不安全的。但查看SessionFactory接口的实现类SessionFactoryImpl源码,可以看其大多数成员变量是final的,所以其是线程安全的。
sessionFacoty对象的使用原则:基于其是线程安全的重量级对象,其创建与销毁时系统开销大,又是单例的特点,sessionFactory对象一般不手工关闭,而是在应用结束时自动将其销毁。因此,sessionFactory不用进行close()关闭。
session对象的特点:session是一个轻量级对象,线程不安全的、多例的。
在web应用中,多个用户对同一应用访问,hibernate会为每个用户创建一个session对象。所以是多利的。Session中包含大量非final成员变量,对于同一个用户的操作,可能会产生多个事务,这多个事务若同时对同一个session的同一个成员变量进行访问,就会引起并发问题,所以session是线程不安全的。
session对象的使用原则:基于session有以上特点,session在使用时要做到一个线程一个session,即一个事务一个session.使用完毕立即关闭。session不要作为某个类的成员变量出现,因为这样会出现多个实例对象对同一个session的共享,使其更不安全。
用getCurrentSession()获取到的session我们无需用手动去关闭、应为在提交或者回滚事务时已经做了销毁session操作!getCurrentSession在同一个线程中是同一个session。而用openSession()获取到的session我们必须用手动关闭、且每次掉用该方法会创建一个新的session。