dorado hibernate

本文介绍了Dorado如何与Hibernate整合,包括SessionFactory与Session的区别,Dorado中的Session管理,实体类与数据库表的映射,以及Dorado中使用Hibernate的配置和操作,如保存数据、查询列表,并提到了原生SQL的addEntity和setResultTransformer方法的使用注意事项。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. hibernate

1.0 SessionFactory、Session、openSession()、getCurrentSession()

hibernate中

  1. SessionFactory 负责创建 Session,SessionFactory 是线程安全的,多个并发线程可以同时访问一个SessionFactory 并从中获取 Session 实例,项目中只有一个sessionFactory。

  2. Session是后台和数据库的一次交互,并非线程安全,所以要在当前线程中获取session。使用sf.getCurrentSession()。

  3. sf.openSession();//创建新的session

  4. sf.getCurrentSession();//获取当前线程的session,如果不存在,会自动创建。

  • 需要在hibernate.cfg.xml中添加:
   <propety name="Hibernate.current_session_context_class">thread</propety>
  • 并当事务结束的时候【提交or回滚事务】自动关闭session,不需要手动写session.close();

  • 此时session所有的crud都需要事务

dorado中

sessionFactory:dorado去负责创建和关闭。

1.1 映射表到实体类

hibernate.cfg.xml+配置
配置有两种方法:xml配置和注解配置

  1. xml配置:在Entity.hbm.xml中配置表和实体类的映射
  2. 注解配置(dorado采用):在实体类中进行注解,dorado可自动进行从数据库表到带有注解的实体类转换
    hibernate.cfg.xml【放在src目录下,如果maven项目,放在src/main/resource目录下】
<?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核心配置文件 -->
	<hibernate-configuration>
		<!-- 配置hibernate数据源连接 -->
		<session-factory>
			<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
			<property name="hibernate.connection.url">jdbc:mysql://localhost:8080/project</property>
			<property name="hibernate.connection.username">root</property>
			<property name="hibernate.connection.password">root</property>
			
			<!-- 配置数据库方言 -->
			<property name="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</property>
			<!-- 配置sql打印、格式化 -->
			<property name="hibernate.show_sql">true</property>
			<property name="hibernate.format_sql">true</property>
			
			<!-- 配置hibernate映射文件位置 xml方式 <mapping resource="com/公司名/项目名/entity/User.hbm.xml"/>-->
			<!-- 配置hibernate映射 注解方式 -->
			<mapping class="com.公司名.项目名.entity.User"></mapping>
			
		</session-factory>
	</hibernate-configuration>

1.2 hibernate的使用

SessionFactory sf = new Configuration().configure().buildSessionFactory();
		Session s= sf.openSession();
		s.beginTransaction();
		/*
		hql:获取List<实体类>
		sql:获取List<Object[]>
		String hql = "from User where id=12";
		List<User> = s.createQuery(hql).list();
		/*
​		String sql = "select name,avg(age) from user where groupby name="hua"";
​		List<Object[]> list = s.createSQLQuery(sql).list();
​		for (Object[] os : list) {
​            for (Object filed: os) {
​                System.out.print(filed+"\t");
​            }
​            System.out.println("\n");
​        }

​		s.getTransaction().commit();
​        s.close();
​        sf.close();

1.3 dorado中hibernate的映射

原生的hibernate需要:hibernate.cfg.xml+配置
在dorado中使用hibernate需要:

  1. hibernate.cfg.xml。dorado不使用hibernate.cfg.xml,而是把相关配置放在dorado-home中的app-context文件中。
  2. 采用注解配置。在实体类中进行注解,dorado可自动进行从数据库表到带有注解的实体类转换

1.4 dorado中hibernate的使用

1. 复杂查询。使用原生的hibernate的sql,此时要手动启动hibernate
2. 增删改以及获取实体类的简单查询。使用dorado的封装hibernate(只能使用hql:不操作数据库,操作的是类对象)
dorado在web项目运行后会自动加载app-context的内容,自动启动hibernate

1.4.0 dorado使用原生hibernate的sql需要:hibernate.cfg.xml+注解配置

hibernate.cfg.xml放在src根目录下,如果maven项目,放在src/main/resource目录下
hibernate.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核心配置文件 -->
	<hibernate-configuration>
		<!-- 配置hibernate数据源连接 -->
		<session-factory>
			<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
			<property name="hibernate.connection.url">jdbc:mysql://localhost:8080/project</property>
			<property name="hibernate.connection.username">root</property>
			<property name="hibernate.connection.password">root</property>
			
			<!-- 配置数据库方言 -->
			<property name="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</property>
			<!-- 配置sql打印、格式化 -->
			<property name="hibernate.show_sql">true</property>
			<property name="hibernate.format_sql">true</property>
			
			<!-- 配置hibernate映射 注解方式 -->
			<mapping class="com.公司名.项目名.entity.User"></mapping>
			
		</session-factory>
	</hibernate-configuration>

1.4.1 保存数据到数据库


	@DataResolver
    @Transactional
	public void saveCompany(Collection<SlCompany> slCompanys) {
		//存入数据库,新建账户和用户
		Account account = new Account();
		account.setStatus(Const.STATUS_OK);
		account.setCompany(company);
		account.setBalance(Const.ACCOUNT_BALANCE_ZERO);
		//变成Entity
		account = EntityUtils.toEntity(account);
		//添加状态,是添加还是删除
		EntityUtils.setState(account, EntityState.NEW);
		//添加到数据库
		accountDao.save(account);
		
		//修改,新建,移动就是save,删除为delete
		for(SlCompany o: slCompanys) {
			//从dorado前端传过来的数据可直接EntityUtils.getState(o),否则先把o变成Entity
			//o = EntityUtils.toEntity(o);EntityUtils.setState(o, EntityState.MODIFIED);
			if(EntityState.DELETED.equals(EntityUtils.getState(o))){
				slCompanyDao.delete(o);
			}
			slCompanyDao.save(o);
		}
		//先查看各对象的状态,再进行处理
//		slCompanyDao.persistEntities(slCompanys);

//HibernateDao.persistEntities
@SuppressWarnings("unchecked")
public int persistEntities(Collection<T> entities) {
    int i = 0;
    for (Object entity : EntityUtils.getIterable(entities,
            FilterType.DELETED)) {
        delete((T) entity);
        i++;
    }
    for (Object entity : EntityUtils.getIterable(entities,
            FilterType.MODIFIED)) {
        save((T) entity);
        i++;
    }
    for (Object entity : EntityUtils
            .getIterable(entities, FilterType.MOVED)) {
        save((T) entity);
        i++;
    }
    for (Object entity : EntityUtils.getIterable(entities, FilterType.NEW)) {
        save((T) entity);
        i++;
    }
    return i;
}
//
public static Iterator getIterator(Collection entities, FilterType filterType)
	{
		return new EntityIterator(entities, filterType);
	}
//
public EntityIterator(Collection entities, FilterType filterType)
	{
		iterator = entities.iterator();
		this.filterType = filterType;
		findNext();
	}

	protected void findNext()
	{
		if (iterator.hasNext())
		{
			currentEntity = iterator.next();
			if (currentEntity != null)
			{
				boolean visible = false;
				EntityState state = EntityUtils.getState(currentEntity);
				if (filterType == FilterType.NONE)
					visible = state == EntityState.NONE;
				else
				if (filterType == FilterType.NEW)
					visible = state == EntityState.NEW;
				else
				if (filterType == FilterType.MODIFIED)
					visible = state == EntityState.MODIFIED;
				else
				if (filterType == FilterType.DELETED)
					visible = state == EntityState.DELETED;
				else
				if (filterType == FilterType.MOVED)
					visible = state == EntityState.MOVED;
				else
				if (filterType == FilterType.VISIBLE)
					visible = state != EntityState.DELETED;
				else
				if (filterType == FilterType.DIRTY)
					visible = state == EntityState.NEW || state == EntityState.MODIFIED || state == EntityState.DELETED || state == EntityState.MOVED;
				else
				if (filterType == FilterType.VISIBLE)
					visible = state == EntityState.NEW || state == EntityState.MODIFIED || state == EntityState.MOVED;
				else
				if (filterType == FilterType.ALL)
					visible = true;
				if (visible)
					hasNext = true;
				else
					findNext();
			} else
			{
				hasNext = false;
			}
		} else
		{
			hasNext = false;
		}
	}

//
	public static EntityState getState(Object entity)
	{
		EntityEnhancer entityEnhancer = getEntityEnhancer(entity);
		if (entityEnhancer != null)
			return entityEnhancer.getState();
		else
			return EntityState.NONE;
	}
	//
public static EntityEnhancer getEntityEnhancer(Object entity)
	{
	//从dorado前端传过来的如果没有经过任何处理,不是EnhanceableEntity
		if (entity instanceof EnhanceableEntity)
		{
			EnhanceableEntity enhanceableEntity = (EnhanceableEntity)entity;
			return enhanceableEntity.getEntityEnhancer();
		}
		//从dorado前端传过来的如果没有经过任何处理,是ProxyBeanUtils
		if (ProxyBeanUtils.isProxy(entity))
		{
			MethodInterceptorDispatcher dispatcher = ProxyBeanUtils.getMethodInterceptorDispatcher(entity);
			if (dispatcher != null)
			{
				org.aopalliance.intercept.MethodInterceptor mis[] = dispatcher.getSubMethodInterceptors();
				org.aopalliance.intercept.MethodInterceptor arr$[] = mis;
				int len$ = arr$.length;
				for (int i$ = 0; i$ < len$; i$++)
				{
					org.aopalliance.intercept.MethodInterceptor mi = arr$[i$];
					if (mi instanceof EntityEnhancer)
						return (EntityEnhancer)mi;
						//mi.getState()
				}

			}
		}
		return null;
	}

1.4.2 查询得到List<实体类>

find(hql);
/此时SlMessage表中有外键sender关联到SlEmployee的employeeId字段,但是Hibernate在生成实体类时,没有成员变量sender,有成员变量slEmployee【SlEmployee类型】,所以使用SlMessage中的slEmployee的employeeId代替sender进行查询
String hql = "from SlMessage where slEmployee.employeeId = ?";
slMessageDao.find(page,hql,employeeId);

//部门是递归的,部门下有部门,顶端的部门没有所属部门,所以设为null,SlDept有外键parentId关联到SlDept的deptId字段,利用关联的字段进行查询
slDeptDao.find("from SlDept where slDept.deptId is null");//查找顶端的

slEmployeeDao.find("from SlEmployee where userName = '"+userName+"'");
slEmployeeDao.find(page, " from SlEmployee where 1=1 " + " AND name like '%li%' ");
slEmployeeDao.find("from SlEmployee where userName = ?",userName);
return slEmployeeDao.find("from SlEmployee where userName = ?",new Object[]{userName});
slEmployeeDao.find("from SlEmployee where userName = :userName",map);//map.get("userName")

DetachedCriteria dc = DetachedCriteria.forClass(SlEmployee.class);
if (username != null && !"".equals(username)) {
   dc.add(Restrictions.eq("userName", username.toUpperCase()));
}
List<SlEmployee> employees = slEmployeeDao.find(dc);

//多个参数
slEmployeeDao.find("from SlEmployee where userName = ? and 1=?",userName,one);
slEmployeeDao.find("from SlEmployee where userName = ? and 1=?",new Object[]{"myName",1});
param.put("one", 1);
param.put("userName", "myName");
slEmployeeDao.find("from SlEmployee where userName = :userName and 1=:one",param);


原生sql的addEntity和setResultTransformer

使用原生 sql 语句进行 query 查询时,hibernate 是不会自动把结果包装成实体,可通过addEntity和setResultTransformer

addEntity

查找结果为:有表对应的实体类,需要:

  1. 在hibernate.cfg.xml中配置<mapping class="com.entity.User"></mapping>
  2. 实体类经过dorado的自动编写hibernate注解
Stirng sql = "select * from user";
Query q = s.createSQLQuery(sql).addEntity(User.class);
List<User> list = q.list();

setResultTransformer

查找结果为:无表对应的类,要求:
public class Demo(){//类为public
//有参无参构造函数为public
public Demo(){};

}

String sql = "selest name,age from user";
Query q = s.createSQLQuery(sql)
	.addScalar("name",StandardBasicTypes.STRING)
	.addScalar("age",StandardBasicTypes.INTEGER)
	.setResultTransformer(Transformers.aliasToBean(Demo.class));
List<Demo> list = q.list();	

dorado中使用hibernate

测试

先在hibernate.cfg.xml 中添加注解:<mapping class=“com.entity.Account”></mapping>

		SessionFactory sf = new Configuration().configure().buildSessionFactory();
		Session s= sf.getCurrentSession();//获取当前线程的session,没有的话,创建,会自动关闭session
		s.beginTransaction();//开启事务
		String sql = "select * from user";
		List<Object[]> list = s.createSQLQuery(sql).list();
		//List<User> list = s.createSQLQuery(sql).addEntity(User.class).list();
		/* 
		String sql = "select * from user where name=? and id=?";
		Ojbect[] params = new Object[]{"aini",1};
		Query query = s.createSQLQuery(sql).addEntity(User.class)
		if (params != null) {
            if (params.length > 0) {
                for (int i = 0; i < params.length; i++) {
                	//两种传参方式
                	//hql="select * from user where id=:myId"
                	//query.setParameter("myId",id);
                    query.setParameter(i, params[i]);
                }
            }
        }
        List<User> list = q.list();
		*/
		/*
		in的两种使用
		1. in的数据需要从其他表中获取
		String hql="from A a where a.id in (select b.aId from B b where b.name=?)";
		Query query = session.createQuery(hql);
     List<A> list = query.setParameter(0, name);
		2. in的数据已知
		String hql="from A a where a.id in (:myList)";
		Query query = session.createQuery(hql);
     List<A> list = query.setParameterList("myList", List/数组);
		/
		for (Object[] os : list) {
            for (Object filed: os) {
                System.out.print(filed+"\t");
            }
            System.out.println("\n");
        }
		s.getTransaction().commit();//提交事务
//        s.close(); getCurrentSession()会自动进行session的关闭
        sf.close();//服务器被关闭,程 序被卸载时关闭

web项目

//sessionFactory的创建和关闭dorado负责,不关心
//只是复杂查询得到List<Object[]>是用得到HelpDao,其他都用原来的
//HelpDao
@Repository
public class HelpDao extends HibernateDao {

	
	public List find(String sql){
		return getSession().createSQLQuery(sql).list();
	}
	public List find(String sql, Class entity){
		return getSession().createSQLQuery(sql).addEntity(entity).list();
	}
	public List find(String sql,Object params[]){
		Query query = getSession().createSQLQuery(sql);
		if (params != null) {
            if (params.length > 0) {
                for (int i = 0; i < params.length; i++) {
                    query.setParameter(i, params[i]);
                }
            }
        }
		return query.list();
	}
	public List find(String sql, Class entity, Object params[]){
		Query query = getSession().createSQLQuery(sql).addEntity(entity);
		if (params != null) {
            if (params.length > 0) {
                for (int i = 0; i < params.length; i++) {
                    query.setParameter(i, params[i]);
                }
            }
        }
		return query.list();
	}
}
public class Service{
	@Resource
	private HelpDao helpDao;
	String sql = "select * from user";
	List<User> list = helpDao.find(sql,User.class);
	List<Object[]> list2 = helpDao.find(sql);
	for (Object[] os : list2) {
          for (Object o: os) {
              System.out.print(o+"\t");
          }
          System.out.println("\n");
      }
	String sql2 = "select * from user where name=? and id=?";
	List<User> list3 = helpDao.fin(sql2,User.class,new Ojbect[]{"lian",1});
	List<Object[]> list4 = helpDao.find(sql2,new Ojbect[]{"lian",1});
}

注意

注解的@Entity

导包:javax.persistence.Entity
不推荐使用:org.hibernate.annotations.Entity //会出错

无法保存或更新或删除

原因:没有在方法上使用@Transactional

复杂查询 在web中

使用sql,但分页麻烦

String sql="select pm.name packageName,apc.num_left numLeft,apc.package_start_time startTime from APC apc left join PM pm on apc.id1=pm.id where apc.account_id=? and pm.name=?"       
Map<String,Type> map = new HashMap();
map.put("packageName", StandardBasicTypes.STRING);
map.put("numLeft", StandardBasicTypes.INTEGER);
map.put("startTime", StandardBasicTypes.STRING);                                
map.put("statusByte", StandardBasicTypes.BYTE);
List<Pack> list = helpDao.find(sql,Pack.class,new Object[]{accountId,name},map)

使用hql时,方便分页

利用select
//where后
String hql="from A a where a.id in (select b.aId from B b where b.name=?)";
String hql="from A a where a.age > (select b.age from B b where b.name=?)";
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值