所需工具:
ide:eclipse or myeclipse
jdk:1.7
jar包:hibernate-distribution-3.6.0.Final 和对应mysql的驱动类(对应jar包如图)
数据库:mysql 要支持事务的版本,命令行下或用navicat生成如图所示表
项目目录结构如下:
其中cn.kiwifly.entity为实体类包,cn.kiwifly.dao为Dao层包,cn.kiwifly.utils为工具包,cn.kiwifly.test为测试包
学习目标:完成hibernate的基础入门
都准备好了,搞起!
第一步:建立hibernate.cfg.xml,这是hibernate的主配置文件,具体配置已在注释上写的很清楚了,
最后一个<mapping />是配置的最后一步,在完成后面两项后再写的!
<?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> <!-- 配置数据库的别名 --> <!-- 什么是别名?大家都知道hibernate一个重要的优点是可以跨数据库使用,实现这点的原因就在这里,hibernate为每种常见的数据库都 实现了特定的sql语句,比如就分页来说,mysql就是limit语句,而oracle就是恶心的多个select嵌套在一起,但是hibernate本身不 能识别数据库的类型,在这里我们通过设置别名来告诉hibernate使用什么数据库的语句来实现 不同数据库的别名分别是什么? hibernate的包里有一个是常用配置文件,从这里可以查到 Hiberante开发包__hibernate-distribution-3.6.0.Final-dist\hibernate-distribution-3.6.0.Final\project\etc\hibernate.properties --> <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property> <!-- 配置数据库的url地址 --> <property name="hibernate.connection.url">jdbc:mysql:///test</property> <!-- 配置数据库的用户名 --> <property name="hibernate.connection.username">root</property> <!-- 配置数据库的密码 --> <property name="hibernate.connection.password">root</property> <!-- 非必须配置 --> <!-- 是否在控制台打印sql语句,建议开发时打开,发布后关闭 --> <property name="show_sql">true</property> <!-- 格式化控制台打印的sql语句 --> <property name="format_sql">true</property> <!-- hibernate有两种开发流程,一个是先在数据库里建好库,建好表,再写对应的实体类,与对应关系。另一种是按需求直接写实体类与对应关系,再通过hibernate自动 生成对应的数据库里的表。如果想自动生成表就要配置这个hbm2ddl.auto这个属性了,这个属性有好几个值,一般用update,其余的查文档吧 --> <property name="hbm2ddl.auto">update</property> <!-- 添加映射文件 --> <mapping resource="cn/kiwifly/entity/User.hbm.xml"/> </session-factory> </hibernate-configuration>
第二步:写与数据库表对应的实体类User.java
package cn.kiwifly.entity; /* * 写一个与表对应的实体类,类属性与表一一对应 * */ public class User { /*在数据库中id,我们设置的是int类型,在设置实体类属性时,我们也可以设置成int类型 * 但是这里我们要与数据库对应成整型时,最好用Integer类型,因为int是基本 * 类型,它只能为0不能为空,但数据库有些字段是可以为空的,为空用null表示最合适,所以 * 用包装类对应最好 * */ private Integer id; private String name; /******参考id类型*****/ private Integer age; private String sex; /*******实现getter与setter方法*********/ 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; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } /**********最好也同时实现toString方法,便于测试********/ public String toString() { return "User [id=" + id + ", name=" + name + ", age=" + age + ", sex=" + sex + "]"; } }
第三步:写实体类的映射文件User.hbm.xml(这一步完成就可以在hibernate.cfg.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"> <!-- 如果这里不加package,下面如果用类就要写全路径 --> <hibernate-mapping package="cn.kiwifly.entity"> <!-- 把实体类与表对应起来,格式 <class name="实体类" table="对应的表名"> <id name="对应主键的实体类的属性" type="这个属性的类型" column="对应数据库表中的字段"> <generator class="主键的生成策略" /> </id> <property name="对应普通属性的实体类的属性" type="这个普通属性类型" column="对应数据库表中的字段" /> </class> --> <class name="User" table="t_user"> <!-- 这里配置映射表的主键, --> <id name="id" type="java.lang.Integer" column="id"> <generator class="native" /> </id> <property name="name" type="java.lang.String" column="name" /> <property name="age" type="java.lang.Integer" column="age" /> <property name="sex" type="java.lang.String" column="sex" /> </class> </hibernate-mapping>
第四步:写一个封装分页结果的QueryResult类
package cn.kiwifly.entity; import java.util.ArrayList; import java.util.List; /* * 这个类是用来封装,分页查询数据的类,不 是实体类 * */ public class QueryResult { private List<User> userList = new ArrayList<>(); private Long total; public List<User> getUserList() { return userList; } public void setUserList(List<User> userList) { this.userList = userList; } public Long getTotal() { return total; } public void setTotal(Long total) { this.total = total; } public String toString() { return "QueryResult [userList=" + userList + ", total=" + total + "]"; } }
第五步:写一个用来获取Session对象的工具类,HibernateUtil.java
package cn.kiwifly.utils; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.cfg.Configuration; /* * 一个简单的hibernate工具类,主要作用是,可以返回一个session对象,为什么要用hibernate工具类获取?而不是直接在代码里获取 * 因为SessionFactory是一个重量级的类,如果不停的获得,释放,会很占资源,一个应用一般一个SessionFactory对象就够了 * */ public class HibernateUtil { private static SessionFactory sessionFactory; static { sessionFactory = new Configuration()// .configure()// .buildSessionFactory(); } public static Session getSession(){ return sessionFactory.openSession(); } }
第六步:写UserDao.java来实现,增删改查分页等方法
package cn.kiwifly.dao; import java.util.List; import org.hibernate.Query; import org.hibernate.Session; import org.hibernate.Transaction; import cn.kiwifly.entity.QueryResult; import cn.kiwifly.entity.User; import cn.kiwifly.utils.HibernateUtil; public class UserDao { public void add(User user) { // 首先要获取session对象,它是所有操作的根本 Session session = HibernateUtil.getSession(); // 开启事务 Transaction tx = session.beginTransaction(); try { // 调用hibernate封装好save方法把对象存入数据库中,在hibernate中一个类对应数据库库中一张表 // 一个对象对应数据库中表中的一条记录 session.save(user); // 提交记录 tx.commit(); } catch (Exception e) { // 如果有任何异常就回滚 tx.rollback(); // 这里没有对异常进行处理,一定要抛出去,不然永远不知道,问题出在哪 throw e; } finally { // 用完session一定要记得释放 session.close(); } } public void delete(Integer id) { Session session = HibernateUtil.getSession(); // 开启事务 Transaction tx = session.beginTransaction(); try { // 首先要通过id获取数据库里对应的记录的对象 User user = (User) session.get(User.class, 1); // 再通过hibernate封装好的,delete方法,来删除记录 session.delete(user); // 提交记录 tx.commit(); } catch (Exception e) { // 如果有任何异常就回滚 tx.rollback(); // 这里没有对异常进行处理,一定要抛出去,不然永远不知道,问题出在哪 throw e; } finally { // 用完session一定要记得释放 session.close(); } } public void update(User user) { Session session = HibernateUtil.getSession(); // 开启事务 Transaction tx = session.beginTransaction(); try { // 首先要通过id获取数据库里对应的记录的对象 User oldUser = (User) session.get(User.class, user.getId()); // 再通过对象的setter方法来修改,对象的值 oldUser.setAge(user.getAge()); oldUser.setName(user.getName()); oldUser.setSex(user.getSex()); // 再通过hibernate封装好的update方法,来修改记录 session.update(oldUser); // 提交记录 tx.commit(); } catch (Exception e) { // 如果有任何异常就回滚 tx.rollback(); // 这里没有对异常进行处理,一定要抛出去,不然永远不知道,问题出在哪 throw e; } finally { // 用完session一定要记得释放 session.close(); } } public User findById(Integer id) { // 直接调用session的get方法就可以了 return (User) HibernateUtil.getSession().get(User.class, id); } @SuppressWarnings("unchecked") public List<User> findAll() { Session session = HibernateUtil.getSession(); // 如果要获取全部的记录,那么hibernate封装的方法就没有直接可以使用的了,所以我要创建一个查询 //注意:1、如果前面是SELECT * 可以省略不写2、FROM 后面跟的不是表名,是与表映射的实体类名 Query query = session.createQuery("FROM User"); // 它有一个list()方法可以直接把结果转成list类型,这个真爽 //这里如果用eclipse会警告,不影响使用,我一直没搞清楚这里的警告是为什么?如有大神知道,麻烦告诉一下,谢谢 List<User> userList = query.list(); return userList; } @SuppressWarnings("unchecked") public QueryResult findAllByPage(int firstResult, int maxResults) { Session session = HibernateUtil.getSession(); //创建用于封装结果的QueryResult对象 QueryResult queryResult = new QueryResult(); // 复杂的查询就要用自己写sql // hibernate对分页有封装好的方法,setFirstResult是设置起始页,setMaxResults是设置一页显示的数量 List<User> userList = session.createQuery("FROM User")// .setFirstResult(firstResult)// .setMaxResults(maxResults)// .list(); // 分页还需要知道总的记录数 Long total = (Long) session.createQuery("SELECT COUNT(ID) FROM User").uniqueResult(); //装载数据 queryResult.setUserList(userList); queryResult.setTotal(total); return queryResult; } }
第七步:测试UserDao
package cn.kiwifly.test; import java.util.Iterator; import java.util.List; import org.junit.Test; import cn.kiwifly.dao.UserDao; import cn.kiwifly.entity.QueryResult; import cn.kiwifly.entity.User; public class UserDaoTest { @Test public void testAdd() { User user = new User(); user.setName("小明"); user.setAge(88); user.setSex("男"); UserDao userDao = new UserDao(); userDao.add(user); } @Test public void testDelete() { new UserDao().delete(1); } @Test public void testUpdate() { User user = new User(); user.setId(1); user.setName("小红"); user.setAge(99); user.setSex("女"); new UserDao().update(user); } @Test public void testFindById() { User user = new UserDao().findById(1); System.out.println(user); } @Test public void testFindAll() { List<User> userList = new UserDao().findAll(); for (Iterator<User> iterator = userList.iterator(); iterator.hasNext();) { User user = (User) iterator.next(); System.out.println(user.getName()); } } @Test public void testFindAllByPage() { QueryResult queryResult = new UserDao().findAllByPage(10, 10); List<User> userList = queryResult.getUserList(); Long total = queryResult.getTotal(); System.out.println("总共有"+total+"条记录"); for (User user : userList) { System.out.println(user.getName()); } } @Test public void testAddUses(){ UserDao userDao = new UserDao(); for(int i = 0; i < 30; i++){ User user = new User(); user.setName("张"+i); userDao.add(user); } } }
谢谢观看!