MyBatis总结
-
什么是MyBatis?
MyBatis是支持自定义SQL、存储过程以及高级映射的优秀的持久层框架。MyBatis避免了几乎所有的JDBC代码和手动设置参数以及获取结果集。MyBatis可以使用简单的XML或注解用于配置和原始映射,将接口和Java的POJO(Plain Old Java Objects,普通的Java对象)映射成数据库中的记录,是半自动化持久层框架。
-
MyBatis中的主要组成部分
SqlSessionFactory:用于创建等SqlSession;等同于多个数据库的连接池(整个MySQL),在整个MyBatis的生命周期中,如果创建多个,则会耗光连接池,造成应用崩溃,一般为单例模式,整个应用进行共享。
SqlSessionFactory创建代码示例:
InputStream in = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);
SqlSession:对数据库进行增、删、改、查操作;如果使用完,则会把连接返还给SqlSessionFactory连接池。
SqlSession创建代码示例:
SqlSession sqlSession = sqlSessionFactory.openSession();
MyBatis配置
设置(settings)
主要作用:设置MyBatis日志、缓存等一些功能
设置(settings)代码示例:
<settings >
<setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>
- 类型别名(typeAliases)
主要作用:为实体类设置别名
类型别名(typeAliases)代码示例:
<typeAliases>
<!-- 用法1:为单个实体类设置别名-->
<typeAlias type="com.apesource.entity.Employee" alias="Employee"/>
<typeAlias type="com.apesource.entity.Order" alias="Order"/>
<!-- 用法2:为整个包下的实体类设置别名-->
<package name="com.apesource.entity"/>
</typeAliases>
- 环境配置(environments)
主要作用:配置连接数据库环境
环境配置(environments)代码示例:
<environments default="development">
<environment id="development">
<!-- 事务管理器 -->
<transactionManager type="JDBC"/>
<!-- 数据源 -->
<dataSource type="POOLED">
<!-- 驱动类 -->
<property name="driver" value="${driver_class}"/>
<!-- 数据库连接 -->
<property name="url" value="${jdbc_url}"/>
<!-- 数据库用户名和密码 -->
<property name="username" value="${db_username}"/>
<property name="password" value="${db_password}"/>
</dataSource>
</environment>
<environment>
...
</environment>
</environments>
- 映射器(mappers)
主要作用:引入SQL语句对应的映射文件
映射器(mappers)代码示例:
<mappers>
<mapper resource="com/apesource/dao/mapper/EmployeeMapper.xml"/>
<mapper resource="com/apesource/dao/mapper/OrderMapper.xml"/>
</mappers>
MyBatis XML 映射器
1.常用节点作用总结
- select :查询数据,数据库字段名和类中的属性名须保持一致,否则会映射失败;可以使用
<resultMap></resultMap>节点来手动映射
<select id="" resultType=""></select>
- update:修改数据
<update id="" parameterType=""></update>
- delete:删除数据
<delete id="deleteAnswerRecord" parameterType="int"> </delete>
- insert:添加数据
<insert id="" parameterType="" useGeneratedKeys="" keyProperty=""></insert>
2.常用属性作用总结
- id 属性:SQL语句的名字,与接口中的方法名保持一致;
- resultType 属性:返回结果类型,可以是int、String或者自定义类型;
- parameterType 属性:传入的参数类型,可以是int、String或者自定义类型,如果闯入多个参数需要使用@Param(“ ”);
- useGeneratedKeys属性:主键回填,获取生成的主键;
- keyProperty属性:会根据useGeneratedKeys的返回值,标记一个属性返回值,默认不开启;
3.常见SQL映射示例
- 示例1:普通增加
<!-- 添加新答题记录 -->
<!-- parameterType:设置添加操作时使用的实体类(别名) -->
<!-- useGeneratedKeys:开启主键回填 -->
<!-- keyProperty: 设置主键回填的属性名称 -->
<insert id="insertAnswerRecord" parameterType="AnswerRecord"
useGeneratedKeys="true" keyProperty="recordId">
INSERT INTO answer_record(respondent,
question,
right_answer,
submit_answer,
submit_datetime)
VALUES(#{respondent},#{question},#{rightAnswer},#{submitAnswer},now())
</insert>
/**
* 添加新答题记录
* @param answerRecord 答题记录对象
* @return 影响行数
* ps.测试时需要输出新答题记录的编号
*/
int insertAnswerRecord(AnswerRecord answerRecord);
- 示例2:批量增加
<!-- foreach:用于动态SQL中的循环遍历,collection指定遍历的集合类型,
item为每次循环遍历的元素命名 -->
<insert id="insertAnswerRecordBatch" parameterType="list"
useGeneratedKeys="true" keyProperty="recordId">
INSERT INTO answer_record(respondent,
question,
right_answer,
submit_answer,
submit_datetime)
VALUES
<foreach collection="list" item="record" separator=",">
(
#{record.respondent},
#{record.question},
#{record.rightAnswer},
#{record.submitAnswer},
now()
)
</foreach>
</insert>
/**
* 批量添加新答题记录
* @param answerRecordList 添加数据集合
* @return 影响行数
*/
int insertAnswerRecordBatch(List<AnswerRecord> answerRecordList);
- 示例3:普通删除
<delete id="deleteAnswerRecord" parameterType="int">
DELETE FROM answer_record
WHERE record_id = #{recordId}
</delete>
/**
* 删除答题记录
* @param recordId 答题记录编号
* @return 影响行数
*/
int deleteAnswerRecord(int recordId);
- 示例4:批量删除
<delete id="deleteAnswerRecordBatch" parameterType="list">
DELETE FROM answer_record
WHERE record_id IN
<foreach collection="list" item="rid" separator="," open="(" close=")">
#{rid}
</foreach>
</delete>
/**
* 批量删除答题记录
* @param recordIdList
* @return
*/
int deleteAnswerRecordBatch(List<Integer> recordIdList);
示例5:动态修改
<!-- set节点用于动态处理update语句中的set -->
<!-- if节点用于条件判断 -->
<update id="updateAnswerRecord" parameterType="AnswerRecord">
UPDATE answer_record
<set>
<if test="respondent != null">
respondent = #{respondent},
</if>
<if test="question != null">
question = #{question},
</if>
<if test="rightAnswer != null">
right_answer = #{rightAnswer} ,
</if>
<if test="submitAnswer != null">
submit_answer = #{submitAnswer},
</if>
submit_datetime = now()
</set>
WHERE record_id = #{recordId}
</update>
/**
* 修改答题记录
* @param answerRecord 答题记录对象(包含答题记录编号)
* @return 影响行数
*/
int updateAnswerRecord(AnswerRecord answerRecord);
- 示例6:动态查询
<!-- where节点:处理where子句和条件之间的关系 -->
<select id="listAnswerRecordByCondition" resultType="AnswerRecord" parameterType="AnswerRecord">
SELECT record_id as recordId,
respondent,
question,
right_answer as rightAnswer,
submit_answer as submitAnswer,
submit_datetime as submitDatetime
FROM answer_record
<where>
<if test="respondent != null">
AND respondent = #{respondent}
</if>
<if test="question != null">
AND question LIKE concat('%', #{question} ,'%')
</if>
<if test="rightAnswer != null">
AND right_answer = #{rightAnswer}
</if>
<if test="submitAnswer != null">
AND submit_answer = #{submitAnswer}
</if>
</where>
</select>
/**
* 按照条件对象中的多条件值,动态查询
* @param condition 条件对象
* @return 答题记录集合
*/
List<AnswerRecord> listAnswerRecordByCondition(AnswerRecord condition);
- 示例7:查询结果封装为Map
<select id="countAnswerRecordDataByRespondent" resultType="map" >
SELECT COUNT(record_id) as allAnswer,
(SELECT COUNT(record_id)
FROM answer_record
WHERE respondent = #{respondent} AND
right_answer = submit_answer) as trueAnswer,
(SELECT COUNT(record_id)
FROM answer_record
WHERE respondent = #{respondent} AND
right_answer != submit_answer) as falseAnswer
FROM answer_record
WHERE respondent = #{respondent}
</select>
/**
* 按照答题者姓名,统计该答题者的总答题数目、正确题目数目、错误题目数目
* @param respondent
* @return
*/
Map<String,Integer> countAnswerRecordDataByRespondent(String respondent);