利用一晚上的时间配置了一下Hibernate,做了一个简单的demo练习实现对数据库的增删改查,接下来我一步步的分析并且会指出每一步大家该注意的地方。
首先引进jar包:
接下来,我们来看一下目录:
好了,现在就开始我们的工作:
1 . 建立实体类User,和数据库中的表有对应关系,实现每个属性的get和set方法(有三个属性),并实现可序列化。
package User;
import java.io.Serializable;
public class User implements Serializable {
public User() {
//默认的构造方法
}
private Integer id;
private String loginName;
private String loginPwd;
public String getLoginPwd() {
return loginPwd;
}
public void setLoginPwd(String loginPwd) {
this.loginPwd = loginPwd;
}
public String getLoginName() {
return loginName;
}
public void setLoginName(String loginName) {
this.loginName = loginName;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
}
2.写Hibernate的映射文件,在这个文件中写数据库表和实体类的映射关系。
以下是一个简单的映射文件的配置。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernat mapping DTD3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.hibtest1.entity.User" table="users" catalog="bookshop">
<id name="id" type="java.lang.Integer">
<column name = "Id"/><!-- 指定主键 -->
<generator class = "native"></generator>
<!-- generator用来指定主键的生成策略,常用值为native和assigned -->
</id>
<property name="loginName" type="java.lang.String">
<column name="LoginName" length="50"/>
</property>
<property name="loginPwd" type="java.lang.String">
<column name="LoginPwd" length="16"/>
</property>
</class>
</hibernate-mapping>
<!-- 是Hibernate的映射文件,告知Hibernate框架实体类Users映射到数据库中的哪个表,以及属性和字段的对应关系 -->
<!-- 配置了从User实体类到数据库users表的映射,每个class中配置一个实体类的映射信息 -->
3.最后写hibernate.cfg.xml,即hibernate的配置文件,在这个文件中写连接数据库的相关信息和hibernate的参数,并将映射文件加载进来。
<?xml version="1.0" encoding="UTF-8"?>
<!-- hibernate的配置文件 -->
<!-- 需要配置连接数据库的相关信息和hibernate的参数 -->
<!-- 数据库的相关信息包括驱动,username,password,url等 -->
<!-- dialect参数必须配置,用来配置Hibernate使用的不同数据库类型 -->
<!-- show_sql表示程序运行时在控制台输出执行的sql语句 -->
<!DOCTYPE hibernate-configution PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configution>
<session-factory>
<property name="show_sql">true</property>
<property name="eclipse.connection.profile">bookshop</property>
<property name="connection.url">jdbc:mysql://localhost:3306/bookshop</property>
<property name="connection.username">root</property>
<property name="connection.password">12345</property>
<property name="driver_class">com.mysql.jdbc.Driver</property>
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<mapping resource="com.hibtest1/entity/User.hbm.xml"/>
<!-- 声明加载之前写的数据库和表的映射文件User.hbm.xml -->
</session-factory>
</hibernate-configution>
4.到此,所有准备工作已经做完,接下来我们要编写测试类,实现向数据库中添加数据,并且一起经历整个Hibernate操作处理的过程。
(1) TestAdd.java
package User;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
public class TestAdd {
public static void main(String[] args) {
new TestAdd().addUser();
}
public void addUser() {
//建立持久化对象,并赋初值(实例化实体类)
User user = new User();
user.setLoginName("huqianmenfg");
user.setLoginPwd("12345");
//初始化,读取配置文件hibernate.cfg.xml
Configuration config = new Configuration().configure();
//读取创建sessionFactory
SessionFactory sessionFactory = config.buildSessionFactory();
//打开session
Session session = sessionFactory.openSession();
//事务处理
Transaction tx=null;
try {
//开始一个事务
tx = session.beginTransaction();
//持久化操作,保存user对象信息
session.save(user);
//提交事务
tx.commit();
} catch(Exception e) {
if(tx != null) {
tx.rollback();
//回滚
}
} finally {
session.close();
}
}
}
/*
* 注意: 除了持久化对象的建立过程以及赋值过程之外,所有的操作步骤都是固定的,整个hibernate的处理过程就是这样的
* Hibernate的处理过程:读取配置文件,根据Configuration创建sessionFactory,用来生产session,接着就是生产session的过程。
* 最后进行事务提交和处理的过程。事务提交的过程中,如果提交成功,则提交数据,否则回滚。
*
* 需要注意的是:Session的save方法必须在事务环境中完成,并需要使用commit方法来提交事务,提交成功后数据才会被写入数据库。
* */
运行最后的测试类,就可以实现将user用户数据添加到数据库中,方便简单!!!
以上完成了用hibernate实现向数据库中添加数据的过程,接下来我们来实现查询、修改和删除数据的过程。
(2)TestDelete.java
package User;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
public class TestDelete {
public static void main(String[] args) {
}
private void testDelete() {
//读取配置文件
Configuration config = new Configuration();
//创建sessionFactory
SessionFactory sessionFactory = config.buildSessionFactory();
//打开session
Session session = sessionFactory.openSession();
Transaction tx = null;
//加载要删除的数据,和查询的方法一样(其实本质就是查询到需要删除的值,都用的是session.get());
//也是根据主键进行查询,方便后期的删除过程。
User user = (User)session.get(User.class, new Integer(1));
//注意删除的过程需要加事务处理和 try-catch 异常处理机制
try {
//开启一个事务
tx = session.beginTransaction();
//进行删除操作
session.delete(user);
//提交这个事务
tx.commit();
} catch(Exception e) {
if(tx != null) {
tx.rollback();//回滚
}
e.printStackTrace();
} finally {
session.close();//在 finally 中关闭 session
}
}
}
/*
*注意: 实现删除功能的方法都是private void 类型的方法。
* */
(3) TestUpdate.java
package User;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
public class TestUpdate {
public static void main(String[] args) {
}
private void testUpdate() {
//加载配置文件
Configuration config = new Configuration();
//创建sessionFactory
SessionFactory sessionFactory = config.buildSessionFactory();
//得到session
Session session = sessionFactory.openSession();
//得到需要修改的数据,根据主键查询即可
User user = (User)session.get(User.class, new Integer(2));
Transaction tx = null;
//直接在外部修改数据
user.setLoginName("qianmenghu");
//以下是事务处理
try {
//开启事务
tx = session.beginTransaction();
//执行修改操作
session.update(user);
//提交事务
tx.commit();
} catch(Exception e) {
if(tx != null) {
tx.rollback();//出错即回滚
}
e.printStackTrace();
} finally {
session.close();
}
}
}
/*
* 注意:执行修改操作的时候需要在事务的外部修改数据。直接用user.set方法就可以实现。
* 其他的步骤都和之前的操作一样,修改也要进行事务处理
* 除了查询不需要进行事务处理之外,别的(添加、删除、修改),只要是对数据有相应的改动的操作,都需要进行事务处理。
* 获取操作数据的方式都是相同的。
* */
接下来是实现查询的功能,查询功能中不需要进行事务处理,直接根据主键查询即可。
(4) TestLoad.java
package User;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
/*
* 查询功能:根据主键将一条数据从数据库中查询出来
* */
public class TestLoad {
public static void main(String[] args) {
}
private void testLoad() {
//初始化,读取配置文件
Configuration config = new Configuration().configure();
//打开sessionFactory
SessionFactory sessionFactory = config.buildSessionFactory();
//创建session
Session session = sessionFactory.openSession();
//加载数据
User user = (User)session.get(User.class, new Integer(1));
//在控制台输出用户名和密码
System.out.println(user.getLoginName()+" "+user.getLoginPwd());
}
}
/*
* 注意: 查询过程中,直接读取配置文件,打开sessionFactory,创建session即可。
* 创建完session之后就可以根据主键查询数据,采用session.get(User.class, new Integer(1))
* 查询过程中不需要事务处理过程,只有在修改或者添加数据的过程中才需要进行事务处理。
* 还有就是session.get()的第一个参数是通过反射得到user对象的所有属性值,get方法调完之后就可以在控制台显示属性的信息。
*/
以上就是按照顺序实现增删改查的功能的过程和实现,我们可以发现,hibernate已经为我们封装好了这几种操作的接口,我们直接用session调用接口即可,只需要一句话就能完成增删改查操作,而不是像以前一样需要写sql语句自己完成增删改查过程。极大的简化了程序员的编码工作。
接下来是福利:(哈哈哈哈—)
我们可以在 eclipse中自动添加hibernate支持(通过配置直接添加),从而可以自动生成hibernate实体类和hibernate配置文件,配置完数据库的相关信息之后还可以直接生成映射文件。
1 . 我们自己实现的过程中,在测试类中需要读取配置信息,读取解析映射信息,创建session工厂最终生成session实例,最后调用session接口的方法实现增删改查操作。
2 . 但是当我们利用eclipse自动添加hibernate支持的时候,会自动创建工厂,我们只需要创建session实例即可。
3 . 接下来,我们在2的基础上,直接写一个BaseHibernateDao类,将数据的增删改查方法都写进去。
4 .写接口,写实现,实现继承BaseHibernateDao类,调方法实现功能。
(1)BaseHibernate.java
package User;
public interface BaseHibernate {
public void add(User user);
public User get(Integer id);
public void delete(User user);
public void update(User user);
}
(2)BaseHibernateImpl.java
package User;
public class BaseHibernateImpl extends BaseHibernateDao implements BaseHibernate {
@Override
public void add(User user) {
super.add(user);
}
@Override
public User get(Integer id) {
return (User)super.get(User.class, id);
}
@Override
public void delete(User user) {
super.delete(user);
}
@Override
public void update(User user) {
super.update(user);
}
}
(3)BaseHibernateDao.java
package User;
import java.io.Serializable;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
//是一个抽象类,抽象类的作用?为什么要写成抽象类?
public abstract class BaseHibernateDao {
/* 添加数据 */
// protected类型,无返回值,参数是 Object 类型(传进来user对象)
protected void add(Object object) {
Transaction tran = null;
// 获取session
// 如果eclipse自动创建一个HibernateSessionFactory的话,这里可以直接用
// 即 Session session = HibernateSessionFactory.getSession();
//常规方法获取session
Configuration config = new Configuration().configure();
SessionFactory sessionFactory = config.buildSessionFactory();
Session session = sessionFactory.openSession();
//事务处理
try {
tran = session.beginTransaction();
session.save(object);
tran.commit();
} catch(Exception e) {
if(tran != null) {
tran.rollback();//回滚
}
e.printStackTrace();
} finally {
session.close();
}
}
//添加没有返回值,但是查询有返回值,返回值类型是Object,参数类型是按照id升序排列的所有对象
protected Object get(Class cla, Serializable id) {
Object object = null;
Configuration config = new Configuration().configure();
SessionFactory sessionFactory = config.buildSessionFactory();
Session session = sessionFactory.openSession();
try {
object = session.get(cla, id);
} catch(Exception e) {
e.printStackTrace();
} finally {
session.close();
}
return object;
}
//删除数据,没有返回值
protected void delete(Object object) {
Transaction tran = null;
Configuration config = new Configuration().configure();
SessionFactory sessionFactory = config.buildSessionFactory();
Session session = sessionFactory.openSession();
try {
tran = session.beginTransaction();
session.delete(object);
tran.commit();
} catch(Exception e) {
if(tran != null) {
tran.rollback();
}
e.printStackTrace();
} finally {
session.close();
}
}
//修改数据,无返回值
protected void update(Object object) {
Transaction tran = null;
Configuration configuration = new Configuration().configure();
SessionFactory sessionFactory = configuration.buildSessionFactory();
Session session = sessionFactory.openSession();
try {
tran = session.beginTransaction();
session.update(object);
tran.commit();
} catch(Exception e) {
if(tran != null) {
tran.rollback();
}
e.printStackTrace();
} finally {
session.close();
}
}
}
//在这个类中,实现了增删改查四种方法,我们为了方便调用,写一个接口,然后写一个实现类去实现这个接口,
//在实现类中继承本类,利用本类中的方法去实现功能。此后操作的时候就直接调用接口就可以实现增删改查的功能。
至此,eclipse自动添加hibernate的支持,完整实现对数据的增删改查。我们的工作就先告一段落!
待更!!!