zoukankan      html  css  js  c++  java
  • Mybatis配置

     
    首先导入mybatis-3.2.3.jar包 还有连接数据库的驱动包
     
    工程中必须导入的三个包(对应的包附件中可以下载):
     
    mybatis-3.2.3.jar
    sqljdbc.jar
    log4j-1.2.14.jar
    配置过程如下六个步骤缺一不可
    第一步:编写数据库连接文件sqlserver-jdbc-connection.properties,我的文件路径在com.mybatis.config包下
    class="xml">#sqlserver connection
    driver=com.microsoft.sqlserver.jdbc.SQLServerDriver
    url=jdbc:sqlserver://192.168.1.31:1433; DatabaseName=dataBaseName
    username=sa
    password=sa
    ?
    第二步:编写MyBatis配置文件Configuration.xml,我的文件路径在com.mybatis.config包下
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
    "http://mybatis.org/dtd/mybatis-3-config.dtd">
     
    <!-- 注意:每个标签必须按顺序写,不然蛋疼的DTD会提示错误:The content of element type "configuration" must match "(properties?,settings?,typeAliases?,typeHandlers?,objectFactory?,objectWrapperFactory?,plugins?,environments?,mappers?)". -->
    <configuration>
     <!-- 属性配置 -->
     <properties resource="com/mybatis/config/sqlserver-jdbc-connection.properties">
      <!-- 相同属性:最高优先级的属性是那些作为方法参数的,然后是资源/url 属性,最后是 properties元素中指定的属性 -->
    <!-- <property name="username" value="sa"/> -->
    <!-- <property name="password" value="phoenix"/> -->
     </properties>
     
     <!-- 设置缓存和延迟加载等等重要的运行时的行为方式 -->
     <settings>
      <!-- 设置超时时间,它决定驱动等待一个数据库响应的时间 -->
      <setting name="defaultStatementTimeout" value="25000"/>
      <!-- 这个配置使全局的映射器启用或禁用缓存 -->
      <setting name="cacheEnabled" value="true"/>
     
      <!-- 全局启用或禁用延迟加载。当禁用时,所有关联对象都会即时加载 -->
    <!-- <setting name="lazyLoadingEnabled" value="true"/> -->
      <!-- 当启用时,有延迟加载属性的对象在被调用时将会完全加载任意属性。否则,每种属性将会按需要加载 -->
      <setting name="aggressiveLazyLoading" value="true"/>
     
      <!-- 允许或不允许多种结果集从一个单独的语句中返回(需要适合的驱动) -->
      <setting name="multipleResultSetsEnabled" value="true"/>
      <!-- 使用列标签代替列名。不同的驱动在这方便表现不同。参考驱动文档或充分测试两种方法来决定所使用的驱动 -->
      <setting name="useColumnLabel" value="true"/>
      <!-- 允许JDBC支持生成的键。需要适合的驱动。如果设置为true则这个设置强制生成的键被使用,尽管一些驱动拒绝兼容但仍然有效(比如Derby) -->
      <setting name="useGeneratedKeys" value="false"/>
      <!-- 指定MyBatis如何自动映射列到字段/属性。PARTIAL只会自动映射简单,没有嵌套的结果。FULL会自动映射任意复杂的结果(嵌套的或其他情况) -->
      <setting name="autoMappingBehavior" value="PARTIAL"/>
      <!-- 配置默认的执行器。SIMPLE执行器没有什么特别之处。REUSE执行器重用预处理语句。BATCH执行器重用语句和批量更新 -->
      <setting name="defaultExecutorType" value="SIMPLE"/>
     </settings>
     
     <!-- 别名 -->
     <typeAliases>
      <!-- 该映射类type一般都为实体类的路径 -->
      <typeAlias alias="UserBean" type="com.restservice.bean.UserBean"/>
     
     
     <environments default="development">
      <!-- environment 元素体中包含对事务管理和连接池的环境配置 -->
      <environment id="development">
       <transactionManager type="JDBC" />
       <!-- type分三种:
         UNPOOLED是每次被请求时简单打开和关闭连接
         UNPOOLED的数据源仅仅用来配置以下 4 种属性driver,url,username,password
         POOLED :JDBC连接对象的数据源连接池的实现,不直接支持第三方数据库连接池
       -->
       <dataSource type="POOLED">
        <property name="driver" value="${driver}" />
        <property name="url" value="${url}" />
        <property name="username" value="${username}" />
        <property name="password" value="${password}" />
       </dataSource>
      </environment>
     </environments>
     
     <!-- ORM映射文件 -->
     <mappers>
      <!-- 用户测试XML -->
      <mapper resource="com/restservice/bean/UserBean.xml" />
     </mappers>
    </configuration>
    ?
    第三步:编写对应的用户bean及xml
    贴一下xml代码,需要自己写一下bean哦,(不会可以留言。)
     
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE mapper????
    PUBLIC "-//ibatis.apache.org//DTD Mapper 3.0//EN"????
    "http://ibatis.apache.org/dtd/ibatis-3-mapper.dtd">????
     
    <!-- namespace用于java代码调用时识别指定xml的mapper文件 -->
    <!-- 这里namespace必须是其对应的接口的路径,,不然要运行的时候要报错 “is not known to the MapperRegistry”-->  
    <mapper namespace="userinfo">
    <!-- 开启Mabatis二级缓存 -->
    <cache/>
    <!-- 配置ORM映射 -->
    <resultMap type="UserInfo" id="user_orm">
    <id property="id" column="id"/>
    <result property="code" column="code"/>
    <result property="name" column="name"/>
    <result property="sex" column="sex"/>
    <result property="phone" column="phone"/>
    <result property="money" column="money"/>
    </resultMap>
     
    <!-- 用来定义可重用的SQL代码段 -->
    <sql id="demo_sql">
    code,name,sex,phone,money
    </sql>
     
    <insert id="inser_userInfo" parameterType="UserInfo">
    <!-- include 引用可重用的SQL代码段 -->
    INSERT INTO USERINFO(<include refid="demo_sql"/>) VALUES(#{code},#{name},#{sex},#{phone},#{money})
    </insert>
     
    <update id="update_userInfo" parameterType="UserInfo">
    UPDATE USERINFO SET code=#{code} ,name=#{name} ,sex=#{sex} ,phone=#{phone} ,money=#{money} WHERE id=#{id}
    </update>
      <!-- 在接口的映射文件中SQL语句的id必须和UserMapper接口中的接口方法名相同,不然运行的时候也要报错 --> 
     <select id="selectAll_userInfo"? resultMap="user_orm">
     ?SELECT * FROM USERINFO
    </select>
     
    <select id="selectById_userInfo" parameterType="int" resultType="UserInfo">
    <!-- 这里sql结尾不能加分号,否则报“ORA-00911”的错误 -->  
    SELECT * FROM USERINFO WHERE id= #{id}
    ? ?</select>
    </mapper>?
    ?
     
    ?sql语句中常用的特殊处理
    如:需要in查询
    ?
     
    <select id="findWellsInfo" useCache="false" flushCache="true" resultType="hashmap">
      SELECT ID AS FIELDCODE,NAME AS DATACATEGORYNAME,'' COLOR FROM IMS_WELL WHERE ID IN
      <foreach item="wellIds" index="index" collection="wellIds"
      open="(" separator="," close=")">
      #{wellIds}
      </foreach>
       </select>
    我这里传入的参数是一个map ,map中有一个参数是数组wellIds,所以我写成collection="wellIds";
     
    可以直接传入数组,写法:只需要把collection="wellIds"改成collection="array";
     
    也可以传入List ,写法:只需要把collection="wellIds"改成collection="list";
     
    ?还有很多特殊情况就不一一举例了,具体请详细阅读附件MyBatis3.2中文API
     
    ?
     
    ?第四步:创建SessionFactoryUtil.java工具类
    import java.io.IOException;
    import java.io.Reader;
     
    import org.apache.ibatis.io.Resources;
    import org.apache.ibatis.session.SqlSession;
    import org.apache.ibatis.session.SqlSessionFactory;
    import org.apache.ibatis.session.SqlSessionFactoryBuilder;
    import org.apache.log4j.Logger;
    /**
     *
     * MyBatis会话工厂类.
     *
     * @version 1.0 2013-12-1
     * @author xqwu
     */
    public class SessionFactoryUtil {
     
     protected static final Logger log = Logger.getLogger(SessionFactoryUtil.class);
     //MyBatis配置路径
     private static final String RESOURCE = "com/mybatis/config/Configuration.xml";
     //sql会话工厂
     private static SqlSessionFactory sqlSessionFactory = null;
     //所有sqlSession
     private static ThreadLocal<SqlSession> threadLocal = new ThreadLocal<SqlSession>();
     
     /**
      * 静态代码块 用于获得sqlSessionFactory
      * 不执行 由SessionFactoryListener调用初始化方法
      */
     /*static {
      Reader reader = null;
      try {
       reader = Resources.getResourceAsReader(RESOURCE);
      } catch (IOException ioex) {
       throw new RuntimeException("Get resource error:"+RESOURCE, ioex);
      }
      //获得sqlSessionFactory
      sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
     }*/
     
     /**
      *
      * 获得SqlSessionFactory
      * @author xqwu
      * @date 2013-12-1 下午2:08:59
      *
      * @return
      */
     public static SqlSessionFactory getSqlSessionFactory(){
            return sqlSessionFactory;
        }
     
     /**
      *
      * 初始化SqlSessionFactory.
      * @author xqwu
      * @date 2013-12-1 下午2:08:39
      *
      */
     public static void initSqlSessionFactory() throws RuntimeException,Exception{
      try {
       
       if(sqlSessionFactory == null){
        Reader reader = Resources.getResourceAsReader(RESOURCE);
        sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
        log.debug("init sqlSessionFactory success");
       }
       
      } catch (IOException ioex) {
       
       throw new RuntimeException("Get resource error:"+RESOURCE, ioex);
       
      }
     }
     
     /**
      *
      * 获取sqlSession.
      * @author xqwu
      * @date 2013-12-1 上午11:27:38
      *
      * @return
      */
     public static SqlSession getSession(){
      SqlSession sqlsession = threadLocal.get();
     
      if(sqlsession!=null){
       if(sqlSessionFactory == null){
        getSqlSessionFactory();
       }
       //如果sqlSessionFactory不为空则获取sqlSession,否则返回null
       sqlsession = (sqlSessionFactory!=null) ? sqlSessionFactory.openSession(): null;
      }
     
      return sqlsession;
     }
     
     /**
      *
      * 关闭sqlSession
      * @author xqwu
      * @date 2013-12-1 上午11:26:23
      *
      */
     public static void closeSqlSession() throws Exception{
      //获得sqlsession
      SqlSession sqlsession = threadLocal.get();
      threadLocal.set(null);
      if(sqlsession!=null){//验证关闭sqlsession
       sqlsession.close();
       log.debug("close sqlsession success");
      }
     
      log.debug("sqlsession is null");
     }
    }
    ?
     
    ?第五步:创建tomcat启动监听器类SessionFactoryListener,用于管理sqlSessionFactory生命周期(我用的是tomcat6.0)
    import javax.servlet.ServletContextEvent;
    import javax.servlet.ServletContextListener;
     
    import org.apache.log4j.Logger;
     
    import com.opro.ims.i.restservice.utils.SessionFactoryUtil;
     
    /**
     * Class description goes here.
     *
     * @version 1.0 2013-12-6
     * @author xqwu
     */
    public class SessionFactoryListener implements ServletContextListener {
     
     protected static final Logger log = Logger.getLogger(SessionFactoryListener.class);
     /* (non-Javadoc)
      * <p>Title: contextDestroyed</p>
      * <p>Description: </p>
      * @param arg0
      * 当Servlet 容器终止Web 应用时调用该方法。在调用该方法之前,容器会先销毁所有的Servlet 和Filter 过滤器。
      * @see javax.servlet.ServletContextListener#contextDestroyed(javax.servlet.ServletContextEvent)
      */
     @Override
     public void contextDestroyed(ServletContextEvent arg0) {
      try {
       
       SessionFactoryUtil.closeSqlSession();
       
      } catch (Exception ex) {
       
       log.error(ex.getMessage());
       
      }
     }
     
     /* (non-Javadoc)
      * <p>Title: contextInitialized</p>
      * 当Servlet 容器启动Web 应用时调用该方法。在调用完该方法之后,容器再对Filter 初始化,
      * 并且对那些在Web 应用启动时就需要被初始化的Servlet 进行初始化。
      * @param arg0
      * @see javax.servlet.ServletContextListener#contextInitialized(javax.servlet.ServletContextEvent)
      */
     @Override
     public void contextInitialized(ServletContextEvent arg0) {
     
      try {
       
       SessionFactoryUtil.initSqlSessionFactory();
       
      } catch (RuntimeException rex) {
     
       log.error(rex.getMessage());
       
      } catch (Exception ex) {
     
       log.error(ex.getMessage());
       
      }
     
     }
     
    }
    ?
     
    ?第六步:web.xml 配置文件中加入如下内容
     <!-- 初始化SessionFactory监听器 -->
     <listener>
      <listener-class>com.opro.ims.i.restservice.listener.SessionFactoryListener</listener-class>
     </listener>
    ?
     
    ?
     
    ?
     
    编写接口BaseDao
    import java.sql.SQLException;
    import java.util.List;
     
    import org.apache.ibatis.session.SqlSession;
    import org.apache.ibatis.type.TypeException;
     
    /**
     * Class description goes here.
     *
     * @version 1.0 2013-11-29
     * @author xqwu
     */
    public interface BaseDao {
     
     /**
      *
      * 获得sqlSession对象.
      * @author xqwu
      * @date 2013-11-29 下午4:17:11
      *
      * @return
      */
     public SqlSession getSqlSession() throws TypeException,SQLException,Exception;
     
     /**
      *
      * 插入数据.
      * @author xqwu
      * @date 2013-12-6 上午09:56:00
      *
      * @param s
      * @param obj
      * @throws TypeException
      * @throws SQLException
      * @throws Exception
      */
     public void insert(String s, Object obj) throws TypeException,SQLException,Exception;
     
     /**
      *
      * 查询所有数据.
      * @author xqwu
      * @date 2013-11-29 下午3:52:21
      *
      * @return
      */
     public List<?> findAll(String s, Object obj) throws TypeException,SQLException,Exception;
     
     /**
      *
      * 查询指定页数大小.
      * @author xqwu
      * @date 2013-11-29 下午3:54:06
      *
      * @param s namespace用于java代码调用时识别指定xml的mapper文件
      * @param pageNo 页码
      * @param pageSize 大小
      * @return
      */
     public List<?> findList(String s, Object obj, int pageNo, int pageSize) throws TypeException,SQLException,Exception;
     
     /**
      *
      * 查询返回对象.
      * @author xqwu
      * @date 2013-12-2 下午02:58:41
      *
      * @param s
      * @param param
      * @return
      */
     public Object selectOne(String s, Object param) throws TypeException,SQLException,Exception;
     
     /**
      *
      * 更新数据方法.
      * @author xqwu
      * @date 2013-12-4 下午05:59:16
      *
      * @param s
      * @param param
      * @throws TypeException
      * @throws SQLException
      * @throws Exception
      */
     public void update(String s, Object param) throws TypeException,SQLException,Exception;
    }
    ?编写接口实现BaseDaoImpl
    import java.sql.SQLException;
    import java.util.List;
     
    import org.apache.ibatis.session.RowBounds;
    import org.apache.ibatis.session.SqlSession;
    import org.apache.ibatis.type.TypeException;
     
    import com.opro.ims.i.restservice.core.BaseDao;
    import com.opro.ims.i.restservice.utils.SessionFactoryUtil;
     
    /**
     * Dao基类,所有Dao都继承该类.
     *
     * @version 1.0 2013-11-29
     * @author xqwu
     */
    public class BaseDaoImpl implements BaseDao{
     
     @Override
     public SqlSession getSqlSession() throws TypeException,SQLException,Exception {
      // TODO Auto-generated method stub
      return SessionFactoryUtil.getSqlSessionFactory().openSession();
     }
     
     @Override
     public List<?> findAll(String s, Object obj) throws TypeException,SQLException,Exception {
      // TODO Auto-generated method stub
      SqlSession session = getSqlSession();
      try{
       List list = session.selectList(s, obj);
       return list;
      } finally{
       session.close();
      }
     }
     
     @Override
     public List<?> findList(String s, Object obj, int pageNo, int pageSize) throws TypeException,SQLException,Exception {
      // TODO Auto-generated method stub
      SqlSession session = getSqlSession();
      try{
       List list = session.selectList(s, obj, new RowBounds((pageNo-1)*pageSize, pageSize));
       return list;
      } finally{
       session.close();
      }
     }
     
     @Override
     public Object selectOne(String s, Object param) throws TypeException,SQLException,Exception {
      // TODO Auto-generated method stub
      SqlSession session = getSqlSession();
      try{
       Object object = session.selectOne(s, param);
       return object;
      } finally{
       session.close();
      }
     }
     
     @Override
     public void update(String s, Object param) throws TypeException,SQLException, Exception {
      // TODO Auto-generated method stub
      SqlSession session = getSqlSession();
      try{
       session.update(s, param);
       session.commit();
      } finally{
       session.close();
      }
     }
     
     /* (non-Javadoc)
      * <p>Title: insert</p>
      * <p>Description: </p>
      * @param s
      * @param obj
      * @throws TypeException
      * @throws SQLException
      * @throws Exception
      * @see com.opro.ims.i.restservice.core.BaseDao#insert(java.lang.String, java.lang.Object)
      */
     @Override
     public void insert(String s, Object param) throws TypeException, SQLException, Exception {
      // TODO Auto-generated method stub
      SqlSession session = getSqlSession();
      try{
       session.insert(s, param);
       session.commit();
      } finally{
       session.close();
      }
     }
     
    }
     
    SQL映射XML文件一些初级的元素
    1:cache-配置给定模式的缓存
    2:cache-ref-从别的模式中引用一个缓存
    3:resultMap-这是最复杂而却强大的一个元素了,她描述如何从结果集中加载对象
    4:sql-一个可以被其他语句复用的SQL块

    5. insert – 映射INSERT 语句

     6. update – 映射UPDATE 语句

     7. delete – 映射DELEETE 语句

    8. select - 映射SELECT语句

    resultMap属性:type为java实体类;id为此resultMap的标识。

      resultMap可以设置的映射:

     1. constructor – 用来将结果反射给一个实例化好的类的构造器 a) idArg – ID ;参数将结果集标记为ID,以方便全局调用 b) arg –反射到构造器的通常结果

     2. id – ID 结果,将结果集标记为ID,以方便全局调用

     3. result – 反射到JavaBean 属性的普通结果

     4. association – 复杂类型的结合;多个结果合成的类型 a) nested result mappings – 几resultMap 自身嵌套关联,也可以引用到一个其它上

     5. collection –复杂类型集合a collection of complex types

     6. nested result mappings – resultMap 的集合,也可以引用到一个其它上

     7. discriminator – 使用一个结果值以决定使用哪个resultMap a) case – 基本一些值的结果映射的case 情形 i. nested result mappings –一个case 情形本身就是一个结果映射,因此也可以包括一些相同的元素,也可以引用一个外部resultMap。

    2.1.1 id、result

    id、result是最简单的映射,

    id为主键映射;result其他基本数据库表字段到实体类属性的映射。

    最简单的例子: Xml代码

    <resultMap type="StudentEntity" id="studentResultMap">

    <id property="studentID" column="STUDENT_ID"/>

     <result property="studentSex" column="STUDENT_SEX"/>

     <result property="studentBirthday" column="STUDENT_BIRTHDAY"/> </resultMap>

    id、result语句属性配置细节

    属性的描述

    property-需要映射到JavaBean的属性名称

    column-数据表的列名或者标签别名

    javaType-一个完整的类名,或者是一个类型别名,如果你匹配的是一个JavaBean,那MyBatis通常会自行检测到,然后,如果你是要映射到一个HashMap,那你需要指定javaType要达到的目的。

    jdbcType

    数据表支持的类型列表。这个属性只在insert,update 或delete 的时候针对允许空的列有用。JDBC 需要这项,但MyBatis 不需要。如果你是直接针对JDBC 编码,且有允许空的列,而你要指定这项。

    typeHandler 使用这个属性可以覆写类型处理器。这项值可以是一个完整的类名,也可以是一个类型别名。

    2.1.2 constructor

    我们使用id、result时候,需要定义java实体类的属性映射到数据库表的字段上。这个时候是使用JavaBean实现的。当然我们也可以使用实体类的构造方法来实现值的映射,这个时候是通过构造方法参数的书写的顺序来进行赋值的。

    使用construcotr功能有限(例如使用collection级联查询)。

    上面使用id、result实现的功能就可以改为:

    Xml代码 <resultMap type="StudentEntity" id="studentResultMap" > <constructor>

    <idArg javaType="String" column="STUDENT_ID"/>

    <arg javaType="String" column="STUDENT_NAME"/>

    <arg javaType="String" column="STUDENT_SEX"/>

    <arg javaType="Date" column="STUDENT_BIRTHDAY"/>

    </constructor>

    </resultMap>

    当然,我们需要定义StudentEntity实体类的构造方法:

    Java代码 public StudentEntity(String studentID, String studentName, String studentSex, Date studentBirthday){

    this.studentID = studentID;

    this.studentName = studentName;

    this.studentSex = studentSex;

    this.studentBirthday = studentBirthday; } 

    2.1.3 association联合

    联合元素用来处理“一对一”的关系

    需要指定映射的Java实体类的属性,属性的javaType(通常MyBatis 自己会识别)。

    对应的数据库表的列名称。如果想覆写的话返回结果的值,需要指定typeHandler。

    不同情况需要告诉MyBatis 如何加载一个联合。

    MyBatis 可以用两种方式加载:

    1. select: 执行一个其它映射的SQL 语句返回一个Java实体类型。较灵活;

    2. resultsMap: 使用一个嵌套的结果映射来处理通过join查询结果集,映射成Java实体类型。

    例如,一个班级对应一个班主任。 首先定义好班级中的班主任属性:

    Java代码

    private TeacherEntity teacherEntity; 

    2.1.3.1使用select实现联合

     例:班级实体类中有班主任的属性,通过联合在得到一个班级实体时,同时映射出班主任实体。

    这样可以直接复用在TeacherMapper.xml文件中定义好的查询teacher根据其ID的select语句。而且不需要修改写好的SQL语句,只需要直接修改resultMap即可。 

    ClassMapper.xml文件部分内容:

    Xml代码 

     <resultMap type="ClassEntity" id="classResultMap">

    <id property="classID" column="CLASS_ID" />

    <result property="className" column="CLASS_NAME" />

    <result property="classYear" column="CLASS_YEAR" />

    <association property="teacherEntity" column="TEACHER_ID" select="getTeacher"/>

    </resultMap>

    <select id="getClassByID" parameterType="String" resultMap="classResultMap">

    SELECT * FROM CLASS_TBL CT WHERE CT.CLASS_ID = #{classID};

    </select>

    TeacherMapper.xml文件部分内容:

    Xml代码

    <resultMap type="TeacherEntity" id="teacherResultMap">

    <id property="teacherID" column="TEACHER_ID" />

    <result property="teacherName" column="TEACHER_NAME" />

    <result property="teacherSex" column="TEACHER_SEX" />

    <result property="teacherBirthday" column="TEACHER_BIRTHDAY"/>

    <result property="workDate" column="WORK_DATE"/>

    <result property="professional" column="PROFESSIONAL"/>

    </resultMap>

    <select id="getTeacher" parameterType="String" resultMap="teacherResultMap">

        SELECT * FROM TEACHER_TBL TT WHERE TT.TEACHER_ID = #{teacherID}

    </select>  

    2.1.3.2使用resultMap实现联合

    与上面同样的功能,查询班级,同时查询器班主任。

    需在association中添加resultMap(在teacher的xml文件中定义好的),

    新写sql(查询班级表left join教师表),不需要teacher的select。

    修改ClassMapper.xml文件部分内容:

    Xml代码

    <resultMap type="ClassEntity" id="classResultMap">

    <id property="classID" column="CLASS_ID" />

    <result property="className" column="CLASS_NAME" />

    <result property="classYear" column="CLASS_YEAR" />

    <association property="teacherEntity" column="TEACHER_ID" resultMap="teacherResultMap"/>

    </resultMap> <select id="getClassAndTeacher" parameterType="String" resultMap="classResultMap">

    SELECT * FROM CLASS_TBL CT LEFT JOIN TEACHER_TBL TT ON CT.TEACHER_ID = TT.TEACHER_ID WHERE CT.CLASS_ID = #{classID};

    </select>

    其中的teacherResultMap请见上面TeacherMapper.xml文件部分内容中。

    2.1.4 collection聚集 聚集元素用来处理“一对多”的关系。

    需要指定映射的Java实体类的属性,属性的javaType(一般为ArrayList);

    列表中对象的类型ofType(Java实体类);

    对应的数据库表的列名称;

    不同情况需要告诉MyBatis 如何加载一个聚集。

    MyBatis 可以用两种方式加载:

    1. select: 执行一个其它映射的SQL 语句返回一个Java实体类型。较灵活;

    2. resultsMap: 使用一个嵌套的结果映射来处理通过join查询结果集,映射成Java实体类型。

    例如,一个班级有多个学生。 首先定义班级中的学生列表属性:

    Java代码 private List<StudentEntity> studentList;

    2.1.4.1使用select实现聚集 用法和联合很类似,区别在于,这是一对多,所以一般映射过来的都是列表。所以这里需要定义javaType为ArrayList,还需要定义 列表中对象的类型ofType,以及必须设置的select的语句名称(需要注意的是,这里的查询student的select语句条件必须是外键 classID)。

    ClassMapper.xml文件部分内容:

    Xml代码

    <resultMap type="ClassEntity" id="classResultMap">

    <id property="classID" column="CLASS_ID" />

    <result property="className" column="CLASS_NAME" />

    <result property="classYear" column="CLASS_YEAR" />

    <association property="teacherEntity" column="TEACHER_ID" select="getTeacher"/>

    <collection property="studentList" column="CLASS_ID" javaType="ArrayList" ofType="StudentEntity" select="getStudentByClassID"/>

    </resultMap>

    <select id="getClassByID" parameterType="String" resultMap="classResultMap">

    SELECT * FROM CLASS_TBL CT WHERE CT.CLASS_ID = #{classID};

    </select>

    StudentMapper.xml文件部分内容:

    Xml代码

    <!-- java属性,数据库表字段之间的映射定义 -->

    <resultMap type="StudentEntity" id="studentResultMap">

    <id property="studentID" column="STUDENT_ID" />

    <result property="studentName" column="STUDENT_NAME" />

    <result property="studentSex" column="STUDENT_SEX" />

    <result property="studentBirthday" column="STUDENT_BIRTHDAY" />

    </resultMap> <!-- 查询学生list,根据班级id -->

    <select id="getStudentByClassID" parameterType="String" resultMap="studentResultMap">

    <include refid="selectStudentAll" /> WHERE ST.CLASS_ID = #{classID}

    </select>

    2.1.4.2使用resultMap实现聚集 使用resultMap,就需要重写一个sql,left join学生表。

    Xml代码

    <resultMap type="ClassEntity" id="classResultMap">

    <id property="classID" column="CLASS_ID" />

    <result property="className" column="CLASS_NAME" />

    <result property="classYear" column="CLASS_YEAR" />

    <association property="teacherEntity" column="TEACHER_ID" resultMap="teacherResultMap"/>

    <collection property="studentList" column="CLASS_ID" javaType="ArrayList" ofType="StudentEntity" resultMap="studentResultMap"/>

    </resultMap>

    <select id="getClassAndTeacherStudent" parameterType="String" resultMap="classResultMap">

    SELECT * FROM CLASS_TBL CT

    LEFT JOIN STUDENT_TBL ST

    ON CT.CLASS_ID = ST.CLASS_ID

     LEFT JOIN TEACHER_TBL TT

    ON CT.TEACHER_ID = TT.TEACHER_ID

    WHERE CT.CLASS_ID = #{classID};

    </select>

    多联表查询

    <resultMap type="Remark" id="remarkMap">

    <id property="remarkId" column="REMARK_ID" />

    <result property="starId" column="STAR_ID"/>

    <result property="userId" column="USER_ID"/>

    <result property="replyFor" column="REPLY_FOR"/>

    <association property="replyUser" javaType="AppUser" column="REPLY_FOR" select="getReplyFor">

    <id property="userId" column="USER_ID"/> </association>

    <association property="user" javaType="AppUser" column="USER_ID" select="getAppUser">

    <id property="userId" column="USER_ID"/>

    </association>

    <association property="star" javaType="Star" column="STAR_ID" select="getStar">

    <id property="starId" column="STAR_ID"/>

    </association>

    </resultMap>

    需要获得的结果

      <sql id="remark_columns"> REMARK_ID AS remarkId, STAR_ID, USER_ID, REPLY_FOR, OBJECT_TYPE AS objectType, OBJECT_ID AS objectId,

    CONTENT, TO_CHAR(TIME,'yyyy-mm-dd hh24:mi:ss') AS TIME, STATE </sql> 查询语句

      <select id="findToneByRemarkId" parameterType="int" resultMap="remarkMap">

       SELECT <include refid="remark_columns" /> FROM REMARK WHERE

    REMARK_ID=#{remarkId} 

     </select>

  • 相关阅读:
    Scala学习笔记(八):Scala的层级
    Scala学习笔记(七):闭包
    Scala学习笔记(六):函数
    Struts 2(八):文件上传
    Struts 2(七):国际化
    Struts 2(五):输入校验 & 校验框架
    Struts 2(四):类型转换
    Struts 2(三):示例→基于Struts 2的用户注册模块
    Struts 2(二):使用Struts2
    Struts 2(一):初识Struts
  • 原文地址:https://www.cnblogs.com/lhfyy/p/4076785.html
Copyright © 2011-2022 走看看