一、hibernate的相关介绍
Hibernate是一个轻量级的ORMapping框架,对JDBC进行了轻量级的封装,他能够自动根据我们的需求,能够将我们的实体类映射到数据库表中而进行存储。说到此处先来讲一下JPA(Java persistence API),是JavaEE5
标准的ORM接口 标准,是一种规范和接口,并不是ORM的具体实现,用于实现这一套规范的框架有很多,其
中Hibernate就是一个这样的框架。
ORMapping原理(Object Relational Mapping)
ORMapping基本对应规则:
1.类跟表对应
2.类的属性跟表的字段相对应
3.类的实例与表中具体的一条记录相对应
4.一个类可以对应多个表,一个表也可以对应多个类
5.DB中的表可以没有主键,但是object中必须设置主键字段
6.DB中表与表之间的关系(如外键)映射成为object之间的关系
7.Obejct中属性的个数和名称可以和表中定义的字段个数和名称不一样。
ORMapping的基本实现方式:
使用JDBC,用sql来操作数据库,只是看动态生成还是人工代码来实现
二
二、hibernate的作用
hibernate主要用来实现java对象和表之间的映射,除此之外还提供数据查询和获取数据的方法,可以大幅度减少
开发时人工使用sql和jdbc处理数据的时间。hibernate的目标是对于开发者通常的数据持久化相关的编程任务,解
放其中的95%。对于以数据为中心的程序来说,它们往往只在数据库中使用存储过程来实现商业逻辑,Hibernate可能
不是最好的解决方案;对于那些在基于Java的中间层应用中,它们实现面向对象的业务模型和商业逻辑的应用,Hib
ernate是最有用的。
Hibernate可以帮助你消除或者包装那些针对特定厂商的SQL代码,并且帮你把结果集从表格式的表示形式转换到一
系列的对象去。
JPA,ORM,Hibernate之间的关系:
ORM是一种思想,JPA是这种思想的规范约束,Hibernate是这种思想和规范的具体实现。
Hibernate的工作大体工作模式:
三、hibernate中的对象
SessionFactory (org.hibernate.SessionFactory)
针对单个数据库映射关系经过编译后内存镜像,是线程安全的,它是生存的工厂,本身要用到。
Session (org.hibernate.Session)
表示应用程序与持久层之间交互操作的一个单线程对象,此对象生存期很短,隐藏了连接。
Transaction (org.hibernate.Transaction)
应用程序用来指定原子操作单元范围的对象,它是单线程的,生命周期很短,他通过抽象将应用从底层具体的、以
及事务隔离开。
ConnectionProvider (org.hibernate.connection.ConnectionProvider)
生成连接的工厂(有连接池的作用)。它通过抽象将应用从底层隔离开,仅供开发者拓展/实现用,并不暴露给应用程序使用。
TransactionFactory (org.hibernate.TransactionFactory)
生成对象实例的工厂。仅供开发者扩展/实现用,并不暴露给应用程序使用。
四、hibernate的基本配置
1.下载jar包 http://hibernate.org/
第一步:选择Hibernate orm
第二步:在releases模块中进行版本的选择,一般选择稳定版本
第三步:拉到最下面,点击进行下载
第四步:解压并进入lib文件夹,选中required中所有jar包(一定要选中所有的包否则运行项目时可能会报错),optional里面c3p0所有jar包,optional的
ehcache下slf4j-api-1.6.1.jar,jpa-metamodel-generator下所有jar包,jpa下所有jar包,当然
还需要我们的数据库驱动jar包,根据我们使用的数据库自行选定。
2.配置(这里以建java project为例)
2.1 hibernate环境配置
第一步:在eclipse上安装hibernate tools插件。
Eclipse的“Help”-->"Eclipse Marketplace", 输入hibernate查找,因为Hibernate是JBoss的一种,所以安装
的是JBoss Tools,安装的时候只选择Hiberante Tools即可。
第二步:HibernateTools的安装完成!选择工程下的SRC目录,然后右键 New->Other->Hibernate->
Hibernate Configuration File(cfg.xml)。这一步只是测试有没有安装好工具,不需要创建任何东西。
五、项目(java project)
1. 创建配置 hibernate.cfg.xml(放在src目录下)
<?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>
<!--DB连接四要素 -->
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql:///hibernate_test?useUnicode=true&characterEncoding=UTF8</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">admin</property>
<!-- hibernate会根据你所指定生成sql语句,但是要指定数据库的版本 配置从core jar包里面找 -->
<property name="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</property>
<!-- 数据源(DBCP):数据库连接池 -->
<property name="hibernate.connection.provider_class">org.hibernate.c3p0.internal.C3P0ConnectionProvider</property>
<!-- 配置当前session上下文 保证同一个线程中获取的session是同一个-->
<property name="hibernate.current_session_context_class">thread</property>
<!-- 自动建表 里面的值也可以是create,但是每次都会新建一个表,影响效率,update在原有的表上面添加信息 -->
<property name="hibernate.hbm2ddl.auto">update</property> <!-- 显示sql -->
<!--显示语句 true:在控制台打印sql语句 -->
<property name="hibernate.show_sql">true</property>
<!-- 格式化sql -->
<!-- <property name="hibernate.format_sql">true</property> -->
<mapping class="com.hibernate.usermanage.entity.User"/>
<!-- 注册映射文件 -->
<mapping resource="com/hibernate/usermanage/entity/user.hbm.xml"/>
</session-factory>
</hibernate-configuration>
2 新建实体类 User.java
package com.hibernate.usermanage.entity;
public class User {
private Integer id;
private String name;
private Integer age;
public User() {
super();
}
public User(String name, Integer age) {
super();
this.name = name;
this.age = age;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "User [id=" + id + ", name=" + name + ", age=" + age + "]";
}
}
3. 创建映射文件 user.xml(放在对应实体类的同一包中)
<?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>
<!-- 作用:实体类到表的映射,属性到字段的映射-->
<class name="com.hibernate.usermanage.entity.User" table="user">
<id name="id" column="id">
<!-- 设置数据库表id增长的策略 native:生成表id值主键就是自动增长 -->
<generator class="native"/></id>
<property name="name" column="name"/>
<property name="age" column="t_age"/>
</class>
</hibernate-mapping>
4. 测试
package com.hibernate.usermanage.action;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import com.hibernate.usermanage.entity.User;
public class Test2 {
public static void main(String[] args) {
//加载配置文件
//Configuration config = new Configuration().configure("hibernate.cfg.xml");
// Configuration configuration = new Configuration().configure(); //因为使用默认的命名,所以不用指定也可以
Configuration config = new Configuration().configure("hibernate.cfg.xml");
//根据配置文件创建会话工厂
SessionFactory factory = config.buildSessionFactory();
//根据会话工厂创建会话,从工厂中取出一个session
Session session = factory.getCurrentSession();
//开启事务
Transaction t = session.beginTransaction();
User u = new User();
u.setName("石破天");
u.setAge(25);
//插入数据
session.save(u);
//提交事务
t.commit();
//关闭session会话
session.close();
//关闭工厂
factory.close();
}
}
六、ssh(spring4+struts2+hibernate3)
1 创建 web Project项目(这里不以maven构建项目)
1.1 导入jar包
尽量不要导入多余的jar包,另外导入的jar包一定要跟框架版本一致以免造成找不到相关类或者冲突。
2. 配置文件
2.1 struts2
web.xml
<!-- struts2核心过滤器 -->
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
如果struts.xml文件名自定义且位置自定义,则需要重新配置
<servlet>
<servlet-name>action</servlet-name>
<servlet-class>org.apache.struts.action.ActionServlet</servlet-class>
<!--<servlet-class>fangwei.servlet.BaseServlet</servlet-class> -->
<init-param>
<param-name>config</param-name>
<param-value><param-value>
<为了减少混淆,可以根据不同的模块功能将struts.进行某块化>
/WEB-INF/config/struts/schooldbInfo-struts-config.xml,
/WEB-INF/config/struts/classcomments-struts-config.xml,
/WEB-INF/config/struts/communicationunit-struts.config.xml
</param-value>
</init-param>
<init-param>
<param-name>debug</param-name>
<param-value>3</param-value>
</init-param>
<init-param>
<param-name>detail</param-name>
<param-value>3</param-value>
</init-param>
<init-param>
<param-name>nocache</param-name>
<param-value>yes</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
struts.xml(默认文件名,且放在src根目录下,如果另定义需要在web.xml中进行配置)
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
"http://struts.apache.org/dtds/struts-2.5.dtd">
<struts>
<!-- 告知Struts2运行时使用Spring来创建对象 -->
<constant name="struts.objectFactory" value="spring" />
<!-- 第1步:先定义一个包 -->
<package name="default" extends="struts-default" namespace="/">
<!-- 第2步:定义一个action,配置跳转信息 name 类似于Servlet @WebServlet("/IndexServlet")
http://xxxx/xxx/Index.action http://xxxx/xxx/Index class 对应于自己写的Action类 当不写method属性时,默认调用的是execute
class="ssh.action.IndexAction" ** new ssh.action.IndexAction()
设计思想:关心了具体的实现类必须改为不要关注那个实现类 加入spring后,struts的action节点的class属性意义发生变化,直接引用spring帮忙创建的实例
-->
<action name="getSelect" class="userAction" method="execute">
<!-- 跳转是forward/WEB-INF/是防止jsp不经过action就可以访问-->
<!-- result接收返回的字符串,然后做对应的事情 -->
<result name="success">/WEB-INF/jsp/index.jsp</result>
</action>
</package>
</struts>
2.2 Hibernate
hibernate.cfg.xml
<?xml version="1.0" encoding="UTF-8"?>
<!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.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql:///hibernate_test?useUnicode=true&characterEncoding=UTF8</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">admin</property>
<!-- 数据源(DBCP):数据库连接池 -->
<property name="hibernate.connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider</property>
<!-- 配置Hibernate的基本属性 -->
<!-- 1.数据源配置到IOC容器中 -->
<!-- 2.关联的.hbm.xml也在IOC容器配置SessionFactory实例 -->
<!-- 3.配置Hibernate的基本属性:方言,SQL显示及格式化,生成数据表的策略以及二级缓存 -->
<property name="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</property>
<property name="hibernate.show_sql">true</property>
<property name="hbm2ddl.auto">update</property>
<!-- 数据表映射配置文件 -->
<mapping resource="com/ssh/usermanage/entity/user.hbm.xml"/>
</session-factory>
</hibernate-configuration>
映射文件 user.hbm.xml(由于此例是以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 2018-12-21 15:56:01 by Hibernate Tools 3.5.0.Final -->
<hibernate-mapping>
<class name="com.ssh.usermanage.entity.User" table="user">
<id name="id" type="java.lang.Integer">
<column name="id" />
<generator class="assigned" />
</id>
<property name="name" type="java.lang.String">
<column name="name" />
</property>
<property name="age" type="java.lang.Integer">
<column name="t_age" />
</property>
</class>
</hibernate-mapping>
2.3 Spring
web.xml
<!-- 配置spring上下文环境 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
applicationContext.xml(文件名可以自定义)
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd"
default-lazy-init="true">
<!--数据源-->
<!-- <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="open">
<property name="driverClass" value="com.mysql.jdbc.Driver"></property>
<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/hibernate_test?useUnicode=true&characterEncoding=utf-8"></property>
<property name="user" value="root"></property>
<property name="password" value="admin"></property> -->
<!-- <property name="initialPoolSize" value="2"></property>-->
<!-- 最大空闲时间 -->
<!-- <property name="maxIdleTime" value="30"></property>-->
<!-- 最多有多少个连接 -->
<!-- <property name="maxPoolSize" value="10"></property> -->
<!-- 最少几个连接 -->
<!-- <property name="minPoolSize" value="2"></property> -->
<!-- 每次最多可以执行多少个批处理语句 -->
<!--<property name="maxStatements" value="50"></property>
</bean>-->
<!-- 添加sessionFactory bane ,注意,该类是Spring提供的 -->
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean" scope="prototype">
<!-- TransactionManager -->
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<!-- 事务 -->
<bean id="baseServiceProxy"
class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="transactionManager">
<ref bean="transactionManager" />
</property>
<property name="target">
<ref local="baseService" />
</property>
<property name="transactionAttributes">
<props>
<prop key="insert*">PROPAGATION_REQUIRED</prop>
<prop key="delete*">PROPAGATION_REQUIRED</prop>
<prop key="update*">PROPAGATION_REQUIRED</prop>
<prop key="search*">readOnly</prop>
<prop key="list*">readOnly</prop>
</props>
</property>
</bean>
<!-- 注入Hibernate 配置文件路径,前面要加上 classpath:-->
<property name="configLocation" value="classpath:hibernate.cfg.xml"/>
</bean>
<!--以下是注入信息,同样的可以根据不同的模块将注入信息进行模块化,分成多个子配置文件,其格式如
<import resource="spring/usermanage-spring.xml"/> 置于WEB-INF下的自定义的文件夹中-->
<!--将对象的创建和注入交给spring进行管理-->
<bean id="userAction" class="com.ssh.usermanage.action.UserAction" scope="prototype">
<!-- setIs(myIndexService) -->
<property name="userService" ref="userService"/>
</bean>
<!-- myIndexService = new ssh.service.IndexServiceImpl() -->
<bean id="userService" class="com.ssh.usermanage.service.impl.UserServiceImpl" scope="prototype">
<property name="userDao" ref="userDao"/>
</bean>
<bean id="userDao" class="com.ssh.usermanage.dao.impl.UserDaoImpl" scope="prototype">
<!-- 把sessionFactory 注入给userDao -->
<property name="sessionFactory" ref="sessionFactory" />
</bean>
</beans>
2.4 日志记录
log4j.properties
### direct log messages to stdout ###
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.err
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n ### direct
messages to file mylog.log ### log4j.appender.file=org.apache.log4j.FileAppender
log4j.appender.file.File=d\:mylog.log
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n ### set log
levels - for more verbose logging change 'info' to 'debug' ### log4j.rootLogger=info,
stdout
3 创建包结构和类
3.1 实体类 User.java
package com.ssh.usermanage.entity;
public class User {
private Integer id;
private String name;
private Integer age;
public User() {
super();
}
public User(String name, Integer age) {
super();
this.name = name;
this.age = age;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "User [id=" + id + ", name=" + name + ", age=" + age + "]";
}
}
3.2 服务接口service和对应的实现类
UserService.java
package com.ssh.usermanage.service;
import com.ssh.usermanage.entity.User;
public interface UserService {
public User getUserById(Integer id);
public void insert(User user);
}
UserServiceImpl.java
package com.ssh.usermanage.service.impl;
import com.ssh.usermanage.dao.impl.UserDaoImpl;
import com.ssh.usermanage.entity.User;
import com.ssh.usermanage.service.UserService;
public class UserServiceImpl implements UserService{
private UserDaoImpl userDao;
public void setUserDao(UserDaoImpl userDao) {
this.userDao = userDao;
}
public UserDaoImpl getUserDao() {
return userDao;
}
@Override
public User getUserById(Integer id) {
return userDao.getUserById(id);
}
@Override
public void insert(User user) {
userDao.insert(user);
}
}
3.3 持久层接口和对应实现类
UserDao.java
package com.ssh.usermanage.dao;
import com.ssh.usermanage.entity.User;
public interface UserDao {
public User getUserById(Integer id);
public void insert(User user);
}
UserDaoImpl.java
package com.ssh.usermanage.dao.impl;
import com.ssh.usermanage.dao.UserDao;
import com.ssh.usermanage.entity.User;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
import org.springframework.stereotype.Repository;
/*
*JdbcTemplate是由Spring提供的对jdbc简单封装的接口,HibernateDaoSupport是hibernate框架提供的
*对数据库的操作。
*
*/
public class UserDaoImpl extends HibernateDaoSupport implements UserDao{
//获取和当前线程绑定的session
private JdbcTemplate jdbcTemplate;
public JdbcTemplate getJdbcTemplate() {
return jdbcTemplate;
}
public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
public JdbcTemplate getJdbcTemplate(JdbcTemplate jdbcTemplate) {
return jdbcTemplate;
}
@Override
public User getUserById(Integer id) {
String hql = "select * from user where id=?";
return(User)this.getHibernateTemplate().get(User.class, id);
}
@Override
public void insert(User user) {
this.getHibernateTemplate().save(user);
}
}
4 jsp
<%@ page language="java" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head></head>
<body>
<a style="color:red">
<a></a>
</body>
</html>
5 action
package com.ssh.usermanage.action;
import com.opensymphony.xwork2.ActionSupport;
import com.ssh.usermanage.entity.User;
import com.ssh.usermanage.service.impl.UserServiceImpl;
/**
* Action类中的方法签名有要求的,必须定义为public,返回类型必须为String,且不能有参数列表,更多关于struts的只是将在以后的章节中学到。
*/
public class UserAction extends ActionSupport {
/**
*
*/
private static final long serialVersionUID = 1L;
private UserServiceImpl userService;
public UserServiceImpl getUserService() {
return userService;
}
public void setUserService(UserServiceImpl userService) {
this.userService = userService;
}
//action中的方法不能参数列表
public String execute() {
User user = userService.getUserById(4);
System.out.println(user.getName());
return "success";
}
}
总结:该点主要是将hibernate在ssh框架中的基本配置和运用,更多配置和运用将会在以后的经典整合框架中详细讲到。