分享知识-快乐自己:搭建第一个 Hibernate (Demo)
使用 Hibernate 完成持久化操作 七大 步骤:
1、读取并解析配置文件及映射文件:
Configuration configuration=new Configuration().configure();
根据默认位置的 Hibernate 配置文件中的信息,构建 Configuration 对象。 Configuration 负责管理 Hibernate 的配置信息。
2、依据配置文件和映射文件中的信息,创建 SessionFactory 对象;
SessionFactory sessionFactory=configuration.buildSessionFactory();
Configuration 对象会根据当前的数据库配置信息, 构造 SessionFactory 对象。SessionFactory 对象一旦构造完毕,Configuration 对象的任何变更不会影响已经创建的 SessionFactory 对象。
如果 Hibernate 配置信息有改动,那么需要基于改动后的 Configuration 对象重新构建一个 SessionFactory 对象。
3、打开 Session ;
Session session=sessionFactory.getCurrentSession(); 或 sessionFactory.openSession();
SessionFactory 负责创建 Session 对象。Session 是持久化操作的基础。Session 作为贯穿 Hibernate 的持久化管理的核心,提拱了众多持久化方法,如 save()、delete()、update()、get()、load()等…
通过这些方法,即可透明地完成对象的 增删改查(CRUD)
4、开始一个事务;
Tansaction tx = session.beginTansaction();
5、数据库操作;
session.save();//保存操作
6、结束事务;
tx.commit();//提交事务 或 回滚事务
7、如果是通过 SessionFactory 的 openSession() 方法获取的 Session 对象,则需要关闭 session。
session.close();
提示:如果在 Hibernate 配置文件中将参数 current_session_context_class 设置为 thread,并采用 SessionFactory 的 getCurrentSession()方法 获得 Session 对象。
则不需要执行 session.close() 方法,通过这种方式获得的Session 对象,会在关联的事务结束(提交或回滚)时自动关闭。
更新数据的方法:
1): update() 方法,用于将游离的对象恢复为持久状态,同时进行数据库更新操作。当参数对象的 OID 为 null 时会报错异常
2):saveOrUpdate()方法,同时包含了save()与update()方法的功能,如果入参是瞬时状态的对象,就调用 save()方法;如果入参是游离状态的对象,则调用update()方法。
3):merge()方法,能够把作为参数传入的游离状态对象的属性 复制到一个拥有相同 OID 的持久状态对象中,通过对持久状态的对象的脏检查实现更新操作,并返回该持久状态对象;
如果无法从Session 缓存或数据库中加载到相应的持久状态对象,即传入的是瞬时对象,则创建其副本执行插入操作,并返回这一新的持久状态对象。无论何种情况,传入的对象状态都不受影响。
案例目录结构:
1):环境搭建前期准备:
目前以及后期需要的 JAR:
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.3</version>
</dependency>
<!-- 添加Hibernate依赖 -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>3.6.10.Final</version>
</dependency>
<!-- 添加Log4J依赖 -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.16</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-nop</artifactId>
<version>1.6.4</version>
</dependency>
<!-- 添加javassist -->
<dependency>
<groupId>javassist</groupId>
<artifactId>javassist</artifactId>
<version>3.12.0.GA</version>
</dependency>
<dependency>
<groupId>org.hibernate.javax.persistence</groupId>
<artifactId>hibernate-jpa-2.0-api</artifactId>
<version>1.0.1.Final</version>
</dependency>
<dependency>
<groupId>javax.transaction</groupId>
<artifactId>jta</artifactId>
<version>1.1</version>
</dependency>
<!-- mysql数据库的驱动包 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.6</version>
</dependency>
</dependencies>
<build>
<!-- 加载我们的各种hbm.xml文件,如果hbm.xml文件在resources文件夹下面就不需要了-->
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
</resource>
</resources>
</build>
配置核心配置文件:hibernate.cfg.xml (必须以 .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> <!--配置连接数据库的四要素--> <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property> <property name="hibernate.connection.url">jdbc:mysql://39.105.105.186:3306/MyBatisCode?useUnicode=true&characterEncoding=UTF-8</property> <property name="hibernate.connection.username">root</property> <property name="hibernate.connection.password">root</property> <!--是否显示底层生成的sql语句--> <property name="hibernate.show_sql">true</property> <!--是否格式化sql语句--> <property name="hibernate.format_sql">true</property> <!--方言设置--> <!--MySql 驱动程序 eg. mysql-connector-java-5.0.4-bin.jar--> <property name="dialect">org.hibernate.dialect.MySQLDialect</property> <!--当前会话上下文--> <property name="current_session_context_class">thread</property> <!--hbm2ddl 就是把xx.hbm.xml文件中的配置生成数据库中DDL(数据定义语言) create: 每次运行都会删除 上次生成的表,还会创建新的! update: 没有表会自动创建,有表就增加数据! validate: 如果hbm文件和数据库中的字段对应 就会新增, 否则抛出异常! create-drop: 每次运行都会删除 上次生成的表,前提是sessionFactory关闭 --> <property name="hbm2ddl.auto">update</property> <!--加载需要的hbm.xml映射文件--> <mapping resource="mapping/user.hbm.xml"/> </session-factory> </hibernate-configuration>
编写映射文件 user.hbm.xml (必须以 .hbm.xml 为后缀)
<?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <!-- package: 需要映射的实体类所在包 class节点: name:对应的是实体类的类名,如果没有书写package,则必须是完整限定类名 table:数据库中的表名,如果表名和实体类名一致,可以省略 id节点:表中的主键 generator:主键生成策略 ,主键由谁去创建?程序猿?Hibernate?数据库 name: 必须和实体类中的属性名一致 column : 必须和数据库中的列名一致,如果列名和属性名一致,可以省略 --> <!--dynamic-update="false":默认非动态更新--> <hibernate-mapping package="com.mlq.bena"> <class name="com.mlq.bena.User" table="`user`" dynamic-update="true"> <id name="uId" column="uId"> <!--<generator class="assigned"/><!–主键生成策略–>--> <generator class="increment"></generator> </id> <property name="userName" column="userName"/> <property name="userPwd" column="userPwd"/> <property name="realName" column="realName"/> </class> </hibernate-mapping> <!--Oracle序列增长--> <!--<generator class="squence">--> <!--<param name="squence">SEQ_DEPTNO</param>--> <!--</generator>--> <!--数据库中查询最大值+1--> <!--<generator class="increment"></generator>--> <!--没有制定使用那种方式:需要结合数据库方言自增--> <!--<generator class="native"></generator>--> <!--uuid:生成32位字符串--> <!--<generator class="uuid"></generator>-->
User 实体类:
package com.mlq.bena; import java.io.Serializable; public class User implements Serializable { private Integer uId; private String userName; private String userPwd; private String realName; @Override public String toString() { return "User{" + "uId=" + uId + ", userName='" + userName + '\'' + ", userPwd='" + userPwd + '\'' + ", realName='" + realName + '\'' + '}'; } public Integer getuId() { return uId; } public void setuId(Integer uId) { this.uId = uId; } public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public String getUserPwd() { return userPwd; } public void setUserPwd(String userPwd) { this.userPwd = userPwd; } public String getRealName() { return realName; } public void setRealName(String realName) { this.realName = realName; } }
BaseDao 层:
package com.mlq.bena; import com.mlq.uitl.SessionTool; import org.hibernate.Session; /** * 获取连接的提升封装 * @author asus */ public class BaseDao { public Session getSession() { return SessionTool.getSession(); } }
mapper 层:
package com.mlq.mapper; import com.mlq.bena.User; import javax.jws.soap.SOAPBinding; import java.io.Serializable; /** * @author asus */ public interface UserMapper { /** * 添加方法 * @param user */ public void addUser(User user); /** * 根据Id查询 * @param id * @return */ public User getUser(Serializable id); /** * 根据Id查询 * @param id * @return */ public User loadUser(Serializable id); /** * 修改用户信息:非动态更新 * 指的是在 映射文件中修改:dynamic-update="false":默认非动态更新 * @param user */ public void updateUser(User user); /** * 修改用户信息:动态更新 * 指的是在 映射文件中修改:dynamic-update="false":默认非动态更新 * @param user */ public void mergeUser(User user); /** * 删除用户信息:需要首先调用查询方法 * @param id */ public void delUser(Serializable id); /** * 删除用户信息:根据自己定义的对象信息删除 * @param user */ public void delUser1(User user); /** * 当传递的 user 主键不生效的时便执行save方法 * @param user */ public void saveUpdate(User user); /** * 可以实现更新 也可以实现 save保存 同样根据主键是否有效 * 当主键不生效的时候变执行的是 save保存 * @param user * @return */ public User testMerge(User user); }
mapperImpl:
package com.mlq.mapper; import com.mlq.bena.BaseDao; import com.mlq.bena.User; import com.mlq.uitl.SessionTool; import org.hibernate.Session; import java.io.Serializable; /** * @author asus */ public class UserMapperImpl extends BaseDao implements UserMapper { private Session session=null; @Override public void addUser(User user) { session= super.getSession(); session.save(user); } @Override public User getUser(Serializable id) { session= super.getSession(); return (User) session.get(User.class,id); } @Override public User loadUser(Serializable id) { session= super.getSession(); return (User) session.load(User.class,id); } @Override public void updateUser(User user) { session= super.getSession(); session.update(user); } @Override public void mergeUser(User user) { session= super.getSession(); session.merge(user); } @Override public void delUser(Serializable id) { session= super.getSession(); session.delete(this.loadUser(id)); } @Override public void delUser1(User user) { session= super.getSession(); session.delete(user); } @Override public void saveUpdate(User user) { session= super.getSession(); session.saveOrUpdate(user); } @Override public User testMerge(User user) { session= super.getSession(); User merge = (User)session.merge(user); return merge; } }
service 层:
package com.mlq.seivice; import com.mlq.bena.User; import java.io.Serializable; /** * @author asus */ public interface UserService { /** * 添加方法 * @param user */ public void addUser(User user); /** * 根据Id查询 * @param id * @return */ public User getUser(Serializable id); /** * 根据Id查询 * @param id * @return */ public User loadUser(Serializable id); /** * 数据更新 * @param user */ public void updUser(User user); /** * 非动态更新数据,会给所有字段赋值 * 指的是在 映射文件中修改:dynamic-update="false":默认非动态更新 * @param user */ public void updateUser(User user); /** * 修改用户信息:动态更新 * 指的是在 映射文件中修改:dynamic-update="false":默认非动态更新 * @param user */ public void mergeUser(User user); /** * 删除用户信息:需要首先调用查询方法 * @param id */ public int delUser(Serializable id); /** * 删除用户信息:根据自己定义的对象信息删除 * @param user */ public int delUser1(User user); /** * 当传递的 user 主键不生效的时便执行save方法 * @param user */ public void saveUpdate(User user); /** * 可以实现实现 更新 也可以实现 save保存 同样根据主键是否有效 * @param user * @return */ public User testMerge(User user); }
service impl:
package com.mlq.seivice.impl; import com.mlq.bena.User; import com.mlq.mapper.UserMapper; import com.mlq.mapper.UserMapperImpl; import com.mlq.seivice.UserService; import com.mlq.uitl.SessionTool; import com.sun.xml.internal.ws.handler.HandlerException; import org.hibernate.Transaction; import java.io.Serializable; /** * 实现数据查询 * @author asus */ public class UserServiceImpl implements UserService { Transaction transaction=null; private UserMapperImpl userMapper=null; @Override public void addUser(User user) { try{ userMapper=new UserMapperImpl(); transaction=userMapper.getSession().beginTransaction(); userMapper.addUser(user); transaction.commit(); }catch (HandlerException e) { e.printStackTrace(); transaction.rollback(); } } @Override public User getUser(Serializable id) { User user=null; try{ userMapper=new UserMapperImpl(); transaction=userMapper.getSession().beginTransaction(); user = userMapper.getUser(id); transaction.commit(); }catch (HandlerException e) { e.printStackTrace(); transaction.rollback(); } return user; } @Override public User loadUser(Serializable id) { User user=null; try{ userMapper=new UserMapperImpl(); transaction=userMapper.getSession().beginTransaction(); user = userMapper.loadUser(id); System.out.println(user+"-----------"); transaction.commit(); }catch (Exception e) { System.out.println("相爱相杀一场!!!"); e.printStackTrace(); transaction.rollback(); } return user; } @Override public void updUser(User user) { try{ userMapper=new UserMapperImpl(); transaction=userMapper.getSession().beginTransaction(); User info = userMapper.loadUser(user.getuId()); info.setUserName(user.getUserName()); info.setUserPwd(user.getUserPwd()); info.setRealName(user.getRealName()); transaction.commit(); }catch (Exception e) { System.out.println("相爱相杀一场!!!"); e.printStackTrace(); transaction.rollback(); } } @Override public void updateUser(User user) { try{ userMapper=new UserMapperImpl(); transaction=userMapper.getSession().beginTransaction(); userMapper.updateUser(user); transaction.commit(); }catch (Exception e) { System.out.println("相爱相杀一场!!!"); e.printStackTrace(); transaction.rollback(); } } @Override public void mergeUser(User user) { try{ userMapper=new UserMapperImpl(); transaction=userMapper.getSession().beginTransaction(); userMapper.mergeUser(user); transaction.commit(); }catch (Exception e) { System.out.println("相爱相杀一场!!!"); e.printStackTrace(); transaction.rollback(); } } @Override public int delUser(Serializable id) { int count=0; try{ userMapper=new UserMapperImpl(); transaction=userMapper.getSession().beginTransaction(); userMapper.delUser(id); transaction.commit(); count= 1; }catch (Exception e) { System.out.println("相爱相杀一场!!!"); count=0; e.printStackTrace(); transaction.rollback(); } return count; } @Override public int delUser1(User user) { int count=0; try{ userMapper=new UserMapperImpl(); transaction=userMapper.getSession().beginTransaction(); userMapper.delUser1(user); transaction.commit(); count= 1; }catch (Exception e) { System.out.println("相爱相杀一场!!!"); count=0; e.printStackTrace(); transaction.rollback(); } return count; } @Override public void saveUpdate(User user) { try{ userMapper=new UserMapperImpl(); transaction=userMapper.getSession().beginTransaction(); userMapper.saveUpdate(user); transaction.commit(); }catch (Exception e) { System.out.println("相爱相杀一场!!!"); e.printStackTrace(); transaction.rollback(); } } @Override public User testMerge(User user) { User user1=null; try{ userMapper=new UserMapperImpl(); transaction=userMapper.getSession().beginTransaction(); user1 = userMapper.testMerge(user); transaction.commit(); }catch (Exception e) { System.out.println("相爱相杀一场!!!"); e.printStackTrace(); transaction.rollback(); } return user1; } }
uitl 获取连接工具类:
package com.mlq.uitl; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.cfg.Configuration; /** * 读取配置信息 */ public class SessionTool { private static SessionFactory sessionFactory=null; private static Configuration configuration=null; static { System.out.println("静态代码块------"); configuration=new Configuration().configure(); sessionFactory=configuration.buildSessionFactory(); } public static Session getSession() { return sessionFactory.getCurrentSession(); } }
测试类:
package com.mlq; import com.mlq.bena.User; import com.mlq.seivice.impl.UserServiceImpl; import org.junit.Test; /** * 提取工具类的测试 */ public class HibernateDemo { /** * get()查询 */ @Test public void getUser() { User user = new UserServiceImpl().getUser(42183); System.out.println(user); } /** * load()查询 */ @Test public void loadUser() { new UserServiceImpl().loadUser(42); } /** * 更新操作 */ @Test public void updUser() { User user=new User(); user.setuId(42183); user.setUserName("aaa"); user.setUserPwd("bbb"); user.setRealName("vvv"); new UserServiceImpl().updUser(user); } //------------------动态与非动态注意查看 控制台打印的 SQL-------------------------------// /** * 更新操作:非动态更新 */ @Test public void updatedUser() { User user=new User(); user.setuId(42183); user.setUserName("aaa"); user.setUserPwd("bcb"); user.setRealName("vbv"); new UserServiceImpl().updateUser(user); } /** * 更新操作2:动态更新 */ @Test public void mergeUser() { User user=new User(); user.setuId(42184); user.setUserName("aaa"); user.setUserPwd("bcb"); user.setRealName("vbbbv"); new UserServiceImpl().mergeUser(user); } /** * 删除用户信息:需要根据查询来获取用户对象 然后删除 */ @Test public void deleteUser() { int i = new UserServiceImpl().delUser(43420); System.out.println((i>0)?"删除成功":"删除失败"); } /** * 删除用户信息:根据自己定义的对象删除 */ @Test public void deleteUser1() { User user=new User(); user.setuId(43417); int i = new UserServiceImpl().delUser1(user); System.out.println((i>0)?"删除成功":"删除失败"); } //当传递的 user 主键不生效的时便执行save方法 @Test public void saveUpdate() { User user=new User(); user.setuId(42183); user.setUserName("修改了"); new UserServiceImpl().saveUpdate(user);//执行了Update方法更新 } //当传递的 user 主键不生效的时便执行save方法 @Test public void saveUpdate1() { User user=new User(); user.setUserName("修改了"); new UserServiceImpl().saveUpdate(user);//执行了save方法更新 } //当传递的 user 主键不生效的时便执行save方法,否则施行更新 @Test public void textMerge() { User user=new User(); user.setUserName("Merge正在执行保存!!!"); User user1 = new UserServiceImpl().testMerge(user);//执行了save方法更新 System.out.println(user1); } @Test public void textMerge1() { User user=new User(); user.setuId(42183); user.setUserName("原来的模样"); User user1 = new UserServiceImpl().testMerge(user);//执行了更新方法更新 System.out.println(user1); } }