0、相关知识
java框架篇—hibernate入门
Hibernate是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,使得Java程序员可以随心所欲的使用对象编程思维来操纵数据库。 Hibernate可以应用在任何使用JDBC的场合,既可以在Java的客户端程序使用,也可以在Servlet/JSP的Web应用中使用,最具革命意义的是,Hibernate可以在应用EJB的J2EE架构中取代CMP,完成数据持久化的重任。
流程图:
核心接口
Hibernate的核心接口一共有6个,分别为:Session、SessionFactory、Transaction、Query、Criteria和Configuration。这6个核心接口在任何开发中都会用到。通过这些接口,不仅可以对持久化对象进行存取,还能够进行事务控制。下面对这6个核心接口分别加以介绍。
Session
Session接口负责执行被持久化对象的CRUD操作(CRUD的任务是完成与数据库的交流,包含了很多常见的SQL语句。)。但需要注意的是Session对象是非线程安全的。同时,Hibernate的session不同于JSP应用中的HttpSession。这里当使用session这个术语时,其实指的是Hibernate中的session,而以后会将HttpSession对象称为用户session。
SessionFactory
SessionFactory接口负责初始化Hibernate。它充当数据存储源的代理,并负责创建Session对象。这里用到了工厂模式。需要注意的是SessionFactory并不是轻量级的,因为一般情况下,一个项目通常只需要一个SessionFactory就够,当需要操作多个数据库时,可以为每个数据库指定一个SessionFactory。
Transaction
Transaction 接口是一个可选的API,可以选择不使用这个接口,取而代之的是Hibernate 的设计者自己写的底层事务处理代码。 Transaction 接口是对实际事务实现的一个抽象,这些实现包括JDBC的事务、JTA 中的UserTransaction、甚至可以是CORBA 事务。之所以这样设计是能让开发者能够使用一个统一事务的操作界面,使得自己的项目可以在不同的环境和容器之间方便地移植。
Query
Query接口让你方便地对数据库及持久对象进行查询,它可以有两种表达方式:HQL语言或本地数据库的SQL语句。Query经常被用来绑定查询参数、限制查询记录数量,并最终执行查询操作。
Criteria
Criteria接口与Query接口非常类似,允许创建并执行面向对象的标准化查询。值得注意的是Criteria接口也是轻量级的,它不能在Session之外使用。
Configuration
Configuration 接口的作用是对Hibernate 进行配置,以及对它进行启动。在Hibernate 的启动过程中,Configuration 类的实例首先定位映射文档的位置,读取这些配置,然后创建一个SessionFactory对象。虽然Configuration 接口在整个Hibernate 项目中只扮演着一个很小的角色,但它是启动hibernate 时所遇到的每一个对象。
以上内容转载自:java框架篇-hibernate入门
Hibernate是一款ORM(Object-Relationship Mapping)框架,常用于Java EE开发中,同样的orm有mybatis,Hibernate的思想是这样的。
1、生成数据库表映射到XML
2、由SessionFactory工厂类获得Session(这个session对应于数据库session,而不是web的session)
3、通过Session执行HQL语句,完成数据库操作(主要操作是这一步,用Hibernate都是跟Session打交道)
4、HQL之前后可以加入Transaction(Transaction可以理解成数据库的事务)
PS:这是在hibernate官网的做法叫做native api,就是原生操作,官网还有其他操作用法,具体去官网了解。
其他Hibernate的相关知识还有:XML配置多表关系(one-to-many,many-to-one等)、级联操作、延迟加载、缓存技术
其实可以看到,这些数据库都有的操作,使用框架实现。
这篇文章并不讲这些只是,仅仅是一篇框架搭建文章,不涉及技术。
1、系统环境
IDE:InterliJ IDEA 2017.1.4
jdk版本:1.8
Maven版本:3.5
Hibernate版本:5.X
数据库:MySQL 5.7 包含user表的sql脚本
maven的目录规定是这样的:
最后点finish
点Enable Auto-import
3、发布项目
点了加号,还要点最后一项,“34 items more”这个菜单项,才会出现这个界面
点ok
点运行,搞定
若报错,可能是maven缺少一个依赖
<!-- ********************** Java Servlet API 4.0.0-b01 ********************** -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.0-b01</version>
</dependency>
添加进去就正常了
##4、添加Hibernate
添加如下依赖:
<!-- ********************** Java Servlet API 4.0.0-b01 ********************** -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.0-b01</version>
</dependency>
<!-- ********************** JUnit 4.12 ********************** -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<!-- ********************** Hibernate 5.0.6.Final ********************** -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.0.6.Final</version>
</dependency>
<!-- ********************** MySQL 5.1.38 ********************** -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.38</version>
</dependency>
<!-- ********************** Java Transaction API 1.1 ********************** -->
<dependency>
<groupId>javax.transaction</groupId>
<artifactId>jta</artifactId>
<version>1.1</version>
</dependency>
创建项目步骤的新建java目录并改变为source root必须做,次啊能正确生生成。
信息自己填了。
点ok生成
再次生成如下:
图片没截图到,用下一张图,涂一下凑合吧QAQ。
6、创建HibernateSessionFactory
创建一个工厂,生成session代码如下:
package util;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.boot.MetadataSources;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
/**
* Configures and provides access to Hibernate sessions, tied to the
* current thread of execution. Follows the Thread Local Session
* pattern, see {@link http://hibernate.org/42.html }.
*/
public class HibernateSessionFactory {
/**
* Location of hibernate.cfg.xml file.
* Location should be on the classpath as Hibernate uses
* #resourceAsStream style lookup for its configuration file.
* The default classpath location of the hibernate config file is
* in the default package. Use #setConfigFile() to update
* the location of the configuration file for the current session.
*/
private static final ThreadLocal<Session> threadLocal = new ThreadLocal<Session>();
private static org.hibernate.SessionFactory sessionFactory;
private static ServiceRegistry serviceRegistry;
static {
try {
serviceRegistry = new StandardServiceRegistryBuilder().configure().build();
try {
sessionFactory = new MetadataSources(serviceRegistry).buildMetadata().buildSessionFactory();
} catch (Exception e) {
StandardServiceRegistryBuilder.destroy(serviceRegistry);
e.printStackTrace();
}
} catch (Exception e) {
System.err.println("%%%% Error Creating SessionFactory %%%%");
e.printStackTrace();
}
}
private HibernateSessionFactory() {
}
/**
* Returns the ThreadLocal Session instance. Lazy initialize
* the <code>SessionFactory</code> if needed.
*
* @return Session
* @throws HibernateException
*/
public static Session getSession() throws HibernateException {
Session session = (Session) threadLocal.get();
if (session == null || !session.isOpen()) {
if (sessionFactory == null) {
rebuildSessionFactory();
}
session = (sessionFactory != null) ? sessionFactory.openSession()
: null;
threadLocal.set(session);
}
return session;
}
/**
* Rebuild hibernate session factory
*/
public static void rebuildSessionFactory() {
try {
serviceRegistry = new StandardServiceRegistryBuilder().configure().build();
try {
sessionFactory = new MetadataSources(serviceRegistry).buildMetadata().buildSessionFactory();
} catch (Exception e) {
StandardServiceRegistryBuilder.destroy(serviceRegistry);
e.printStackTrace();
}
} catch (Exception e) {
System.err.println("%%%% Error Creating SessionFactory %%%%");
e.printStackTrace();
}
}
/**
* Close the single hibernate session instance.
*
* @throws HibernateException
*/
public static void closeSession() throws HibernateException {
Session session = (Session) threadLocal.get();
threadLocal.set(null);
if (session != null) {
session.close();
}
}
/**
* return session factory
*/
public static org.hibernate.SessionFactory getSessionFactory() {
return sessionFactory;
}
}
在web.xml添加如下:
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app>
<display-name>Archetype Created Web Application</display-name>
<servlet>
<servlet-name>HibernateDemo</servlet-name>
<servlet-class>servlet.servlet</servlet-class>
</servlet>
<!--添加如下4行-->
<servlet-mapping>
<servlet-name>HibernateDemo</servlet-name>
<url-pattern>/HibernateServletDemo</url-pattern>
</servlet-mapping>
</web-app>
Hibernate配置文件如下:
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="connection.username" >root</property>
<property name="connection.password">root</property>
<property name="connection.url">jdbc:mysql://localhost:3306/networkalbum?useSSL=false&characterEncoding=utf-8&useUnicode=true</property>
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<mapping resource="POJO/user.xml"/>
<mapping class="POJO.UserEntity"/>
<!-- <property name="connection.username"/> -->
<!-- <property name="connection.password"/> -->
<!-- DB schema will be updated if needed -->
<!-- <property name="hbm2ddl.auto">update</property> -->
</session-factory>
</hibernate-configuration>
HibernateDemo这个servlet的代码:
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request,response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setCharacterEncoding("utf-8");
request.setCharacterEncoding("utf-8");
List<UserEntity> list = HibernateSessionFactory.getSession().createQuery("from UserEntity ").list();
PrintWriter writer = response.getWriter();
for (UserEntity user:list) {
writer.write(user.getId()+"");
writer.append(user.getName());
System.out.println(user.toString());
writer.write("\n");
}
}
ps:发现一个bug,writer.write(user.getId());其中user.getId()的值是int类型,如果直接输出int类型浏览器会认为是其他类型的文件,浏览器不解析response的输出。