- spring整合mybatis的配置文件applicatonContext.xml:https://blog.csdn.net/IT_CREATE/article/details/85329007
- mybtis中的级联关系(关联关系、集合关系)association、collection(一对一关系、一对多关系、多对多关系):https://blog.csdn.net/IT_CREATE/article/details/86523101
- mybatis中动态sql的操作(where、foreach、if、set、choose、trim标签的使用):https://blog.csdn.net/IT_CREATE/article/details/86557260
- mybatis中的级联关系中的鉴别器(discriminator、case、result):https://blog.csdn.net/IT_CREATE/article/details/86561051
mybatis的xml的映射配置基本说明
mybatis是apache提供的开源持久层框架,原本是ibatis,后来改名了,它是用于与数据库进行交互。在使用mybatis的时候,最主要的就是这个怎么用,除了配置一些与数据库建立联系的基本配置applicatonContext.xml(spring整合mybatis的配置文件),最主要的的就是xml映射配置(就是增删改查怎么写的配置)。
用mybatis的时候,我们要用到mapper映射,也就是说,一个项目有持久层dao,业务层service,表现层contraller,现在加上一个mapper映射。创建一个mapper包,在mapper包中,定义接口和xml映射配置,接口要和xml映射配置文件名字一样,一 一对应。比如:假设你给接口名取名为UserMapper.java,那么xml配置文件也得取名为UserMapper.xml。
如:
在接口中,我们可以定义一些方法,这些方法主要就是用来与数据库进行交互,就是跟数据库进行增删改查的那些操作。并且我们在持久层dao中要用到这些方法。整个程序的调用顺序是:controller(表现层)-->service(业务层)-->dao(持久层)-->mapper(映射关系层)。所以mapper接口中的方法都是我们在dao(持久层)要进行调用的。
mybatis的xml的映射配置文件的具体介绍
在mybatis的xml配置中,分别有<insert></insert>、<delete></delete>、<update></update>、<select></select>四组标签对应增删改查的操作,然后在标签中写sql语句。这些标签都有id属性,这个属性对应的是接口中的方法名。看下面代码。
新增(insert):
接口方法:( @Param("u")就是给参数取别名,在xml映射配置中我们才能方便去使用这个参数,使用方法就是: 别名.属性)
//@Param("u") 给参数定义个别名
int addUserBean(@Param("u") UserBean user);
xml映射配置:
<!-- id就是接口的那些方法,实现哪个方法,id就是这个方法的方法名-->
<!-- useGeneratedKeys表示是否去获取自增id 可不写(仅对 insert 和 update 有用)-->
<!-- keyProperty表示获取的自增id保存在哪里 可不写(仅对 insert 和 update 有用)-->
<!-- parameterType表示如果传入的参数只有一个时,那么用它来指定传入参数的类型,
如果在传入参数中加入@Param()注解, 可不写-->
<insert id="addUserBean" useGeneratedKeys="true" keyProperty="u.id"
parameterType="UserBean">
insert into
t_user(login_name,user_name,user_pwd,age,gender,birthday,create_time)
values
(#{u.loginName},#{u.userName},#{u.password},#{u.age},#{u.gender},#{u.birthday},now());
</insert>
<!-- #{ }的作用就是取值的意思,传入对象就用#{别名.属性名};像对象这种层层结构的,
比如Map就有这种结构,就可以这样去取值;如果没有这种结构,比如字符串这种单一类型,直接用#{别名} -->
<!-- #{ }和${ }的作用都是取值,区别就是#{ }要进行预编译,而${ }直接编译-->
对于修改和删除的操作,跟新增是一样的,他们在执行操作完成之后,返回的都是受影响的条数。
修改和删除(update、delete):
修改和删除最常用的属性也就是:id和parameterType,但是parameterType一般情况下不用指定,只要在接口方法的参数上加上@Param()注解就可以了,多个参数多个注解区分就是了。
查询(select)
查询与前面的增删改操作略有不同。比如:
接口方法:(注解含义请看上面)
UserBean findUserBeanByLoginNameAndPwd(@Param("loginName")String loginName,@Param("pwd")String pwd);
xml映射配置:
<!-- <resultMap>标签,定义结果集中数据列与对象中的属性之间的映射关系 orm -->
<!-- <resultMap>标签的id属性是查询标签<select>的resultMap属性要用的,type是要映射的对象类型-->
<!-- <id>标签用来指定对象的id和表的id的映射,<result>标签就是对象其他属性与表中其他列的映射;
property指的是对象的属性,column指的是对应的表的列名,javaType指的是对象属性的类型-->
<resultMap type="UserBean" id="userMap">
<id property="id" column="id" javaType="java.lang.Integer" />
<result property="loginName" column="login_name" javaType="java.lang.String" />
<result property="userName" column="user_name" javaType="java.lang.String" />
<result property="password" column="user_pwd" javaType="string" />
<result property="age" column="age" javaType="int" />
<result property="gender" column="gender" javaType="int" />
<result property="birthday" column="birthday" javaType="java.util.Date" />
<result property="createTime" column="create_time" javaType="java.util.Date" />
</resultMap>
<!-- 定义结果查询方法,有两种接收结果方式:resultMap和resultType-->
<!-- 使用resultMap="userMap"就要用到上面的映射关系;如果用的是resultType的话,
传入的如果是对象,那么就要给sql语句的每列就要用as取别名,和对象的属性名保持一致;如果是Map,
取别名就以别名为键,不取别名默认以列名作为键名;如果是其他数据类型,比如本数据类型这些,那么查询的返回结果必须也是与之对应的单一结果,也就是一个结果-->
<select id="findUserBeanByLoginNameAndPwd" resultType="UserBean">
select
id,login_name as loginName,user_name as userName,age,gender,user_pwd
as password,birthday,create_time as createTime from t_user
where login_name = #{loginName} and user_pwd = #{pwd}
</select>
结果集映射:
<resultMap>标签,定义结果集中数据列与对象中的属性之间的映射关系 orm
<resultMap>标签的id属性是查询标签<select>的resultMap属性要用的,type是要和表要映射的对象类型
<id>标签用来指定对象的id和表的id的映射,<result>标签就是对象其他属性与表中其他列的映射
property指的是对象的属性,column指的是对应的标的列名,javaType指的是对象属性的类型
查询标签
<select>标签用于结果查询,查询了结果之后,我们总得有东西来装结果吧。select标签提供了两种接收结果方式:resultMap和resultType
1、resultMap接受结果,就要定义结果映射,把查询的列也就是from前面需查询的列和对象的属性对应起来,就要用到上面的结果集映射关系。比如:resultMap="userMap",就要用<resultMap>标签写结果集映射关系。
2、如果用的是resultType的话,传入的如果是对象,那么就要给sql语句的每列就要用as取别名,和对象的属性名保持一致;如果是Map,为列取了别名的就以别名为键,没取别名默认以列名作为键名。resultType可以是对象、Map、基本数据类型,引用数据类型。如果是后面两种的数据类型,把么查询结果返回只能是一个值,才能接收到。比如,只有一个数值返回,那么可以用int这些;只有一个字符串返回,可以用String;只有一个时间返回,可以用Data,最好写出类型的全路径,有些类型可以省略全路径,但是写上都不会报错。
四个标签的更多属性请参见mybatis官网:http://www.mybatis.org/mybatis-3/zh/index.html
完整的例子(单表):
在接口UserMapper中,定义了一些方法,在配置文件xml中去实现这些方法的增删改
public interface UserMapper {
//@Param("u") 给参数定义个别名
int addUserBean(@Param("u") UserBean user);
/**
* 批量新增
* @param users
* @return
*/
int addBatchUserBean(@Param("users") List<UserBean> users);
int updateUserBean(@Param("u") UserBean user);
int deleteUserBean(@Param("u") UserBean user);
/**
* 批量删除
* @param ids
* @return
*/
int deleteBatchUserBean(@Param("ids") int[] ids);
int deleteUserBeanById(@Param("id") Integer id);
UserBean getUserBeanById(@Param("id") Integer id);
UserBean findUserBeanByLoginNameAndPwd(@Param("loginName")String loginName,@Param("pwd")String pwd);
/**
* 多参数传递查询的方式一
* 按照对象传值
* @param user
* @return
*/
List<UserBean> findUserBeanByObject(@Param("u") UserBean user);
/**
* 多参数传递查询的方式二
* 按照Map传值
* @param map
* @return
*/
List<UserBean> findUserBeanByMap(@Param("m") Map map);
}
配置文件UserMaper.xml中,代码如下:
<?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的命名空间,建立和接口联系 -->
<mapper namespace="com.ali.mybatis01.usermag.mapper.UserMapper">
<!-- 定义结果集中数据列,与对象中的属性之间的映射关系 orm -->
<resultMap type="UserBean" id="userMap">
<id property="id" column="id" javaType="java.lang.Integer" />
<result property="loginName" column="login_name" javaType="java.lang.String" />
<result property="userName" column="user_name" javaType="java.lang.String" />
<result property="password" column="user_pwd" javaType="string" />
<result property="age" column="age" javaType="int" />
<result property="gender" column="gender" javaType="int" />
<result property="birthday" column="birthday" javaType="java.util.Date" />
<result property="createTime" column="create_time" javaType="java.util.Date" />
</resultMap>
<!-- id就是接口的那些方法,实现哪个方法,id就是这个方法的方法名-->
<!-- useGeneratedKeys表示是否去获取自增id 可不写-->
<!-- keyProperty表示获取的自增id保存在哪里 可不写-->
<insert id="addUserBean" useGeneratedKeys="true" keyProperty="u.id"
parameterType="UserBean">
insert into
t_user(login_name,user_name,user_pwd,age,gender,birthday,create_time)
values
(#{u.loginName},#{u.userName},#{u.password},#{u.age},#{u.gender},#{u.birthday},now());
</insert>
<insert id="addBatchUserBean">
<!-- 批量新增的语法:insert into 表 (列名列表) values (),(),()…… -->
insert into
t_user(login_name,user_name,user_pwd,age,gender,birthday,create_time)
values
<!-- 循环语句,类似我们java的 for(UserBean u,users){ } ,separator表示每个结果之间用什么隔开-->
<foreach collection="users" item="u" separator=",">
(#{u.loginName},#{u.userName},#{u.password},#{u.age},#{u.gender},#{u.birthday},now())
</foreach>
</insert>
<update id="updateUserBean">
update t_user
<!-- set-if判断,可以在修改的时候对指定列进行修改,而不是全部修改-->
<set>
<if test="u.loginName != null and u.loginName != ''">
login_name = #{u.loginName},
</if>
<if test="u.userName != null and u.userName != ''">
user_name = #{u.userName},
</if>
<if test="u.age != null">
age = #{u.age},
</if>
<if test="u.gender != null">
gender = #{u.gender},
</if>
<if test="u.password != null and u.password != ''">
user_pwd = #{u.password},
</if>
<if test="u.birthday != null">
birthday = #{u.birthday},
</if>
create_time = now(),
</set>
where id = #{u.id};
</update>
<delete id="deleteUserBean">
delete from t_user where id = #{u.id}
</delete>
<delete id="deleteUserBeanById">
delete from t_user where id = #{id}
</delete>
<delete id="deleteBatchUserBean">
<!-- 批量删除的语法:delete from 表 where id in (……) -->
<!-- collection 如果参数并未取参数别名,那么此处就要写成array 取了别名,那么就按照别名来写,例如:ids -->
delete from t_user where id in
<foreach collection="ids" item="id" open="(" close=")"
separator=",">
#{id}
</foreach>
<!-- foreach 该标记主要用于遍历集合或者数组,collection 属性代表需要遍历的集合或数组 item 代表每次遍历取出来的数据
open 代表遍历开始前,以什么符号开始, close 代表遍历结束后,以什么符号结束 separator 代表每次遍历的分隔符 -->
</delete>
<!-- 返回结果类型如果用的是 resultMap,那么必须去实现这个关于userMap的映射关系-->
<select id="getUserBeanById" resultMap="userMap">
select
id,login_name,user_name,age,gender,user_pwd,birthday,create_time from
t_user where id = #{id}
</select>
<!-- 返回结果类型如果用的是 resultType,里面可以是map,也就是键值对,键名就是列名或是列别名;也可以是其他对象,这里用了UserBean接收结果,那么查询的列别名必须和UserBean的属性名保持一致-->
<select id="findUserBeanByLoginNameAndPwd" resultType="UserBean">
select
id,login_name as loginName,user_name as userName,age,gender,user_pwd
as password,birthday,create_time as createTime from t_user
where login_name = #{loginName} and user_pwd = #{pwd}
</select>
<select id="findUserBeanByObject" resultMap="userMap">
select
id,login_name,user_name,age,gender,user_pwd,birthday,create_time from
t_user
<where>
<!-- choose when otherwise 等同于java中的switch case default -->
<choose>
<when test="u.userName != null && u.userName != ''">
and user_name like concat(#{u.userName},'%')
</when>
<when test="u.age != null">
and age = #{u.age}
</when>
<when test="u.gender != null">
and gender = #{u.gender}
</when>
<otherwise>
1=1
</otherwise>
</choose>
</where>
<!-- <where>
1 = 1
<if test="u.userName != null && u.userName != ''">
and user_name like concat(#{u.userName},'%')
</if>
<if test="u.age != null">
and age = #{u.age}
</if>
<if test="u.gender != null">
and gender = #{u.gender}
</if>
</where> -->
<!-- trim if 作用跟where if 非常的接近
prefix="where" 表示需要条件判断之前,以什么开始
prefixOverrides="and|or" 如果where 后直接跟and或者or ,那么将使用空字符串替换
<trim prefix="where" prefixOverrides="and|or">
<if test="u.userName != null && u.userName != ''">
and user_name like concat(#{u.userName},'%')
</if>
<if test="u.age != null">
and age = #{u.age}
</if>
<if test="u.gender != null">
and gender = #{u.gender}
</if>
</trim>
order by ${sort} ${order}-->
</select>
<!-- Map键值对传值,直接按照对象获取属性的方式,获得值就可以了 -->
<select id="findUserBeanByMap" resultMap="userMap">
select
id,login_name,user_name,age,gender,user_pwd,birthday,create_time from
t_user
<where>
1 = 1
<if test="m.userName != null && m.userName != ''">
and user_name like concat(#{m.userName},'%')
</if>
<if test="m.age != null">
and age = #{m.age}
</if>
<if test="m.gender != null">
and gender = #{m.gender}
</if>
</where>
</select>
</mapper>