• 【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);
    		}
    	}
    
    }
    


    谢谢观看!奋斗

  • 相关阅读:
    ACM题集以及各种总结大全
    ACM题集以及各种总结大全
    线段树题集
    线段树题集
    POJ 1159 Palindrome【LCS+滚动数组】【水题】
    POJ 1159 Palindrome【LCS+滚动数组】【水题】
    开课博客
    第一周学习进度
    开学测试
    寒假总结
  • 原文地址:https://www.cnblogs.com/kiwifly/p/4435861.html
Copyright © 2020-2023  润新知