• EJB3之查询


          

        EJB3的实体查询 本文 使用的是JPA规范进行操作  产品实现用的是Hibernate

    主要涉及到增加、删除、更新、对象查询带排序、查询条件中使用构造器、运算符查询、字符串函数、计算函数、聚合函数


    先来看看 提供EJB服务的无状态bean

    package com.undergrowth.bean.impl;
    
    import java.util.List;
    
    import javax.ejb.Remote;
    import javax.ejb.Stateless;
    import javax.persistence.EntityManager;
    import javax.persistence.PersistenceContext;
    import javax.persistence.Query;
    
    import com.undergrowth.bean.Person;
    import com.undergrowth.bean.SimplePerson;
    import com.undergrowth.bean.service.IPerson;
    
    @Stateless
    @Remote(IPerson.class)
    public class PersonDao implements IPerson {
    
    	//依赖注入实体管理器
    	@PersistenceContext
    	EntityManager em;
    	
    	@Override
    	public void save(Person person) {
    		// TODO Auto-generated method stub
    		//由新建状态转为托管
    		em.persist(person);
    	}
    
    	@Override
    	public void delete(Integer personId) {
    		// TODO Auto-generated method stub
    		//由托管转为销毁
    		em.remove(getReferencesById(personId));
    	}
    
    	@Override
    	public void update(Person person) {
    		// TODO Auto-generated method stub
    		//由游离转为托管
    		em.merge(person);
    	}
    
    	@Override
    	public Person getById(Integer personId) {
    		// TODO Auto-generated method stub
    		return em.find(Person.class, personId);
    	}
    
    	@Override
    	public Person getReferencesById(Integer personId) {
    		// TODO Auto-generated method stub
    		//使用懒加载 返回代理对象  只有在使用get方法获取数据时  才加载对象
    		return em.getReference(Person.class, personId);
    	}
    
    	/**
    	 * 通过sql来获取对象
    	 * @param sql
    	 * @return
    	 */
    	@SuppressWarnings("unchecked")
    	@Override
    	public List<Person> getBySql(String sql) {
    		// TODO Auto-generated method stub
    		Query query=em.createQuery(sql);
    		return (List<Person>)query.getResultList();
    	}
    
    	/**
    	 * 通过sql来进行删除 添加 修改 数据
    	 * @param sql
    	 * @return
    	 */
    	@Override
    	public int cudBySql(String sql) {
    		// TODO Auto-generated method stub
    		Query query=em.createQuery(sql);
    		int num=query.executeUpdate();
    		return num;
    	}
    	
    	
    	@SuppressWarnings("unchecked")
    	@Override
    	public List<Person> getAllPersons() {
    		// TODO Auto-generated method stub
    		//使用JPQL进行查询结果集
    	return (List<Person>)em.createQuery("select p from Person p").getResultList();
    	}
    
    	/**
    	 * 返回部分对象
    	 */
    	@SuppressWarnings("unchecked")
    	@Override
    	public List<SimplePerson> getSimplePersonThroSql(String sql) {
    		// TODO Auto-generated method stub
    		return (List<SimplePerson>)em.createQuery(sql).getResultList();
    	}
    
    	/**
    	 * 通过查询返回单一的结果集
    	 */
    	@Override
    	public Object getBySqlRetSimple(String sql) {
    		// TODO Auto-generated method stub
    		Query query=em.createQuery(sql);
    		return query.getSingleResult();
    	}
    
    	
    
    }
    



    对应的远程接口

    package com.undergrowth.bean.service;
    
    import java.util.List;
    
    import javax.persistence.Query;
    
    import com.undergrowth.bean.Person;
    import com.undergrowth.bean.SimplePerson;
    
    public interface IPerson {
    	
    	//增删改查
    	public void save(Person person);
    	public void delete(Integer personId);
    	public void update(Person person);
    	/**
    	 * 通过sql来进行删除 添加 修改 数据
    	 * @param sql
    	 * @return
    	 */
    	public int  cudBySql(String sql);
    	public Person getById(Integer personId);
    	public Person getReferencesById(Integer personId);
    	/**
    	 * 通过sql来获取对象
    	 * @param sql
    	 * @return
    	 */
    	public List<Person> getBySql(String sql);
    	public List<Person> getAllPersons();
    	/**
    	 * 获取只有id name age的Person
    	 * @param sql
    	 * @return
    	 */
    	public List<SimplePerson> getSimplePersonThroSql(String sql);
    	public Object getBySqlRetSimple(String sql);
    	
    	
    }
    


    一对一的实体bean

    package com.undergrowth.bean;
    
    import java.io.Serializable;
    
    import javax.persistence.CascadeType;
    import javax.persistence.Column;
    import javax.persistence.Entity;
    import javax.persistence.GeneratedValue;
    import javax.persistence.Id;
    import javax.persistence.JoinColumn;
    import javax.persistence.OneToOne;
    import javax.persistence.Table;
    
    /*
     * 步骤
     * 1.一对一的相互关联 各自实体中拥有对方
     * 2.设置关系维护端与被维护端 指定级联的关系
     * 3.指明外键
     * 4.添加数据
     */
    
    @Entity
    @Table(name="person_info")
    public class Person implements Serializable{
    	/**
    	 * 
    	 */
    	private static final long serialVersionUID = 1L;
    	@Id @GeneratedValue 
    	private Integer id;
    	@Column(length=10,nullable=false)
    	private String name;
    	@Column(nullable=false)
    	private Integer age;
    	//all表示当person进行增删改查的时候 级联的增删改查idcard
    	//optional为false表示外键不能为空
    	@OneToOne(cascade=CascadeType.ALL,optional=false)
    	//JoinColumn指明idcard_id作为外键 来维护两个表的关系
    	@JoinColumn(name="idcard_id")
    	private IDCard idCard;
    	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 Person(){} //用于给反射机制使用
    	public IDCard getIdCard() {
    		return idCard;
    	}
    	public void setIdCard(IDCard idCard) {
    		this.idCard = idCard;
    	}
    	public Person(String name, Integer age, IDCard idCard) {
    		super();
    		this.name = name;
    		this.age = age;
    		this.idCard = idCard;
    	}
    	
    	@Override
    	public String toString() {
    		return "Person [id=" + id + ", name=" + name + ", age=" + age
    				+ ", idCard=" + idCard + "]";
    	}
    	
    	
    	
    }
    


    package com.undergrowth.bean;
    
    import java.io.Serializable;
    
    import javax.persistence.CascadeType;
    import javax.persistence.Column;
    import javax.persistence.Entity;
    import javax.persistence.GeneratedValue;
    import javax.persistence.Id;
    import javax.persistence.OneToOne;
    import javax.persistence.Table;
    
    
    @Entity
    @Table(name="idcard_info")
    public class IDCard implements Serializable{
    	/**
    	 * 
    	 */
    	private static final long serialVersionUID = 1L;
    	@Id @GeneratedValue
    	private Integer id;
    	@Column(length=18,nullable=false)
    	private String cardNum;
    	@Column(length=20,nullable=false)
    	private String issuedBy;
    	//mappedBy指定使用person对象的idCard这个属性来进行维护表间关系 并指明自己是关系的被维护端
    	@OneToOne(mappedBy="idCard")
    	private Person person;
    	
    	public Integer getId() {
    		return id;
    	}
    	public void setId(Integer id) {
    		this.id = id;
    	}
    	public String getCardNum() {
    		return cardNum;
    	}
    	public void setCardNum(String cardNum) {
    		this.cardNum = cardNum;
    	}
    	public String getIssuedBy() {
    		return issuedBy;
    	}
    	public void setIssuedBy(String issuedBy) {
    		this.issuedBy = issuedBy;
    	}
    	public IDCard(){} //用于给反射机制使用
    	public IDCard(String cardNum, String issuedBy) {
    		this.cardNum = cardNum;
    		this.issuedBy = issuedBy;
    	}
    	public Person getPerson() {
    		return person;
    	}
    	public void setPerson(Person person) {
    		this.person = person;
    	}
    	
    	@Override
    	public String toString() {
    		return "IDCard [id=" + id + ", cardNum=" + cardNum + ", issuedBy="
    				+ issuedBy + "]";
    	}
    	
    	
    }
    


    封装部分实体属性的SimplePerson

    package com.undergrowth.bean;
    
    import java.io.Serializable;
    
    public class SimplePerson implements  Serializable{
    	
    	/**
    	 * 
    	 */
    	private static final long serialVersionUID = 1L;
    	private Integer id;
    	private String name;
    	private Integer age;
    	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;
    	}
    	@Override
    	public String toString() {
    		return "SimplePerson [id=" + id + ", name=" + name + ", age=" + age
    				+ "]";
    	}
    	public SimplePerson(Integer id, String name, Integer age) {
    		super();
    		this.id = id;
    		this.name = name;
    		this.age = age;
    	}
    	public SimplePerson() {
    		super();
    	}
    	
    	
    }
    

    哦 persistence.xml文件

    <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="under" transaction-type="JTA">
        <jta-data-source>java:/myDataSource</jta-data-source>
            <properties>
             <property name="hibernate.hbm2ddl.auto" value="update" />
             <property name="hibernate.show_sql" value="true" />
             <property name="hibernate.format_sql" value="true"/>
            </properties>
        </persistence-unit>
    </persistence>

    ant的编译build.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <!-- ================================================ -->
    <!-- Sample buildfile for jar components -->
    <!-- -->
    <!-- ================================================ -->
    <project name="EJB3QL"  basedir=".">
        <!-- 定义属性 -->
        <property name="src.dir" value="${basedir}src" />
    	<!--  访问操作系统的环境变量  -->
        <property environment="env"  />
    	<!-- 设置jboss的目录 -->
        <property name="jboss.home" value="${env.JBOSS_HOME}"/>
    	<!-- 设置jboss的服务器名 -->
        <property name="jboss.server.home" value="standalone"  />
        <property name="dep" value="deployments"  />
        <property name="build.dir" value="${basedir}uild"  />
    
    	<!--构建path路径  -->
        <path id="build.classpath">
        	<fileset dir="${basedir}lib">
        		<include name="*.jar" />
        	</fileset>
        	<!--<pathelement location="${build.dir}" /> -->
        </path>
    
    	<!-- - - - - - - - - - - - - - -->
    	<!-- target: init -->
    	<!-- - - - - - - - - - - - - - -->
    	<target name="init">
    		<delete dir="${build.dir}"></delete>
    		<mkdir dir="${build.dir}"></mkdir>
    	</target>
    
    	<!-- ========================= -->
    	<!-- target: compile -->
    	<!-- ========================= -->
    	<target name="compile" depends="init"
    		description="--> compile  this component" >
             <!--  编译src目录下以com开头的所有子包中的类 
             '*' matches zero or more characters, '?' matches one character.
             When ** is used as the name of a directory in the pattern, it matches zero or more directories
             -->
    		<javac srcdir="${src.dir}" destdir="${build.dir}" includes="com/**" includeAntRuntime="false">
    			<classpath refid="build.classpath" />
    		</javac>
    	</target>
    	
    	<!-- 打包 -->
    	<target name="ejbjar" depends="compile" description="打包ejb">
    	   <jar jarfile="${basedir}${ant.project.name}.jar">
    	   	<fileset dir="${build.dir}">
    	   		<!-- 将build目录下的所有已class结尾的文件打包进去 -->
    	   		<include name="**/*.class"></include>
    	   	</fileset>
    	   	<!--将src目录下的META-INF目录下的文件打包进去 -->
    	   	<metainf dir="${src.dir}META-INF"></metainf>
    	   </jar>
    	</target>
      
        <!-- 部署 -->
        <target name="delopy" depends="ejbjar" description="部署ejb">
        	<copy file="${basedir}${ant.project.name}.jar"  todir="${jboss.home}${jboss.server.home}${dep}" />
        </target>
        
        <!-- 卸载ejb -->
        <target name="undeploy" description="卸载ejb">
          <delete file="${jboss.home}${jboss.server.home}${dep}${ant.project.name}.jar"></delete>
        </target>
        
    	<!-- 打包接口 -->
    	<target name="package_inter" depends="compile" description="打包接口">
    		<jar jarfile="${basedir}${ant.project.name}Interface.jar">
    			   	<fileset dir="${build.dir}">
    			   		<!-- 将build目录下中impl目录下的已class结尾的文件不打包进去 -->
    			   		<exclude name="**/impl/*.class"></exclude>
    			   	</fileset>
    			   </jar>
    	</target>
    	
    	<!--  删除生成的class和打包的文件 -->
    	<target name="clean" description="清除项目">
    		<delete dir="${build.dir}"></delete>
    		<delete file="${basedir}${ant.project.name}.jar"></delete>
    		<delete file="${basedir}${ant.project.name}Interface.jar"></delete>
    	</target>
    	
    
    </project>
    


    将无状态bean使用ant工具进行发布到jboss 中  后 即可通过客户端进行访问无状态的服务bean了


    2、

    客户端

    工具类 用于获取EJB服务

    package com.client.undergrowth.util;
    
    import java.util.Hashtable;
    
    import javax.naming.Context;
    import javax.naming.InitialContext;
    import javax.naming.NamingException;
    
    import com.undergrowth.bean.service.IPerson;
    
    
    
    public class JndiUtil {
    
    	/**
    	 * 获取EJB PersonDao的服务
    	 * @return
    	 * @throws NamingException
    	 */
    	public static IPerson lookupIPersonRemoteBean() throws NamingException{
    	   return (IPerson)lookupRemoteBean("EJB3QL","PersonDao",IPerson.class.getName());
    	}
    	
    	/**
    	 * 通过模块名,Bean名称,接口名称获取远程服务
    	 * @param moduleName
    	 * @param beanName
    	 * @param viewClassName
    	 * @return
    	 * @throws NamingException
    	 */
    	public static Object lookupRemoteBean(String moduleName,String beanName,String viewClassName) throws NamingException {
            final Hashtable jndiProperties = new Hashtable();
            jndiProperties.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming");
            final Context context = new InitialContext(jndiProperties);
            // The app name is the application name of the deployed EJBs. This is typically the ear name
            // without the .ear suffix. However, the application name could be overridden in the application.xml of the
            // EJB deployment on the server.
            // Since we haven't deployed the application as a .ear, the app name for us will be an empty string
            final String appName = "";
            // This is the module name of the deployed EJBs on the server. This is typically the jar name of the
            // EJB deployment, without the .jar suffix, but can be overridden via the ejb-jar.xml
            // In this example, we have deployed the EJBs in a jboss-as-ejb-remote-app.jar, so the module name is
            // jboss-as-ejb-remote-app
            //final String moduleName = "EJB3QL";
            // AS7 allows each deployment to have an (optional) distinct name. We haven't specified a distinct name for
            // our EJB deployment, so this is an empty string
            final String distinctName = "";
            // The EJB name which by default is the simple class name of the bean implementation class
           // final String beanName = "PersonDao";
            // the remote view fully qualified class name
           // final String viewClassName = HelloWorldRemote.class.getName();
           // final String viewClassName = IPerson.class.getName();
            // let's do the lookup
            return context.lookup("ejb:" + appName + "/" + moduleName + "/" + distinctName + "/" + beanName + "!" + viewClassName);
            
     }
    	
    }
    



    单元测试类

    package com.junit.test;
    
    import static org.junit.Assert.*;
    
    import java.util.Iterator;
    import java.util.List;
    
    import org.junit.BeforeClass;
    import org.junit.Test;
    
    import com.client.undergrowth.util.JndiUtil;
    import com.undergrowth.bean.IDCard;
    import com.undergrowth.bean.Person;
    import com.undergrowth.bean.SimplePerson;
    import com.undergrowth.bean.service.IPerson;
    
    public class PersonDaoTest {
    
    	static IPerson personDao = null;
        final int cudNum=8;
        
    	@BeforeClass
    	public static void setUpBeforeClass() throws Exception {
    		// 获取服务
    		personDao = JndiUtil.lookupIPersonRemoteBean();
    	}
    
    	/**
    	 * 保存
    	 */
    	@Test
    	public void testSave() {
    		IDCard idCard = new IDCard("333333333", "太平洋美国");
    		// 将关系被维护端的数据传递给关系维护端的数据 用于外键的更新
    		Person person = new Person("奥巴马", 5, idCard);
    		// 因为级联关系设置了级联保存 所以这里保存person 同时也会保存idCard
    		personDao.save(person);
    	}
    
    	/**
    	 * 删除
    	 */
    	@Test
    	public void testDelete() {
    		personDao.delete(cudNum);
    	}
    
    	/**
    	 * 更新
    	 */
    	@Test
    	public void testUpdate() {
    		Person person=personDao.getById(cudNum);
    		person.setName("普京");
    		personDao.update(person);
    	}
    
    	/**
    	 * 通过id获取对象
    	 */
    	@Test
    	public void testGetById() {
    		System.out.println(personDao.getById(cudNum));
    	}
    
    	/**
    	 * 获取对象代理
    	 */
    	@Test
    	public void testGetReferencesById() {
    		//可避免数据库加载的持久化开销 
    		//因为返回的是代理对象  没有持久化操作 所以这里会报错  无法获取对象
    		//System.out.println(personDao.getReferencesById(8));
    	}
    
    	/**
    	 * 对象查询
    	 */
    	@Test
    	public void testGetBySql() {
    		String sqlString="select p from Person p where p.age>12";
    		outListPerson(personDao.getBySql(sqlString));
    	}
    	
    	/**
    	 * 对象查询带排序
    	 * order by asc/desc
    	 */
    	@Test
    	public void testGetBySqlOrderBy() {
    		String sqlString="select p from Person p order by p.age desc";
    		outListPerson(personDao.getBySql(sqlString));
    	}
    
    	/**
    	 * 查询条件中使用构造器 返回构造器对象的结果集
    	 */
    	@Test
    	public void testGetSimplePersonThroSql() {
    		String sqlString="select new com.undergrowth.bean.SimplePerson(p.id,p.name,p.age) from Person p where p.age>8 order by p.age desc";
    		outListSimplePerson(personDao.getSimplePersonThroSql(sqlString));
    	}
    	
    	/**
    	 * 测试运算符 not 、between and 、like、in、is null、exists
    	 */
    	@Test
    	public void testOperatorBetween() {
    		String sqlString="select p from Person p where p.age between 2 and 15";
    		outListPerson(personDao.getBySql(sqlString));
    	}
    	
    	/**
    	 * 测试运算符 not 、between and 、like、in、is null、exists
    	 */
    	@Test
    	public void testOperatorLike() {
    		String sqlString="select p from Person p where p.name like '%奥%' ";
    		outListPerson(personDao.getBySql(sqlString));
    	}
    	
    	/**
    	 * 测试运算符 not 、between and 、like、in、is null、exists
    	 */
    	@Test
    	public void testOperatorExists() {
    		String sqlString="select p from Person p where  exists(select pe from IDCard pe where pe.id>13) ";
    		outListPerson(personDao.getBySql(sqlString));
    	}
    	
    	/**
    	 * 测试字符串函数  upper lower concat length substring trim locate
    	 */
    	@Test
    	public void testStrFunc() {
    		String sqlString="select p from Person p where  length(p.name)>2 ";
    		outListPerson(personDao.getBySql(sqlString));
    	}
    	
    	/**
    	 * 测试计算函数  abs mod sqrt size
    	 */
    	@Test
    	public void testNumberFunc() {
    		String sqlString="select p from Person p where  mod(p.age,10) > 1 ";
    		outListPerson(personDao.getBySql(sqlString));
    	}
    	
    	/**
    	 * 返回单一的结果集 聚合函数 count max min avg sum
    	 */
    	@Test
    	public void testGetBySqlRetSimple() {
    		//这里不能使用count(1) 因为这是基于对象的查询 1被当做值 导致报错
    		String sqlString="select count(*) from Person p where p.age>8";
    		System.out.println("年龄大于8岁的人有"+personDao.getBySqlRetSimple(sqlString));
    	}
    	
    	/**
    	 * 使用语句进行更新 删除 增加
    	 */
    	@Test
    	public void testCudBySql() {
    		String sqlUpdateString="update Person p set p.name='刘德华' where p.age=20";
    		System.out.println("影响结果集为:"+personDao.cudBySql(sqlUpdateString)+"条");
    	}
    
    	/**
    	 * 获取所有对象
    	 */
    	@Test
    	public void testGetAllPersons() {
    		List<Person> list=personDao.getAllPersons();
    		outListPerson(list);
    	}
    
    	/**
    	 * 遍历输出结果集
    	 * @param list
    	 */
    	private void outListPerson(List<Person> list) {
    		// TODO Auto-generated method stub
    		for (Person person : list) {
    			System.out.println(person);	
    			}
    	}
    	
    	/**
    	 * 输出SimplePerson
    	 * @param list
    	 */
    	private void outListSimplePerson(List<SimplePerson> list) {
    		// TODO Auto-generated method stub
    		for (SimplePerson person : list) {
    			System.out.println(person);	
    			}
    	}
    	
    	
    
    }
    


    客户端连接jboss的jndi配置文件

    jboss-ejb-client.properties

    endpoint.name=client-endpoint  
    remote.connectionprovider.create.options.org.xnio.Options.SSL_ENABLED=false  
       
    remote.connections=default  
       
    remote.connection.default.host= localhost
    remote.connection.default.port = 4447
    remote.connection.default.connect.options.org.xnio.Options.SASL_POLICY_NOANONYMOUS=false  
      
    remote.connection.default.username=qq     
    remote.connection.default.password=q  



  • 相关阅读:
    .Net 并发写入文件的多种方式
    变量命名神器——CODELF
    Python打包发布
    python工具——NumPy
    python工具——Pandas
    没事早点睡
    python工具——pixellib
    Tensorflow在Windows下使用踩坑
    python工具——Tesseract
    python工具——wordcloud
  • 原文地址:https://www.cnblogs.com/liangxinzhi/p/4275549.html
Copyright © 2020-2023  润新知