所有代码
- 学MyBatis时,练习的所有代码都在此了【MyBatis_Maven_Two】,我会尽可能的打上注释。
- 使一个Maven项目,使用工具IDEA,使用MySQL数据库
输入参数和输出参数
传递简单类型参数
- 使用#{}占位符,或者${}进行sql拼接。(order by id 必须使用${})
- 如果传递多个简单类型,使用
@Param
注解实现- 注意:输出简单类型必须查询出来的结果集有一条记录,最终将第一个字段的值转换为输出类型。
传递pojo对象
- #{}或者${}括号中的值为pojo实体类中的属性名称。
传递pojo包装的对象
- 包装对象:Pojo类中的一个属性是另外一个pojo。
- 例:QueryVo中放一个user对象属性。
传递map集合
- map集合中
- 注意:map的key要和sql中的占位符保持名字一致。
resultMap
- resultType可以指定将查询结果映射为pojo,但需要pojo的属性名和sql查询的列名
必须一致
才可映射成功。- 如果sql查询字段名和pojo的属性名
不一致
,那么就取不到值,为空。解决方法
:可以通过resultMap
标签将字段名和属性名设置成一个对应关系 ,resultMap实质上还需要将查询结果映射到pojo对象中。- resultMap可以实现将查询结果映射为复杂类型的pojo,比如在查询结果映射对象中包括pojo和list实现
一对一
查询和一对多
查询。
其他方法
- 使用
<setting>
标签,添加到mybatis的配置文件中,也可处理该问题。
<settings> <!--下划线转驼峰命名法,默认false--> <setting name="mapUnderscoreToCamelCase" value="true"/> </settings>
或者
- 在
<resultMap>
表键中使用autoMapping="true"
属性,将自动加载其他属性
<resultMap>
中最少写一个属性,否则会报错。原因不明
<resultMap id="user_order" type="User" autoMapping="true"> <id property="id" column="id"></id> <!-- 其他属性可以不写,使用autoMapping自动将同名的属性和列映射在一块 --> </resultMap>
MyBatis类型解析
- 第一:mybatis自动处理java.util.Date
- 第二:mybatis自动识别1:0为true/false。数据库中存1/0,java中直接收true/false
- 第三:parameterType 和 resultType 解析
- parameterType类型:jdk8中基本类型+String :double,float,int,short,boolean,long,date,string
- 原理:
- 1>会类型字符转小写,TypeAliasRegistry初始化构造方法中注册了很多类型,先从中检查
- 2>如果如上没有,则用Resources.classForName(string)通过反射得到类型(核心原理是 Class.forName()类加载)
类型转换器
- 每当MyBatis设置参数到
PrepareStatement
或者从ResultSet
结果集中取值时,就会用到TypeHandler
来处理数据库类型与Java类型之间的转换。- MyBatis类型转换器适用于Java实体类中的类型和数据库中的类型不对应时。
- 下图是默认的TypeHandler:
代码实现
- 实现TypeHandler类
- 在mybatis的配置文件中添加类型转换器
- 代码项目中都有
<!--全局注册类型转换器--> <typeHandlers> <typeHandler handler="com.xx.convert.AddressHandler" javaType="com.xx.pojo.Address" jdbcType="VARCHAR"></typeHandler> </typeHandlers>
动态sql(重点)
作用
- 通过mybatis提供的各种标签方法实现
动态拼接sql
。
标签
- If标签
- 注意字符串类型的数据需要做不等于空字符串校验。
- 语法:
<if test="条件"> </if>
- Where标签
- 该标签自动添加where,同时处理SQL语句中第一and和or关键字
- 语法:
<where> <if test=''> </if> </where>
- forEach标签
- 该标签循环遍历解析数据
- 例:改造QueryVo类,添加集合属性,并添加get、set方法。
- 可以通过forEach解析拿到
- 语法:
<foreach collection="接收那个类型的数据" item="item" open="(" close=")" separator=","> #{item} </foreach>
- 剩余标签
- choose (when, otherwise)类似Java的switch语句
- trim (是一个格式化的标记,可以完成set或者是where标记的功能)
- set (update中的set)
- 其他标签可以参考这个博客【YSOcean】,讲的很详细。
sql片段
- Sql中可将重复的sql提取出来,使用时用include引用即可,最终达到sql重用的目的。
- 语法:
<sql id="xx">重复SQL语句</sql> <!--引用--> <include refid="xx"/>
关联查询
表之前的关系包括:一对一、一对多、多对多
一对一查询
- 需求:查询所有订单信息,关联查询下单用户信息。
- 注意:因为一个订单信息只会是一个人下的订单,所以从查询订单信息出发关联查询用户信息为一对一查询。如果从用户信息出发查询用户下的订单信息则为一对多查询,因为一个用户可以下多个订单
- 使用sql语句:
- SELECT o.id,o.user_id userId, o.number,o.createtime,o.note,u.username,u.address FROM orders o LEFT JOIN user u ON o.user_id = u.id
方法一:使用resultType
- 使用resultType,改造订单pojo类,此pojo类中包括了订单信息和用户信息
- 这样返回对象的时候,mybatis自动把用户信息也注入进来了
- OrderUser类继承Order类后OrderUser类包括了Order类的所有字段,只需要定义用户的信息字段即可
- 在UserMapper.xml添加sql,如下:
<!-- 查询订单,同时包含用户数据 --> <select id="queryOrderUser" resultType="orderUser"> SELECT o.id,o.user_id,userId,o.number, o.createtime,o.note,u.username,u.address FROM `order` o LEFT JOIN `user` u ON o.user_id = u.id </select>
- 定义专门的pojo类作为输出类型,其中定义了sql查询结果集所有的字段。此方法较为简单。
方法二:使用resultMap(推荐使用)
- 使用resultMap,定义专门的resultMap用于映射一对一查询结果。
- 改造pojo类
- 在
Order类
中加入User
属性,user属性中用于存储关联查询的用户信息,因为订单关联查询用户是一对一关系,所以这里使用单个User对象存储关联查询的用户信息。- 这里resultMap指定orderUserResultMap,如下:
<resultMap type="order" id="orderUserResultMap"> <id property="id" column="id" /> <result property="userId" column="user_id" /> <result property="number" column="number" /> <result property="createtime" column="createtime" /> <result property="note" column="note" /> <!-- association :配置一对一属性 --> <!-- property:order里面的User属性名 --> <!-- javaType:属性类型 --> <association property="user" javaType="user"> <!-- id:声明主键,表示user_id是关联查询对象的唯一标识--> <id property="id" column="user_id" /> <result property="username" column="username" /> <result property="address" column="address" /> </association> </resultMap>
一对多
- 查询所有用户信息及用户关联的订单信息。
- 用户信息和订单信息为一对多关系。
- sql语句:
- SELECT u.id,u.username,u.birthday,u.sex,
- u.address,o.id oid,o.number,o.createtime,o.note
- FROM user u
- LEFT JOIN order o ON u.id = o.user_id
- 修改pojo类,在User类中添加
List<Orders> orders
属性- UserMapper.xml映射文件中添加:
<resultMap type="user" id="userOrderResultMap"> <id property="id" column="id" /> <result property="username" column="username" /> <result property="birthday" column="birthday" /> <result property="sex" column="sex" /> <result property="address" column="address" /> <!-- 配置一对多的关系 --> <collection property="orders" javaType="list" ofType="order"> <!-- 配置主键,是关联Order的唯一标识 --> <id property="id" column="oid" /> <result property="number" column="number" /> <result property="createtime" column="createtime" /> <result property="note" column="note" /> </collection> </resultMap>
MyBatis的注解开发方式(了解)
- 从MyBatis3开始,注解提供了一种简单的方式来实现简单映射语句,这种方式不会引入大量的开销。但是灵活性较差,不易扩展。
- Mybatis常用注解对应的目标和标签如表所示:
注解 目标 对应的XML标签 @Select 方法 <select>
@Insert 方法 <insert>
@Update 方法 <update>
@Delete 方法 <delete>
@Param 参数 无 @SelectKey 方法 <selectKey>
@One 方法 <association>
@Many 方法 <collection>