首先导入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>