EJB3.0自学笔记,自学视频为黎活明老师主讲

一、   把jboss里面的所有包导入到项目,创建接口,实现类。

1.接口类HelloWorld

publicinterface HelloWorld {

      public String sayHello(Stringname);

}

2.实现类

/* @Stateful   说明这是一个有状态的会话bean

 * @Stateless 说明这是一个无状态的会话bean 

 * @Remote(HelloWorld.class)  把接口指定为远程接口    如果没有写就是默认实现的本地接口

 */

@Stateless

@Remote(HelloWorld.class)

publicclass HelloWorldBeanimplementsHelloWorld {

    public String sayHello(String name) {

      return name+":你好,世界!";

   }

 }

二、   创建测试类EJBClient

设置jndi访问环境信息,两种方式,如下:

1.     硬编码设置参数

      Properties props = new Properties();

      props.setProperty("java.naming.factory.initial",

           "org.jnp.interfaces.NamingContextFactory");

      props.setProperty("java.naming.provider.url","localhost:1099");

      try {

        InitialContext ctx = new InitialContext(props);

        //通过lookup寻找HelloWorldBean绑定的EJB代理存根对象

        HelloWorld helloWorld = (HelloWorld)ctx.lookup("HelloWorldBean/remote");

        System.out.println(helloWorld.sayHello("南昌"));

      } catch (NamingException e) {

        e.printStackTrace();

      }

2.                   通过新建一个jndi.properties设置参数

   try {

        InitialContext ctx =new InitialContext();

        //通过lookup寻找HelloWorldBean绑定的EJB代理存根对象

        HelloWorld helloWorld = (HelloWorld)ctx.lookup("HelloWorldBean/remote");

        System.out.println(helloWorld.sayHello("南昌"));

      } catch (NamingException e) {

        e.printStackTrace();

      }

 

三、   在项目底下新建ant的配置文件,build.xml

<?xml version="1.0"encoding="UTF-8" ?>

<!-- name属性是项目名,或者自定义   basedir属性是项目所在目录 

.说明项目所在路径就在此xml文件的所在路径

    ..说明项目所在路径就在此xml文件的上级目录-->

<projectname="HelloWorld"basedir=".">

   <!--说明项目源文件所在的目录    ${basedir}引用上面的属性值-->

   <propertyname="src.dir"value="${basedir}\src"></property>

   <!--此属性变量指向的是系统变量 -->

   <propertyenvironment="env"></property>

   <propertyname="jboss.home"value="${env.JBOSS_HOME}"></property>

   <!--配置jboss的配项,默认的是用default-->

   <propertyname="jboss.server.config"value="default"></property>

   <!--编译源文件,class类存放的目录 -->

   <propertyname="build.dir"value="${basedir}\build"></property>

   <pathid="build.classpath">

      <!--先定位到dir,然后包含dir目录下的所有jar文件-->

      <filesetdir="${jboss.home}\client">

        <includename="*.jar"/>

      </fileset>

      <pathelementlocation="${build.dir}"/>

   </path>

      <!--定义工作,name可以自己设置  mkdir创建目录  delete如果目录存在,删除目录-->

   <targetname="prepare">

      <deletedir="${build.dir}"/>

      <mkdirdir="${build.dir}"/>

   </target>

   <!-- depends表示先执行prepare,然后再执行compile-->

   <targetname="compile"depends="prepare"description="编译">

      <javacsrcdir="${src.dir}"destdir="${build.dir}">

        <compilerargline="-encoding GBK "/>

        <classpathrefid="build.classpath"></classpath>

      </javac>

   </target> 

   <targetname="ejbjar"depends="compile"description="创建EJB发布包">

      <jarjarfile="${basedir}\${ant.project.name}.jar">

        <filesetdir="${build.dir}">

           <includename="**/*.class"/>

        </fileset>

      </jar>

   </target>

  

   <targetname="deploy"depends="ejbjar"description="发布EJB">

      <copyfile="${basedir}\${ant.project.name}.jar"todir="${jboss.home}\server\${jboss.server.config}\deploy"/>

   </target>

      <targetname="undeploy" description="卸载EJB">

      <deletefile="${jboss_home}\server\${jboss.server.config}\deploy\${ant.project.name}.jar"/>

   </target>

</project>

四、    通过注解的方式其他EJB或者服务

1.  创建一个新的接口 Other

publicinterface Other {

   public String sayMe();

}

2.  创建一个接口实现类

@Stateless

publicclass OtherBeanimplements Other{

      public String sayMe() {

      return"other";

   }

}

3.  HelloWorldBean里面调用Other接口

@Stateless

@Remote(HelloWorld.class)

publicclass HelloWorldBeanimplements HelloWorld {

    publicStringsayHello(String name) {

      try {

        InitialContext ctx = new InitialContext();

        Other other = (Other)ctx.lookup("OtherBean/local");

        return name+":你好,世界!"+other.sayMe();

      } catch (NamingException e) {

        e.printStackTrace();

      }

      returnnull;

   }

}

4.  测试类里面EJBClient

publicclass EJBClient {

    publicstaticvoidmain(String[]args) {

      try {

        InitialContext ctx = new InitialContext();

        HelloWorld helloWorld = (HelloWorld)ctx.lookup("HelloWorldBean/remote");

        System.out.println(helloWorld.sayHello("南昌"));

      } catch (NamingException e) {

        e.printStackTrace();

      }

   }

 }

5.  或者用注入的方式:HelloWorldBean里面

@Stateless

@Remote(HelloWorld.class)

publicclass HelloWorldBeanimplements HelloWorld {

   @EJBOther other;

   publicStringsayHello(String name) {

      return name+":你好,世界!"+other.sayMe();

   }

}

6.  如果Other接口被多个EJB实现了,就必须指定需注入的EJB的名称,

EJB的名称默认的就是类名,也可以自定义,在@Stateless(name=”XXX”)

@EJB(beanName=”OtherBean”) Other other

Ps:@EJB注解只能够注入EJB。如果需要注入服务的话用@Resource

同样,注入数据源也用@Resource(mappedName=””) DataSource dataSource

 

五、   配置数据源

一、       jBoss里面有模版,docs\examples\jca

mysql 就是mssql-ds.xml,修改里面的基本信息。

同时可以配置最高连接数和最小连接数如:

<min-pool-size>3</min-pool-size >

<max-pool-size>100</max-pool-size >

      然后拷贝到server\default\deploy里面去

  

ps:所有数据源文件后面都必须带-ds结尾,也就是说,-ds结尾的文件会被jboss认为是数据源的配置文件,然后对他进行发布。

二、       把对应数据库的架包,比如说mysql,放进jBoss里面的server\default\lib里面去。然后重启jBoss

六、   开发单表映射的实体bean

1.  新建一个项目EntityBean,导入所有jboss里面的架包

2.新建一个META-INF文件夹,在此文件夹里面新建persistence.xml文件

<?xmlversion="1.0"encoding="UTF-8"?>

<persistencexmlns="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_1_0.xsd"version="1.0">

      <persistence-unitname="crazy"transaction-type="JTA">

   <jta-data-source>java:crazyDS</jta-data-sourc>

   </persistence-unit>

  </persistence>

Ps:其中的javacrazyDS就是前面配置的数据源的名称

  

2.  创建实体bean Person,创建所需的数据库,表。

@Entity

@Table(name="person")

publicclass Person implementsSerializable{

    privatestaticfinallongserialVersionUID = -8070495794570698778L;

   private Integerid;

   private Stringpname;

   public Person(){

        }

   public Person(String name) {

      this.pname = name;

   }

   //auto 可以根据数据库的类型由持久化实现产品决定选用 IDENTITY SEQUENCETABLE三种中的一种

   @Id@Column(name="id")@GeneratedValue(strategy=GenerationType.AUTO)

   public Integer getId() {

      returnid;

   }

   publicvoid setId(Integer id) {

      this.id = id;

   }

   @Column(name="pname",length=20,nullable=false)

   public String getPname() {

      returnpname;

   }

   publicvoid setPname(String pname) {

      this.pname = pname;

   }

   @Override

   publicint hashCode() {

      finalint prime = 31;

      int result = 1;

      result = prime * result + ((id ==null) ? 0 :id.hashCode());

      return result;

   }

   @Override

   publicboolean equals(Object obj) {

      if (this == obj)

        returntrue;

      if (obj ==null)

        returnfalse;

      if (getClass() != obj.getClass())

        returnfalse;

      Person other = (Person) obj;

      if (id ==null) {

        if (other.id !=null)

           returnfalse;

      } elseif (!id.equals(other.id))

        returnfalse;

      returntrue;

   }

}

3.  创建接口PersonService

publicinterface PersonService {

 

   publicvoid save(Person person);

   publicvoid update(Person person);

   publicvoid delete(Integer personid);

   public Person getPerson(Integer personid);

   public List<Person> getPersons();

}

4.  创建接口实现类PersonServiceBean

 

@Stateless

@Remote(PersonService.class)

publicclassPersonServiceBeanimplements PersonService {

   /*

    * @PersistenceContext  注入实体管理器,指定持久化单元名称,对应的persistence.xml文件里面的name属性值

    *               因为持久化单元可以为多个,所以必须指定,如果为一个的话,可以省略

    * getReference 返回的是一个代理对象,只要还不访问方式对象的get方法的话,是不会发生数据的装载,只有调用了get属性方法的时候才会进行数据的状态,简单理解就是懒加载

    *          简单来说就是相当于hibernate里面的load方法

    *          如果数据库找不到相应的实体,这个方法会抛出javax.persistence.EntityNotFoundException

    */

   @PersistenceContext(unitName="crazy") EntityManagerem;

   publicvoid delete(Integer personid) {

      em.remove(em.getReference(Person.class, personid));

   }

      public Person getPerson(Integer personid) {

      //如果在数据库里面没有找到的话,返回值就是null 相当于hibernate里面的get方法

      returnem.find(Person.class, personid);

   }

    @SuppressWarnings("unchecked")

   public List<Person> getPersons() {

     

      returnem.createQuery("selecto from Person o").getResultList();

   }

 

   publicvoid save(Person person) {

      em.persist(person);

   }

 

   publicvoid update(Person person) {

      //person在游离状态下,对数据进行了修改,才调用merge方法,如果对象处于托管状态,对数据进行修改,只需调用set方法

      em.merge(person);

   }

}

5.  创建jndi.properties配置文件

6.  JUNIT测试方法:

导入JUNIT的架包,右键PersonService选择NEW

然后再选择Junit Test Case

在对话框里面选择 Junit 4 test,修改报名junit.test

勾选setUpBeforeClass()

然后点next,勾选所有方法。点击finish

7.  6部生成了PersonServiceTest文件

首先测试save方法:

publicclass PersonServiceTest {

   privatestatic PersonServicepersonService;

  

   @BeforeClass

   publicstaticvoid setUpBeforeClass()throws Exception {

      try {

        InitialContext ctx = new InitialContext();

        personService = (PersonService) ctx

              .lookup("PersonServiceBean/remote");

      } catch (Exception e) {

        e.printStackTrace();

      }

   }

   @Test

   publicvoid testSave() {

      personService.save(new Person("小明"));

   }

   @Test

   publicvoid testUpdate() {

      fail("Not yetimplemented");

   }

   @Test

   publicvoid testDelete() {

      fail("Not yetimplemented");

   }

   @Test

   publicvoid testGetPerson() {

      fail("Not yetimplemented");

   }

   @Test

   publicvoid testGetPersons() {

      fail("Not yetimplemented");

   }

}

测试修改方法

   publicvoid testUpdate() {

      Person person = personService.getPerson(1);

      person.setPname("小白");

      personService.update(person);

   }

测试删除方法

   publicvoid testDelete() {

      personService.delete(1);

   }

测试查找方法

   @Test

   publicvoid testGetPerson() {

      Person person = personService.getPerson(1);

      System.out.println(person.getPname());

   }

测试查找集合方法

   @Test

   publicvoid testGetPersons() {

      List<Person> persons = personService.getPersons();

      System.out.println(persons.size());

   }

8.如果编写了bean运行之后自动创建表

persistence.xml文件的<persistence-unit>标签里面添加

<properties>

<propertyname="hibernate.hbm2ddl.auto"value="create"/>

<!-- 在控制台打印出sql语句-->

<propertyname="hibernate.show_sql"value="true"/>

<!-- 在控制台标准化打印出sql语句-->

<propertyname="hibernate.format_sql"value="true"/>

</properties>

 

8. 如果在发布的时候出了错,也就是JUNIT没有打进jar包,

有两种方法解决:

第一种:如果你没有把jUnit的架包放进jboss里面的Client目录的话,

       就会出现错误,所以添加进去;

第二种:过滤掉单元测试,编译的时候我们不编译单元测试类

       在build.xml文件里面 修改编译动作

   <targetname="compile"depends="prepare"description="编译">

      <javacsrcdir="${src.dir}"destdir="${build.dir}" includes=”com/**”>

        <classpathrefid="build.classpath"></classpath>

      </javac>

</target>

主要是因为junit的文件夹为junit.test其他的都是以com开头。

七、    开发消息驱动bean

1. 创建一个xml文件,结尾必须为-service结尾放进jboss里面的server\default\deploy 目录下

如:crazy-service.xml

<?xmlversion="1.0" encoding="UTF-8" ?>

<server>

   <mbeancode="org.jboss.mq.server.jmx.Queue"name="jboss.mq.destination:server=Queue,name=crazyQueue">

      <attributename="JNDIName">queue/crazyQueue</attribute>

      <dependsoptional-attribute-name="DestinationManager">jboss.mq:service=DestinationManager</depends>

   </mbean>

</server>

Ps:红色的都是自定义的,JNDIName可以不写,不写的话就是默认的为queue/+mbean里面的那么名称

 

2.  新建项目MessageDrivenBean,导入所以jboss架包,

在源目录创建jndi.properties,配置以下信息。

3.  创建发送信息的类 QueueSender

publicclass QueueSender {

   publicstaticvoid main(String[] args) {

      try {

        //得到jndi初始化上下文

        InitialContext ctx = new InitialContext();

        //根据上下文查找一个连接工厂QueueConnectionFactory该连接工厂有JMS提供。

        QueueConnectionFactory factory =(QueueConnectionFactory)ctx.lookup("ConnectionFactory");

        //从连接工厂得到一个连接

        QueueConnection conn = factory.createQueueConnection();

        //通过连接来建立一个会话session

        QueueSession session = conn.createQueueSession(false, QueueSession.AUTO_ACKNOWLEDGE);

        //查找目标地址

        Destination destination = (Destination)ctx.lookup("queue/crazyQueue");

        //根据会话和目标地址来创建消息的生产者

        MessageProducer producer =session.createProducer(destination);

        //调用消息发送者的send方法

        producer.send(session.createTextMessage("你好,思远!"));

        //关闭对应的资源

        session.close();

        conn.close();

      } catch (Exception e) {

        e.printStackTrace();

      }

   }

}

4.  创建消息驱动bean MessageDrivenBean实现MessageListener接口

/*

 * 通过注释可以指定消息驱动bean 监听的目标地址的类型destinationType

  目标地址的JBDI名称是什么destination

  并且还可以指定,当消息接收到之后,消息的确认模式是什么acknowledgeMode

  当使用容器管理的时候默认的就是Auto-acknowledge,可以不写

 */

@MessageDriven(activationConfig=

{

   @ActivationConfigProperty(propertyName="destinationType",

     propertyValue="javax.jms.Queue"),

   @ActivationConfigProperty(propertyName="destination",

     propertyValue="queue/crazyQueue"),

   @ActivationConfigProperty(propertyName="acknowledgeMode",

     propertyValue="Auto-acknowledge")

})

publicclass MessageDrivenBeanimplements MessageListener {

 

   publicvoid onMessage(Message message) {

      //因为发送的消息类型为TextMessage类型

      TextMessage msg = (TextMessage) message;

      try {

        System.out.println(msg.getText());

      } catch (Exception e) {

        e.printStackTrace();

      }

   }

}

5.  build.xml文件复制到此项目中,发布。然后再QueueSender里面运行

控制台中就会打印出你好,思远!

 

6.  Topic类型消息可以被多个接收方接受

创建TopicSender

publicclass TopicSender {

   publicstaticvoid main(String[] args) {

      try {

        //得到jndi初始化上下文

        InitialContext ctx = new InitialContext();

        //根据上下文查找一个连接工厂QueueConnectionFactory该连接工厂有JMS提供。

        TopicConnectionFactory factory =(TopicConnectionFactory)ctx.lookup("ConnectionFactory");

        //从连接工厂得到一个连接

        TopicConnection conn = factory.createTopicConnection();

        //通过连接来建立一个会话session

        TopicSession session = conn.createTopicSession(false, TopicSession.AUTO_ACKNOWLEDGE);

        //查找目标地址

        Destination destination = (Destination)ctx.lookup("topic/crazyTopic");

        //根据会话和目标地址来创建消息的生产者

        MessageProducer producer =session.createProducer(destination);

        //调用消息发送者的send方法

        producer.send(session.createTextMessage("你好,思远!"));

       

       

        //关闭对应的资源

        session.close();

        conn.close();

        System.out.println("消息发送完成");

      } catch (Exception e) {

        e.printStackTrace();

      }

   }

}

 

创建两个消息驱动bean

@MessageDriven(activationConfig=

{

   @ActivationConfigProperty(propertyName="destinationType",

     propertyValue="javax.jms.Topic"),

   @ActivationConfigProperty(propertyName="destination",

     propertyValue="topic/crazyTopic")

})

publicclass ReceiveOtherBeanimplements MessageListener {

 

   publicvoid onMessage(Message message) {

      TextMessage msg = (TextMessage) message;

      try {

        System.out.println(msg.getText()+this.getClass());

      } catch (Exception e) {

        e.printStackTrace();

      }

   }

 

}

第二个

@MessageDriven(activationConfig=

{

   @ActivationConfigProperty(propertyName="destinationType",

     propertyValue="javax.jms.Topic"),

   @ActivationConfigProperty(propertyName="destination",

     propertyValue="topic/crazyTopic")

})

publicclass ReceiveBeanimplements MessageListener {

 

   publicvoid onMessage(Message message) {

      TextMessage msg = (TextMessage) message;

      try {

        System.out.println(msg.getText()+this.getClass());

      } catch (Exception e) {

        e.printStackTrace();

      }

   }

}

 

八、   开发EJB模型的Web服务

详细见:http://blog.csdn.net/itm_hadf/article/details/7687797

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
智慧校园的建设目标是通过数据整合、全面共享,实现校园内教学、科研、管理、服务流程的数字化、信息化、智能化和多媒体化,以提高资源利用率和管理效率,确保校园安全。 智慧校园的建设思路包括构建统一支撑平台、建立完善管理体系、大数据辅助决策和建设校园智慧环境。通过云架构的数据中心与智慧的学习、办公环境,实现日常教学活动、资源建设情况、学业水平情况的全面统计和分析,为决策提供辅助。此外,智慧校园还涵盖了多媒体教学、智慧录播、电子图书馆、VR教室等多种教学模式,以及校园网络、智慧班牌、校园广播等教务管理功能,旨在提升教学品质和管理水平。 智慧校园的详细方案设计进一步细化了教学、教务、安防和运维等多个方面的应用。例如,在智慧教学领域,通过多媒体教学、智慧录播、电子图书馆等技术,实现教学资源的共享和教学模式的创新。在智慧教务方面,校园网络、考场监控、智慧班牌等系统为校园管理提供了便捷和高效。智慧安防系统包括视频监控、一键报警、阳光厨房等,确保校园安全。智慧运维则通过综合管理平台、设备管理、能效管理和资产管理,实现校园设施的智能化管理。 智慧校园的优势和价值体现在个性化互动的智慧教学、协同高效的校园管理、无处不在的校园学习、全面感知的校园环境和轻松便捷的校园生活等方面。通过智慧校园的建设,可以促进教育资源的均衡化,提高教育质量和管理效率,同时保障校园安全和提升师生的学习体验。 总之,智慧校园解决方案通过整合现代信息技术,如云计算、大数据、物联网和人工智能,为教育行业带来了革命性的变革。它不仅提高了教育的质量和效率,还为师生创造了一个更加安全、便捷和富有智慧的学习与生活环境。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值