Hibernate_01
A.配置
1.概述
Hibernate是典型的面向对象框架
在使用该框架对数据库进行操作,不需要编写sql语句
框架底层会根据配置文件自动生成sql
大大的减少了开发工作量和代码量
可以使我们采用对象化的思维操作关系型数据库
2.配置步骤
扫描二维码关注公众号,回复: 2833415 查看本文章a.下载hibernate压缩包
b.在环境中引用hibernate的jar包和mysql数据库jar包:
非web在构建路径中引用
web应用在WEB-INF下的lib中拷贝
c.创建数据库配置相关的配置文件
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> <!-- 数据库相关配置 --> <!-- 数据库驱动 --> <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property> <!-- jdbc连接数据库url地址 --> <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/test</property> <!-- 连接数据库的用户名 --> <property name="hibernate.connection.username">root</property> <!-- 连接数据库的密码 --> <property name="hibernate.connection.password">root</property> <!-- 为了使用数据库特性而必须指定的,比如limit是mysql专用的分页操作 --> <property name="hibernate.dialect">org.hibernate.dialect.MySQL55Dialect</property> <!-- 其他特性配置 --> <!-- 显示sql语句 --> <property name="hibernate.show_sql">true</property> <!-- sql语句格式化显示 --> <property name="hibernate.format_sql">true</property> <!-- 底层数据库的表生成方式,仅开发阶段使用 --> <!-- 有则更新,无则创建 --> <property name="hibernate.hbm2ddl.auto">update</property> <!-- 加载映射稳定件,告诉框架和底层表的关系 --> <mapping resource="org/xxxx/hibernate/UserInfo.hbm.xml" /> </session-factory> </hibernate-configuration>
d.创建实体类,通常和数据库表字段匹配
id作为标识列,也就是数据库表中的主键,有参构造不需要设置id
package org.xxxx.hibernate; import java.io.Serializable; public class UserInfo implements Serializable { private static final long serialVersionUID = 1L; private int id; private String username; private String password; public UserInfo() { super(); } // 不要设置id,数据库自增长 public UserInfo(String username, String password) { super(); this.username = username; this.password = password; } 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 getPassword() { return password; } public void setPassword(String password) { this.password = password; } @Override public String toString() { return "UserInfo [id=" + id + ", username=" + username + ", password=" + password + "]"; } }
e.和实体类匹配创建映射文件,通常放置在实体类同包
<?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="org.xxxx.hibernate"> <!-- pojo框架和数据库中表的关系 --> <!-- name为类名,table为数据库生成的表名 --> <class name="UserInfo" table="userinfo"> <!-- pojo的标识列和主键的关系 --> <!-- name为类中的变量,column为表中的字段,也就是id对应的是表中的uid --> <id name="id" column="uid"> <!-- 主键的生成方式,设置为自增长 --> <generator class="native"></generator> </id> <!-- 其他字段和表中列的对应关系 --> <!-- 若column不写,则默认与类中相同 --> <property name="username"></property> <property name="password"></property> </class> </hibernate-mapping>
f.把映射文件添加到数据库配置文件中
就在hibernate.cfg.xml中添加下面这句(上面代码中已添加)
g.测试
运行,查看控制台package org.xxxx.hibernate; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.Transaction; import org.hibernate.cfg.Configuration; public class Test { public static void main(String[] args) { // 加载配置文件 Configuration config = new Configuration().configure(); // 创建数据库映射对象 SessionFactory factory = config.buildSessionFactory(); // 获取Session Session session = factory.openSession(); // 开始事物:如果是select,则不需要,否则必须设置 Transaction tr = session.beginTransaction(); // 使用pojo,给表中增加数据,调用相关session方法 UserInfo uf = new UserInfo("zhangsan", "123456"); session.save(uf); // 提交事物:如果是select,则不需要,否则必须设置 tr.commit(); // 关闭session session.clear(); } }
首次运行,数据库中没有对应的表,会先创建一个表,并生成sql语句
之后,再执行插入,生成insert语句,将数据插入数据库中
接下来查看数据库,发现数据已经产生
B.Hibernate中的核心类
1.图解
2.核心类
a.Configuration接口:配置并启动Hibernate
b.SessionFactort接口:初始化Hibernate
c.Session接口:持久化对象的CRUD才做
d.Transaction接口:事物
e.Query接口和Criteria接口:执行各种数据库查询
注意:Configuration实例是一个启动期间的临时对象
C.Session
1.概述
Java应用程序与hibernate之间的主要运行时接口
是对JDBC Connection封装
其生命周期绑定在一个物理的事务(tansaction)上面
Session的主要功能是提供对映射对象的增删改查方法
有一个缓存,保存了持久化对象,当清理缓存时
这些对象会被同步更新至数据库
2.persist方法和save()方法
a.presist()
persist方法把改动缓存到session的一级缓存中
不会立即生成sql语句
必须在事务范围才会更新到数据库
b.save()
save方法立即把改动写入,不管是否在事务范围
3.load()与get()
a.load()
load方法先返回代理对象
只有在需要访问数据时候才会执行查询数据操作
package org.xxxx.hibernate; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.Transaction; import org.hibernate.cfg.Configuration; public class Test { public static void main(String[] args) { // 加载配置文件 Configuration config = new Configuration().configure(); // 创建数据库映射对象 SessionFactory factory = config.buildSessionFactory(); // 获取Session Session session = factory.openSession(); // 开始事物:如果是select,则不需要,否则必须设置 Transaction tr = session.beginTransaction(); // load获取数据id=1 UserInfo uf = session.load(UserInfo.class, 1); // 当有这句时,才会执行sql语句 System.out.println(uf); // 关闭 session.close(); } }
当没有使用uf时,控制台没有结果
b.get()
get方法通过id立刻从表中查询这条数据
// load获取数据id=1 UserInfo uf = session.get(UserInfo.class, 1);
D.Hibernate对象状态
1.Transient临时
new出来,在内存中,和数据库无关
2.Persist持久化
Persist持久化:session实例关联,数据库有记录,有标识符
3.Detached游离
Detached游离: session实例被关闭,数据库可能有记录
4.Deleted删除
delete方法调用后,数据库没有记录
5.状态关系
6.修改数据:update
// load获取数据id=1 UserInfo uf = session.get(UserInfo.class, 1); // 修改 uf.setUsername("lisi"); // 执行 session.update(uf); // 提交事物 tr.commit(); // 关闭 session.close();
7.删除数据:delete
// load获取数据id=1 UserInfo uf = session.get(UserInfo.class, 1); // 执行 session.delete(uf); // 提交事物 tr.commit(); // 关闭 session.close(); // 删除后,uf属于游离状态,数据库中没有数据,但内存中有 // 再次开启session,使用save,可以将uf变为持久状态
8.saveOrUpdate()
顾名思义,就是添加或更新
// load获取数据id=1 UserInfo uf = session.get(UserInfo.class, 1); uf.setUsername("lisi"); // 执行,获取的有自增长键,数据库中存在所以执行update session.saveOrUpdate(uf); // 提交事物 tr.commit(); // 关闭 session.close();
E.数据库事物
1.概述
主要是为了解决并发情况下保持数据一致性的问题
必须满足ACID(原子性、一致性、隔离性和持久性)原则
比如银行转帐
try { // 发生异常,事物回滚 System.out.println(1/0); } catch (Exception e) { // 事务回滚 tr.rollback(); }
2.事务中包含的操作被看做一个逻辑单元
3.只有合法的数据可以被写入数据库,否则回滚
4.并行事务的修改必须与其他并行事务的修改相互独立
5.事务结束后,事务处理的结果必须能够得到持久化
F.Eclipse中使用Maven创建Hibernate
1.安装Jboss Tools插件后,使用Maven创建web工程
在pom.xml中下载相应依赖和插件
<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>org.xxxx.hibernate</groupId> <artifactId>Login</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>war</packaging> <dependencies> <!-- Hibernate坐标 --> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-core</artifactId> <version>5.2.12.Final</version> </dependency> <!-- mysql驱动 --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.41</version> </dependency> </dependencies> <build> <finalName>Login</finalName> <plugins> <!-- jdk1.8 --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.7.0</version> <configuration> <source>1.8</source> <target>1.8</target> </configuration> </plugin> </plugins> </build> </project>
2.建立UserInfo
代码同上
3.添加配置文件
hibernate.cfg.xml在src/mainresources中
这里使用JbossTools插件生成两个配置文件
减少工作量
右键项目->file->other->查找hibernate如下
选择路径resources
填写参数
点击finish,即可生成,再进行一些修改即可
此界面中,可以进一步完善
4.持久化配置文件
UserInfo.hbm.xml在UserInfo包下
右键UserInfo->new->other
选择,一路下一步,生成代码,稍微修改下即可
在cfg.xml中映射此文件
5.操作完后,完整的映射
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-factory name="mysql"> <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property> <property name="hibernate.connection.password">root</property> <property name="hibernate.connection.url">jdbc:mysql://127.0.0.1:3306/test</property> <property name="hibernate.connection.username">root</property> <property name="hibernate.dialect">org.hibernate.dialect.MySQL57Dialect</property> <property name="hibernate.show_sql">true</property> <property name="hibernate.format_sql">true</property> <property name="hibernate.hbm2ddl.auto">update</property> <mapping resource="org/xxxx/pojo/UserInfo.hbm.xml"/> </session-factory> </hibernate-configuration>
UserInfo.hbm.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-1-6 22:03:42 by Hibernate Tools 3.5.0.Final --> <hibernate-mapping package="org.xxxx.pojo"> <class name="UserInfo" table="userinfo"> <id name="id" type="int"> <column name="ID" /> <generator class="native" /> </id> <property name="username" type="java.lang.String"> <column name="username" /> </property> <property name="password" type="java.lang.String"> <column name="password" /> </property> </class> </hibernate-mapping>
6.写个登陆功能
login.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>登陆</title> </head> <body> <center> <form action="LoginServlet" method="post"> 用户名:<input type="text" name="username" /><br> 密 码:<input type="password" name="password" /><br> <input type="submit" value="提交" /> </form> <font style="font-size: 20px;color: red;">${ msg }</font> </center> </body> </html>
success.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>登陆成功</title> </head> <body> <center> <font style="font-size: 20px; color: green;">${ username },欢迎您!</font> </center> </body> </html>
LoginServlet.java
package org.xxxx.web; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.cfg.Configuration; @WebServlet("/LoginServlet") public class LoginServlet extends HttpServlet { private static final long serialVersionUID = 1L; protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 设置编码 request.setCharacterEncoding("utf-8"); response.setContentType("text/html;charset=utf-8"); // 获取参数 String username = request.getParameter("username"); String password = request.getParameter("password"); // 加载驱动 Configuration config = new Configuration().configure(); // 获取工厂 SessionFactory factory = config.buildSessionFactory(); // 获取Session Session session = factory.openSession(); // 定义hql语句 String hql = "select u from UserInfo u where u.username=? and u.password=?"; // 执行 int size = session.createQuery(hql).setParameter(0, username).setParameter(1, password).list().size(); // 关闭 session.close(); // 判断 if (size > 0) { // 登陆成功 request.setAttribute("username", username); request.getRequestDispatcher("success.jsp").forward(request, response); } else { // 登录失败 request.setAttribute("msg", "用户名或密码错误!"); request.getRequestDispatcher("login.jsp").forward(request, response); } } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
运行程序,自行测试