代理模式--动态(事务代理的例子)

本文详细介绍了在Tomcat中配置数据库,使用JPA的persistence.xml文件进行持久化单元配置,并通过自定义EntityManager工具类实现数据库连接的动态切换。同时,阐述了如何在service调用中通过代理类ServiceBaseProxy引入事务管理,确保数据库操作的正确性和一致性。

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

在tomcat的server.xml配置数据库:

 <Context path="/crm" docBase="/crm"  reloadable="false" crossContext="true">  <!-- 第一个path指web访问地址时的虚拟项目名(一般跟项目名一样),docBase指项目的实际物理地址-->
  	
			<Resource   name="jdbc/crm"   auth="Container"   type="javax.sql.DataSource"  
				 maxActive="10"   maxIdle="2"   maxWait="10000"  removeAbandoned="true" removeAbandonedTimeout="60" logAbandoned="true"
				 username="xxx"   password="xxxx"  
				 driverClassName="net.sourceforge.jtds.jdbc.Driver"  
				 url="jdbc:jtds:sqlserver://x.x.x.x:x;DatabaseName=x"/>  

			<Resource   name="jdbc/dhyx_ivr"   auth="Container"   type="javax.sql.DataSource"  
				 maxActive="4"   maxIdle="2"   maxWait="10000"  removeAbandoned="true" removeAbandonedTimeout="60" logAbandoned="true"
				 username="xxx"   password="xxx"  
				 driverClassName="oracle.jdbc.OracleDriver"  
				 url="jdbc:oracle:thin:@x.x.x.x:x:x"/>		
				 
 </Context>

 

 

在JPA 的配置文件persistence.xml中:

<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
	version="2.0">
	<persistence-unit name="sqlserver" transaction-type="RESOURCE_LOCAL">
		<provider>org.hibernate.ejb.HibernatePersistence</provider>

		<jta-data-source>java:comp/env/jdbc/crm</jta-data-source>  //引用tomcat的server.xml配置的数据对应的Resourcename
		
		<class>com.user.model.Userinfo</class>
				
		。。。。。。
		
		<properties>
			<property name="hibernate.dialect" value="org.hibernate.dialect.SQLServerDialect"></property>
			<property name="hibernate.show_sql" value="false"></property>
		</properties>
	</persistence-unit>
	
	<persistence-unit name="oracle" transaction-type="RESOURCE_LOCAL">
	
		<provider>org.hibernate.ejb.HibernatePersistence</provider>

		<jta-data-source>java:comp/env/jdbc/dhyx_ivr</jta-data-source>//引用tomcat的server.xml配置的数据对应的Resourcename

		
       	<class>com.userMessage.model.Usermessage</class>
		
		。。。。。。		
		<properties>
		 	<property name="hibernate.dialect" value="org.hibernate.dialect.OracleDialect"></property> 
			<property name="hibernate.show_sql" value="false"></property> 
		</properties>
		
	</persistence-unit>
</persistence>

 在util包中创建获得EntityManager工具类:

public class HibernateEntityManager {
	 public static final ThreadLocal entityManager = new ThreadLocal();
	 private static EntityManagerFactory emf = null;
	 private static EntityManagerFactory emf_oracle = null;
		 public static void initDatabase()
	 {
		 try
			{
			 emf = Persistence.createEntityManagerFactory("sqlserver");
			}catch(Exception e)
			{
				e.printStackTrace();
			}
			
			try
			{
				emf_oracle = Persistence.createEntityManagerFactory("oracle");
			}catch(Exception e)
			{
				e.printStackTrace();
			}
			
	 }
		 public static void closeCurrentEm()
	 {
		 EntityManager em1 = (EntityManager)entityManager.get();
		 if(em1!=null)
		 {
			 em1.close();
		 }
		 entityManager.set(null);
	 }
	 
	 public static EntityManager getEm(int databaseType)
		{
		 EntityManager em1 = null;
		 if(databaseType==1)
		 {
			  em1 = (EntityManager)entityManager.get();
				if(em1==null)
				{
					em1 = emf.createEntityManager();
					entityManager.set(em1);
				}
		 }
		 else if(databaseType==2)
		 {
			  em1 = (EntityManager)entityManager.get();
				if(em1==null)
				{
					em1 = emf_oracle.createEntityManager();
					entityManager.set(em1);
				}
		 }
			
			return em1;
		}

action调用service的方式:

UserServiceInter userService =(UserServiceInter)ServiceFactory.getUserService();

ServiceFactory类中中的getUserService方法:

 public static UserServiceInter getUserService() {
  UserService g = new UserService();   //new出一个具体要让代理的service对象
  return (UserServiceInter) ServiceBaseProxy.newInstance(g);//通过代理就会在执行原方法前后添加所需的逻辑
 }

ServiceBaseProxy类:

public class ServiceBaseProxy implements InvocationHandler {

	private Object obj;
	private int datebaseType = 1;

	public static Object newInstance(Object obj) {
		// 返回一个指定接口的代理类实例,该接口可以将方法调用指派到指定的调用处理程序。
		return java.lang.reflect.Proxy.newProxyInstance(obj.getClass()
				.getClassLoader(), obj.getClass().getInterfaces(),
				new ServiceBaseProxy(obj));
	}
//第一个参数是要让代理的service对象的classloader,第二个参数是service对象的接口,第三个参数是处理逻辑的InvocationHandler类
	public static Object newInstance(Object obj, int datebaseType) {
		return java.lang.reflect.Proxy.newProxyInstance(obj.getClass()
				.getClassLoader(), obj.getClass().getInterfaces(),
				new ServiceBaseProxy(obj, datebaseType));
	}

	public ServiceBaseProxy(Object obj) {
		this.obj = obj;
	}

	public ServiceBaseProxy(Object obj, int datebaseType) {
		this.obj = obj;
		this.datebaseType = datebaseType;
	}
	public Object invoke(Object proxy, Method method, Object[] args)
			throws Exception {
		
		EntityManager em = HibernateEntityManager.getEm(this.datebaseType);
		String methodName = method.getName();
		EntityTransaction et = null;
		boolean flag = false;
		if (methodName.indexOf("WithTran") != -1) {  //执行前添加的逻辑
			flag = true;
		}
		Object result = null;
		try {
			if (flag) {
				System.out.println("em.getTransaction()");
				et = em.getTransaction();     //执行前添加的逻辑
				et.begin();
			}
			result = method.invoke(obj, args);   //执行原来service中的方法,obj对象告诉method执行哪个对象中的方法
		} catch (Exception e) {
			e.printStackTrace();
			if (flag) {
				 if ( et != null && et.isActive() ) 
				  et.rollback();
			}
			throw new Exception(e.getMessage());
		} finally {
			if (flag) {
				System.out.println("et.commit()");
				et.commit();
			}
			HibernateEntityManager.closeCurrentEm();  //执行后添加的逻辑
		}
		return result;
	}
}

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值