zoukankan      html  css  js  c++  java
  • 【hibernate】<第一节>hibernate简单入门

    所需工具:


    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-disthibernate-distribution-3.6.0.Finalprojectetchibernate.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, 1);
    	}
    
    	@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);
    		}
    	}
    
    }
    


    谢谢观看!奋斗

  • 相关阅读:
    start tag, end tag issues in IE7, particularly in xslt transformation
    用SandCastle为注释生成chm文档
    Firebug
    架构的重点
    Linux Shell常用技巧(十) 管道组合
    Linux JDK升级
    Linux Shell常用技巧(十二) Shell编程
    Packet Tracer 5.0实验(一) 交换机的基本配置与管理
    Linux Shell常用技巧(六) sort uniq tar split
    Linux Shell常用技巧(二) grep
  • 原文地址:https://www.cnblogs.com/kiwifly/p/4435861.html
Copyright © 2011-2022 走看看