网站首页 > 技术文章 正文
Mybatis映射文件
增删改查
简单地增删改查
<select id="selectUser" resultType="User">
select * from `user` where id = #{id}
</select>
<insert id="addUser">
insert into `user` (`name`,account) values (#{name},#{account})
</insert>
<update id="updateUser">
update `user` set `name` = #{name}, account = #{account} where id = #{id}
</update>
<delete id="deleteUser">
delete from `user` where id = #{id}
</delete>
使用factory.openSession()得到的sqlSession默认不会自动提交,需要手动的提交事务
使用factory.openSession(true)得到的sqlSession自动提交
select详细属性
<!--
id 命名空间的唯一标识,一般为方法名
parameterType 入参类型,该参数可选,mybatis通过类型处理器TypeHandler推断出具体传入的参数
resultType 返回结果的类全限定名或别名(如果为集合,应设置为集合包含的类型,而不是集合本身的类型)
resultMap 结果映射(resultType和ResultMap只能同时使用一个)
flushCache 设置为true,该语句被调用后清空本地缓存和二级缓存,默认false
useCache 设置为true,该语句结果被二级缓存缓存 select语句默认true
timeout 等待数据库返回的超时时间
fetchSize 批量返回的行数
statementType 可选STATEMENT/PREPARED/CALLABLE 分别对应于Statement/PreparedStatement/CallaleStatement 默认PREPARED
resultSetType FORWARD_ONLY/SCROLL_SENSITIVE/SCROLL_INSENSITIVE/DEFAULT
databaseId 数据库厂商id
resultOrdered 只针对于嵌套结果select语句:如果为true,将会假设包含了嵌套结果集或是分组,当返回一个主结果行时,就不会产生对前面结果集的引用 默认false
resultSets 针对于多结果集的情况。将列出语句执行后返回的结果集并赋予每个结果集一个名称,多个名称逗号隔开
-->
<select
id="selectUser"
parameterType="int"
resultType="hashmap"
resultMap="personResultMap"
flushCache="false"
useCache="true"
timeout="10"
fetchSize="256"
statementType="PREPARED"
resultSetType="FORWARD_ONLY">
insert/update/delete详细属性
<!--
id 命名空间的唯一标识,一般为方法名
parameterType 入参类型,该参数可选,mybatis通过类型处理器TypeHandler推断出具体传入的参数
flushCache 设置为true,该语句被调用后清空本地缓存和二级缓存, insert、update、delete语句默认false
timeout 等待数据库返回的超时时间
statementType 可选STATEMENT/PREPARED/CALLABLE 分别对应于Statement/PreparedStatement/CallaleStatement 默认PREPARED
databaseId 数据库厂商id
useGeneratedKeys 使用JDBC的getGeneratedKeys方法来获取数据库生成的主键,默认false
keyProperty 指定对象的主键属性,将getGeneratedKeys的返回值赋给该属性,如果生成列不止一个,使用逗号隔开
keyColumn 指定生成键值在数据库中的列名,如果生成列不止一个,用逗号隔开
-->
<insert
id="insertAuthor"
parameterType="domain.blog.Author"
flushCache="true"
statementType="PREPARED"
keyProperty=""
keyColumn=""
useGeneratedKeys=""
timeout="20">
<update
id="updateAuthor"
parameterType="domain.blog.Author"
flushCache="true"
statementType="PREPARED"
timeout="20">
<delete
id="deleteAuthor"
parameterType="domain.blog.Author"
flushCache="true"
statementType="PREPARED"
timeout="20">
插入扩展
获取自增id
默认情况下,插入数据后无法获取自增属性的主键id
<!--
自增主键,mybatis利用statement.getGeneratedKeys()来获取
useGeneratedKeys="true" 使用自增主键获取主键值策略
keyProperty 指定对应的主键属性,mybatis获取到主键值后,将值赋给该属性
-->
<insert id="addUserReturnGeneratedKey" useGeneratedKeys="true" keyProperty="id">
insert into `user` (`name`,account) values (#{name},#{account})
</insert>
不支持自增主键的方式
<!--
不支持自增主键的方式
-->
<insert id="addUserReturnGeneratedKey" databaseId="oracle">
<!-- 使用selectKey来获取主键序列值
keyProperty 指定对应的主键属性,mybatis获取到主键值后,将值赋给该属性
order before表示当前sql在插入sql之前
after表示当前sql在插入sql之后
resultType 查出来的数据返回值类型
-->
<selectKey keyProperty="id" order="BEFORE" resultType="Integer">
select user_seq.nextval from dual
</selectKey>
insert into `user` (id,`name`,account) values (#{id},#{name},#{account})
</insert>
参数处理
普通的数据类型
User selectUserByIdAndName(@Param("id") int id,@Param("name") String name);
<!-- 测试多个参数取值
mybatis默认将多个参数封装为一个map
map的key为param1~paramN
map的value为传入的参数值
#{}使用的是map的key来取值
可以使用命名参数来明确指定封装成map时的key @Param("id") @Param("name")
map的key为@Param注解指定的名称
map的value为传入的参数值
-->
<select id="selectUserByIdAndName" resultType="User">
select * from user where id = #{id} and name = #{name}
</select>
自定义的java对象数据类型
对于很多入参的情况,不希望方法的入参那么多,而且需要指定@Param参数,可以将这些入参封装为一个对象.
对于对象,可以直接使用字段来进行获取
User selectUserByCondition(User user);
<select id="selectUserByCondition" resultType="User">
select * from user
<where>
<if test="id != null and id != 0">
and id = #{id}
</if>
<if test="name != null">
and name = #{name}
</if>
<if test="account != null and account != 0">
and account = #{account}
</if>
</where>
</select>
集合属性
对于List,mybatis会映射为list,可以通过list来获取集合中的值
List<User> selectByIds(List<Integer> ids);
<select id="selectByIds" resultType="User">
select * from user
<where>
id in
<foreach collection="list" index="index" item="item" open="(" separator="," close=")">
#{item}
</foreach>
</where>
</select>
结果映射
resultMap和resultType都是作为结果集返回映射
ResultType
使用map
很多情况下使用map作为返回是可以支持的,但是map不是一个很好的领域模型,在获取到数据库结果之后,还需要再去人工的从map中取值给业务需要的字段去赋值,是一件痛苦而繁琐的事情
<select id="selectUser" resultType="map">
select * from user where id = #{id}
</select>
使用PO
使用PO进行接收结果集时,考虑到数据库中的列名可能与po中的字段名不一致,需要为每个字段起别名,sql写起来就变长了很多
<select id="selectUser" resultType="User">
select user_id as id,user_name as userName,
from user where id = #{id}
</select>
ResultMap
由于在使用ResultType时有一些的问题,而且ResultType对于一些复杂的查询结果来说处理起来也并不友好,ResultMap自定义映射的好处就凸显出来了。
<resultMap id="user" type="com.zhanghe.study.mybatis.model.User">
<!--
id定义主键
column 指定数据库的列名
property 指定java的属性名
-->
<id column="id" property="id"/>
<!-- 普通的列 -->
<result column="name" property="name"/>
<result column="account" property="account"/>
</resultMap>
<select id="selectUserReturnResultMap" resultMap="user">
select * from `user` where id = #{id}
</select>
关联查询一对一
public class Employee {
private Integer id;
private String name;
private double salary;
private Department department;
}
public class Department {
private Integer id;
private String name;
}
级联属性封装
<!-- 级联查询 -->
<resultMap id="emp1" type="com.zhanghe.study.mybatis.model.Employee">
<id column="id" property="id"/>
<result column="name" property="name"/>
<result column="salary" property="salary"/>
<!-- 使用属性.属性来获取 -->
<result column="did" property="department.id"/>
<result column="dname" property="department.name"/>
</resultMap>
<select id="getEmpAndDep" resultMap="emp1">
select emp.id id,emp.name name,emp.salary salary,emp.dep_id did,dep.name dname from employee emp join department dep on emp.dep_id = dep.id
where emp.id = #{id}
</select>
使用association进行join查询
<resultMap id="emp2" type="com.zhanghe.study.mybatis.model.Employee">
<id column="id" property="id"/>
<result column="name" property="name"/>
<result column="salary" property="salary"/>
<!-- 指定该字段的类型 -->
<association property="department" javaType="com.zhanghe.study.mybatis.model.Department">
<id column="did" property="id"/>
<result column="dname" property="name"/>
</association>
</resultMap>
<select id="getEmpAndDep" resultMap="emp2">
select emp.id id,emp.name name,emp.salary salary,emp.dep_id did,dep.name dname from employee emp join department dep on emp.dep_id = dep.id
where emp.id = #{id}
</select>
使用association进行分步查询
使用分步查询会执行多条sql语句,先查询出主表,之后将关联列作为条件去查询字表信息
EmployeeMapper的映射文件
<resultMap id="emp3" type="com.zhanghe.study.mybatis.model.Employee">
<id column="id" property="id"/>
<result column="name" property="name"/>
<result column="salary" property="salary"/>
<!-- select 当前属性使用select调用的方法
column 指定将那一列的值作为参数传入select语句
-->
<association property="department" column="dep_id"
select="com.zhanghe.study.mybatis.mapper.DepartmentMapper.selectDepById">
<id column="did" property="id"/>
<result column="dname" property="name"/>
</association>
</resultMap>
<select id="getEmpAndDep" resultMap="emp3">
select * from employee where id = #{id}
</select>
DepartmentMapper的映射文件
<resultMap id="dep" type="com.zhanghe.study.mybatis.model.Department">
<id column="id" property="id"/>
<result column="name" property="name"/>
</resultMap>
<select id="selectDepById" resultMap="dep">
select * from department where id = #{id}
</select>
分步查询延迟加载
在使用子表信息的时候在进行查询
在全局配置中开启延迟加载
<settings>
<setting name="logImpl" value="STDOUT_LOGGING"/>
<!-- 延迟加载的全局开关。当开启时,所有关联对象都会延迟加载。 特定关联关系中可通过设置 fetchType 属性来覆盖该项的开关状态。 -->
<setting name="lazyLoadingEnabled" value="true"/>
<!-- 开启时,任一方法的调用都会加载该对象的所有延迟加载属性。 否则,每个延迟加载属性会按需加载 -->
<setting name="aggressiveLazyLoading" value="false"/>
</settings>
关联查询一对多
使用collection标签
DepartmentMapper的映射文件
<resultMap id="dep1" type="com.zhanghe.study.mybatis.model.Department">
<id column="id" property="id"/>
<result column="name" property="name"/>
<!-- select 当前属性使用select调用的方法
column 指定将那一列的值作为参数传入select语句(如果需要多个条件使用{key1=value1,key2=value2})
-->
<collection property="employeeList" select="com.zhanghe.study.mybatis.mapper.EmployeeMapper.getEmployeeByDid"
column="id">
<id column="id" property="id"/>
<result column="name" property="name"/>
<result column="salary" property="salary"/>
<result column="did" property="department.id"/>
</collection>
</resultMap>
<select id="getDepAndEmps" resultMap="dep1">
select * from department where id = #{id}
</select>
EmployeeMapper的映射文件
<resultMap id="emp" type="com.zhanghe.study.mybatis.model.Employee">
<id column="id" property="id"/>
<result column="name" property="name"/>
<result column="salary" property="salary"/>
</resultMap>
<select id="getEmployeeByDid" resultMap="emp">
select * from employee where dep_id = #{did}
</select>
猜你喜欢
- 2024-10-27 一文看懂mycat配置--数据库的读写分离、分表分库
- 2024-10-27 基于Percona XtraBackup 实现全备&增量备份与恢复
- 2024-10-27 Java EE核心框架实战:如何使用MyBatis实现CURD-2种数据库
- 2024-10-27 mysql如何进行累加计算 mysql 变量累加
- 2024-10-27 Springboot集成Mybatis ID生成策略注解 @GeneratedValue
- 2024-10-27 mybatis插入获取主键的方式和原理
- 2024-10-27 mybatis-plus保姆级入门教程,手把手教你轻松实现增删改查
- 2024-10-27 MyBatis框架 - 映射文件 mybatis如何映射表结构
- 2024-10-27 数据库操作语言SQL数据处理的增、查、删、改
- 2024-10-27 终于等到你:CYQ.Data V5系列 (ORM数据层)最新版本开源了
你 发表评论:
欢迎- 633℃几个Oracle空值处理函数 oracle处理null值的函数
- 626℃Oracle分析函数之Lag和Lead()使用
- 614℃0497-如何将Kerberos的CDH6.1从Oracle JDK 1.8迁移至OpenJDK 1.8
- 608℃Oracle数据库的单、多行函数 oracle执行多个sql语句
- 606℃Oracle 12c PDB迁移(一) oracle迁移到oceanbase
- 599℃【数据统计分析】详解Oracle分组函数之CUBE
- 588℃最佳实践 | 提效 47 倍,制造业生产 Oracle 迁移替换
- 574℃Oracle有哪些常见的函数? oracle中常用的函数
- 最近发表
-
- oracle 19cOCM认证有哪些内容(oracle认证ocm月薪)
- Oracle新出AI课程认证,转型要持续学习
- oracle 表的查询join顺序,可能会影响查询效率
- Oracle DatabaseAmazon Web Services正式可用,Oracle数据库上云更容易了
- Oracle 19.28 RU 升级最佳实践指南
- 汉得信息:发布EBS系统安装启用JWS的高效解决方案
- 如何主导设计一个亿级高并发系统架构-数据存储架构(三)
- Java 后端开发必看!工厂设计模式轻松拿捏
- ORA-00600 「25027」 「x」报错(抱错孩子电视剧 爸爸是武术 另一个爸爸是画家)
- 新项目终于用上了jdk24(jdk新建项目)
- 标签列表
-
- 前端设计模式 (75)
- 前端性能优化 (51)
- 前端模板 (66)
- 前端跨域 (52)
- 前端缓存 (63)
- 前端aes加密 (58)
- 前端脚手架 (56)
- 前端md5加密 (54)
- 前端路由 (61)
- 前端数组 (73)
- 前端js面试题 (50)
- 前端定时器 (59)
- 前端获取当前时间 (50)
- Oracle RAC (76)
- oracle恢复 (77)
- oracle 删除表 (52)
- oracle 用户名 (80)
- oracle 工具 (55)
- oracle 内存 (55)
- oracle 导出表 (62)
- oracle约束 (54)
- oracle 中文 (51)
- oracle链接 (54)
- oracle的函数 (58)
- 前端调试 (52)
本文暂时没有评论,来添加一个吧(●'◡'●)