一:搭建Mybatis环境
1.导入mybatis包
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.5</version>
</dependency>
2.MyBatis核心配置文件
<?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">
<configuration>
<!--取别名-->
<typeAliases>
<!-- 给某一个对象取别名
<typeAlias type="cn.itcast.mybatis.model.User" alias="User" /> -->
<!--给某个包下的所有对象取别名, 别名就是类的名字 -->
<package name="cn.itcast.mybatis.model" />
</typeAliases>
<!--数据源配置-->
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url"
value="jdbc:mysql://localhost:3306/demo/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</dataSource>
</environment>
</environments>
<!--映射文件指定-->
<mappers>
<mapper resource="cn/itcast/mybatis/mapper/UserMapper.xml" />
</mappers>
</configuration>
映射文件包扫描
1、当前接口和对应的Mapper.xml必须在同一包下
2、接口名字和Mapper.xml映射文件必须一样
<mappers>
<package name="cn.itcast.mybatis.mapper" /> </mappers>
接口扫描
1、class=类的全限定名
2、当前接口和对应的Mapper.xml必须在同一包下
3、接口名字和Mapper.xml映射文件必须一样
<mappers>
<mapper class="cn.itcast.mybatis.mapper.UserMapper"/>
</mappers>
3.MyBatis映射文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.itcast.mybatis.model.User">
<!-- addUser -->
<insert id="addUser" parameterType="cn.itcast.mybatis.model.User">
INSERT INTO user(username,userage)VALUES(#{username},#{userage})
</insert>
</mapper>
4.主策略
user表主键userid为int自增,增加用户后,程序获取主键自增的值
方法一:SelectKey获取主键
<!-- 在*Mapper.xml中增加如下代码 -->
/*
keyColumn:指定自增主键的列
keyProperty:指定入参的JavaBean的属性
order:执行的优先级顺序
AFTER:表示其他SQL语句执行完毕之后再执行selectKey
BEFORE:表示其他SQL语句执行完毕之前执行selectKey
*/
<insert id="addUserBackKeyOfIdentityForSQL" parameterType="cn.itcast.mybatis.model.User">
<selectKey keyColumn="userid" keyProperty="userid" resultType="int" order="AFTER">
SELECT LAST_INSERT_ID()
</selectKey>
INSERT INTO user(username,userage)VALUES(#{username},#{userage})
</insert>
---如果主键是UUID 则设置 resultType="string" select uuid()
方法二:属性配置
<!-- useGeneratedKeys:是否使用自增主键
keyProperty:主键值返回后和入参的哪个属性建立映射关系
-->
<insert id="addUserBackKeyOfIdentityForProperty" parameterType="cn.itcast.mybatis.model.User" useGeneratedKeys="true" keyProperty="userid">
INSERT INTO user(username,userage)VALUES(#{username},#{userage})
</insert>
二.MyBatis动态代理
动态代理约束
1.namespace必需是Dao接口的全限定名
2.接口的方法名必需与映射文件的节点id一致,节点:insert、select、update、delete
3.接口的方法输入参数必需与映射文件的parameterType类型一致
4.接口的方法返回类型必须与映射文件的resultType类型一致
<mapper namespace="DAO接口全限定名">
<select id="接口方法名" parameterType="接口输入参数" resultType="还回类型">
SELECT * FROM user WHERE userid=#{userid}
</select>
//获取UserDao的代理对象
userDao = session.getMapper(UserDao.class);
</mapper>
三. 动态sql
1.if语句
<select id="getUserByMap" parameterType="map" resultMap="UserResultMap">
SELECT * FROM USER
WHERE 1=1
<if test="user_name!=null">
AND user_name like CONCAT("%",#{user_name},"%")
</if>
<if test="user_age!=null">
AND userage=#{user_age}
</if>
</select>
2.choose, when, otherwise
如果id不为空则根据id查找
SELECT * FROM USER
WHERE 1=1
<choose>
<when test="user_id!=null">
AND userid=#{user_id}
</when>
<otherwise>
<if test="user_name!=null">
AND user_name like CONCAT("%",#{user_name},"%")
</if>
<if test="user_age!=null">
AND userage=#{user_age}
</if>
</otherwise>
</choose>
3.where
where可以替代 1=1 —-where包含其他sql语句
4.trim
trim功能和 where一样
<trim prefixOverrides="OR|AND" prefix="WHERE">
......其他slq语句 </trim>
5.set
根据判断动态修改数据
UPDATE USER
<set>
<if test="username!=null">
user_name=#{username},
</if>
<if test="userage!=null">
userage=#{userage},
</if>
</set>
WHERE
userid=#{userid}
6.foreach
SELECT * FROM USER
<foreach collection="array" item="uid" open="WHERE userid IN(" separator="," close=")">
#{uid}
</foreach>
7.sql片段
定义: <sql id="UserColumnSelect">
SELECT * FROM USER </sql>
引用: <include refid="UserColumnSelect" />
四. 映射关系
A.一对一关系映射
1.一次查询
<resultMap id="IdCardResultMap" type="IdCard">
<id column="cardId" property="cardId"/>
<result column="province" property="province" />
<result column="city" property="city" />
<!--
一对一映射配置
property:IdCard的属性
association:配置对应属性的映射关系,和resultMap配置一样
javaType:表示association的数据最终要转换的类型
-->
<association property="user" javaType="User">
<id column="userid" property="userid"/>
<result column="user_name" property="username"/>
<result column="userage" property="userage"/>
</association>
</resultMap>
<select id="getCardInfo" parameterType="string" resultMap="IdCardResultMap">
SELECT
card.cardId,card.province,card.city,u.*
FROM
idcard card
INNER JOIN
`user` u
ON
card.userid=u.userid
WHERE card.cardId=#{cardId}
</select>
</mapper>
2.二次查询
<!--IdCardResultMapOfSelect-->
<resultMap id="IdCardResultMapOfSelect" type="IdCard">
<id column="cardId" property="cardId"/>
<result column="province" property="province" />
<result column="city" property="city" />
<!--
一对一映射配置
property:IdCard的属性
association:配置对应属性的映射关系
select:调用id=getUserById的select节点
column:调用外部查询的时候将当前查询出的userid列的值传入过去
注:association这里不需要设置转换类型,因为id=getUserById的select节点返回的resultType指明了User类型
-->
<association property="user" select="getUserById" column="userid" />
</resultMap>
<!--getIdCardByIdOfSelect-->
<select id="getIdCardByIdOfSelect" parameterType="string" resultMap="IdCardResultMapOfSelect">
SELECT * FROM idcard WHERE cardId=#{cardId}
</select>
<!--getUserById-->
<select id="getUserById" parameterType="int" resultType="User">
SELECT userid,user_name username,userage FROM `user` WHERE userid=#{userid}
</select>
B.一对多映射
1.一次查询
<resultMap id="UserResultMap" type="User">
<id column="userid" property="userid"/>
<result column="user_name" property="username"/>
<result column="userage" property="userage"/>
<!--
一对多关系映射
collection:实现一对多集合映射关系
property:User对应的属性
ofType:当前映射所要转的类型
-->
<collection property="mobiles" ofType="Mobile">
<id column="mnumber" property="mnumber"/>
<result column="mname" property="mname"/>
</collection>
</resultMap>
<!--getUserById-->
<select id="getUserById" parameterType="int" resultMap="UserResultMap">
SELECT u.userid,u.user_name,u.userage,m.* FROM `user` u LEFT JOIN mobile m ON u.userid=m.userid WHERE u.userid=#{userid}
</select>
2.二次查询
<resultMap id="UserResultMapOfSelect" type="User">
<id column="userid" property="userid"/>
<result column="user_name" property="username"/>
<result column="userage" property="userage"/>
<!--
一对多关系映射
collection:实现一对多集合映射关系
property:User对应的属性mobiles
column:将查询出来的列userid的值作为参数传给id=getMobilesByUserId的查询节点
-->
<collection property="mobiles" select="getMobilesByUserId" column="userid" />
</resultMap>
<!--getUserByIdOfSelect-->
<select id="getUserByIdOfSelect" parameterType="int" resultMap="UserResultMapOfSelect">
SELECT * FROM `user` WHERE userid=#{userid}
</select>
<!--getMobilesByUserId-->
<select id="getMobilesByUserId" parameterType="int" resultType="Mobile">
SELECT * FROM mobile WHERE userid =#{userid}
</select>
数据库字段和属性不一致
方法一:取别名
SELECT userid,user_name username,userage FROM USER
方法二:添加resultMap节点
其他地方通过ID调用,type=”User”表示该resultMap最终映射的类型
column数据库的字段,propertyJavaBean的属性名。
id主要用来映射主键列和属性对应关系,有去除重复的功能。
<resultMap id="UserResultMap" type="User">
<id column="userid" property="userid"/>
<result column="user_name" property="username" />
<result column="userage" property="userage" />
</resultMap>
—resultType换成了resultMap,resultMap的值换成resultMap节点的id值
注: IDEA是不会编译src的java目录的xml文件,如果需要读取,要在xml里的bulid加入代码
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
</resource>
</resources>