本文集各家之长,自学整理,若有错误,欢迎留言指出!!!
<mapper namespace="com.scau.demo.mapper.UserMapper">
## ...具体内容...
mapper>
其中,namespace
用于绑定Mapper接口。不同mapper接口对应到不同的xml。
1、在application.yml
中添加:
mybatis:
# 设置别名,这样,在xml文件中就不用写全名
type-aliases-package: com.scau.demo.entity
# resources文件夹下创建mapper文件夹,内含xxxMapper.xml文件
mapper-locations: classpath:mapper/*.xml
2、在启动类前添加:
// mapper接口所在包路径
@MapperScan(basePackages = "com.scau.demo.mapper")
内最外层可以包含的元素。
id
:对应mapper接口中的函数定义,如:parameterType
:入参类型,可以使用的有基本数据类型和Java复杂数据类型
// 基本类型
<select id="get" parameterType="String" resultType="User">
select * from `scau_log` where `_openid`=#{_openid};
select>
// 复杂类型 - 实体类
<select id="selectTeacher" parameterType="com.myapp.domain.Teacher" resultType="com.myapp.domain.Teacher">
select * from Teacher where c_id=#{id}
select>
resultType
:结果类型,与mapper接口中的函数定义的返回值一致// 返回一般数据类型的值
<select id="Sel" resultType="java.lang.String">
select username from user_test where id = #{id}
select>
// 返回类型是javaBean
<select id="Sel" resultType="com.tx.springboottestdemo.entity.User">
select * from user_test where id = #{id}
select>
// 返回是List类型
List<User> getUsers(); // mapper 接口
// SQL映射文件,这里需要注意的是返回是List类型 但是resultType依然是javaBean
<select id="getUsers" resultType="com.tx.entity.User">
select * from user
select>
// 返回类型是Map结构
// 当我们在查询并返回一条数据的时候,可以把{字段名,字段值}封装成Map结构
Map<String, Object> findUserByName(Integer id); // mapper 接口
<select id="findUserByName" resultType="string">
select userName from user where id=#{id};
select>
// 传入多个参数 - 1
// 可以看做是加了注解
public List<User> findUser(@Param("name1") String name1, @Param("name2") String name2);
// 对应的SQL文件:
<select id="findUser" resultType="com.tx.springboottestdemo.entity.User">
select * from user_test where userName = #{name1} and realName = #{name2}
select>
// 传入多个参数 - 2
// 可以把参数封装到Map里面 有些时候我们的业务数据查询没有定义对应的POJO,就进行参数的封装操作。
public List<User> findUser1(Map<String, Object> map);
// 对应的SQL文件:
<select id="findUser1" parameterType="java.util.Map" resultType="com.tx.springboottestdemo.entity.User">
select * from user_test where userName = #{username} and realName = #{realname}
select>
数据变更语句 insert,update 和 delete 在它们的实现中非常相似。
补充说明:
useGeneratedKeys、keyProperty
:如果你的数据库支持自动生成主键的字段(比如 MySQL 和 SQL Server),那么你可以设置 useGeneratedKeys=”true”,然后再把 keyProperty 设置为目标属性就 OK 了。例如使用下列语句,这样每次插入数据时,就可以省略掉 id 列了。(注:当数据库中的字段不是自增的时,useGeneratedKeys 不起作用。)<insert id="insertAuthor" useGeneratedKeys="true" keyProperty="id">
insert into Author (username,password,email,bio) values (#{username},#{password},#{email},#{bio})
insert>
如果你的数据库还支持多行插入, 你也可以传入一个数组或集合,并返回自动生成的主键。
<insert id="batchInsert" parameterType="java.util.List" useGeneratedKeys="true" keyProperty="id">
INSERT INTO user (name, age) VALUES
<foreach collection="list" item="user" index="index" separator="," >
(#{user.name}, #{user.age})
foreach>
insert>
keyColumn
:用于指定数据库table中的主键。通过生成的键值设置表中的列名,这个设置仅在某些数据库(像 PostgreSQL)是必须的,当主键列不是表中的第一列的时候需要设置。如果希望得到多个生成的列,也可以是逗号分隔的属性名称列表。now()
总体说来mybatis 动态SQL 语句主要有以下几类:
在mapper接口中定义一个函数名,其中@Param
指定xml中对应的名称,后面会用到。
List<Map<String,Object>> getByItem(@Param("item") String item, @Param("val") String val);
在controller类和service类中:
@RequestMapping(value = "/getByItem")
public Result getByItem(String item, String value){
return userService.getByItem(item, value);
}
public Result getByItem(String item, String value){
return Result.ok(userMapper.getByItem(item, value));
}
Result 类是封装的一个返回类,可以先不用管。
XML中:
<select id="getByItem" resultType="User">
select * from `scau_log` where
<if test="item == '_id'">
_id=#{val}
if>
select>
postman发送:
但如果item!=_id
,则语句就变成了select * from
scau_logwhere
而报错,可以使用
。
where
元素只会在子元素返回任何内容的情况下才插入 “WHERE” 子句。而且,若子句的开头为 “AND” 或 “OR”,where 元素也会将它们去除。
将上面的xml改为如下即可:
<select id="getByItem" resultType="User">
select * from `scau_log`
<where>
<if test="item == '_id'">
_id=#{val}
if>
where>
select>
如果 where 元素与你期望的不太一样,你也可以通过自定义 trim
元素来定制 where 元素的功能。
和 where 元素等价的自定义 trim 元素为:
<trim prefix="WHERE" prefixOverrides="AND |OR ">
...
trim>
prefixOverrides、suffixOverrides
属性会忽略通过管道符分隔的文本序列(注意此例中的空格是必要的)。上述例子会移除所有 prefixOverrides(suffixOverrides)
属性中指定的内容,并且插入 prefix(suffix)
属性中指定的内容。
用于动态更新语句的类似解决方案叫做 set。set 元素可以用于动态包含需要更新的列,忽略其它不更新的列。
<update id="updateAuthorIfNecessary">
update Author
<set>
<if test="username != null">username=#{username},if>
<if test="password != null">password=#{password},if>
<if test="email != null">email=#{email},if>
<if test="bio != null">bio=#{bio}if>
set>
where id=#{id}
update>
这个例子中,set 元素会动态地在行首插入 SET 关键字,并会删掉额外的逗号(这些逗号是在使用条件语句给列赋值时引入的)。
来看看与 set 元素等价的自定义 trim 元素,注意我们覆盖了后缀值设置,并且自定义了前缀值。:
<trim prefix="SET" suffixOverrides=",">
...
trim>
对集合进行遍历(尤其是在构建 IN 条件语句的时候)。
<select id="selectPostIn" resultType="domain.blog.Post">
SELECT *
FROM POST P
WHERE ID in
<foreach item="item" index="index" collection="list"
open="(" separator="," close=")">
#{item}
foreach>
select>
foreach 元素的功能非常强大,它允许你指定一个集合,声明可以在元素体内使用的集合项(item
)和索引(index
)变量。它也允许你指定开头与结尾的字符串以及集合项迭代之间的分隔符。这个元素也不会错误地添加多余的分隔符
你可以将任何可迭代对象(如 List
、Set
等)、Map 对象或者数组对象作为集合参数传递给 foreach。当使用可迭代对象或者数组时,index
是当前迭代的序号,item
的值是本次迭代获取到的元素。当使用Map
对象(或者 Map.Entry 对象的集合)时,index
是键,item
是值。
foreach元素的属性主要有item,index,collection,open,separator,close。
在使用foreach的时候最关键的也是最容易出错的就是collection属性,该属性是必须指定的,但是在不同情况下,该属性的值是不一样的,主要有一下3种情况:
// 单参数List的类型
public List<User> dynamicForeachTest(List<Integer> ids); // 对应的Mapper
<select id="dynamicForeachTest" resultType="com.mybatis.entity.User">
select * from t_user where id in
<foreach collection="list" index="index" item="item" open="(" separator="," close=")">
#{item}
foreach>
select>
// 数组类型的参数
public List<User> dynamicForeach2Test(int[] ids); // 对应的Mapper
<select id="dynamicForeach2Test" resultType="com.mybatis.entity.User">
select * from t_user where id in
<foreach collection="array" index="index" item="item" open="(" separator="," close=")">
#{item}
foreach>
select>
// Map类型的参数
public List<User> dynamicForeach3Test(Map<String, Object> params); // 对应的Mapper
<select id="dynamicForeach3Test" resultType="com.mybatis.entity.User">
select * from t_user where username like '%${username}%' and id in
<foreach collection="ids" index="index" item="item" open="(" separator="," close=")">
#{item}
foreach>
select>
<select id="dynamicChooseTest" parameterType="Blog" resultType="Blog">
select * from t_blog where 1 = 1
<choose>
<when test="title != null">
and title = #{title}
when>
<when test="content != null">
and content = #{content}
when>
<otherwise>
and owner = "owner1"
otherwise>
choose>
select>
when
元素表示当when
中的条件满足的时候就输出其中的内容,当when中有条件满足的时候,就会跳出choose
,即所有的when
和otherwise
条件中,只有一个会输出;当所有的条件都不满足的时候就输出otherwise
中的内容。
所以上述语句的意思非常简单,当title!=null
的时候就输出and titlte = #{title}
,不再往下判断条件,当title
为空且content!=null
的时候就输出and content = #{content}
,当所有条件都不满足的时候就输出otherwise
中的内容。
<if test="infoTemplateAll.templateName != null">
AND template_name LIKE '%${infoTemplateAll.templateName}%'
if>
<insert id="insertSelectives" parameterType="java.util.List">
INSERT INTO oap_detail_income
(
income_seq_num,
interest_terms
)
VALUES
<foreach collection="list" item="file" index="index"
separator=",">
(
#{file.incomeSeqNum},
<choose>
<when test="file.interestTerms != null">
#{file.interestTerms},
when>
<otherwise>
0,
otherwise>
choose>
)
foreach>
insert>
… …
打开my.ini,搜索[mysqld],在[mysql]节点下加上这一行
default-time-zone='+08:00'
重启mysql服务
File -> Setting -> File and Code Templates - > ‘+’号新建 -> 填写Name和Extension -> 自行填写内容 -> OK
<mapper namespace="com.xx.mapper.xxMapper">
<select id="GetUserByID" parameterType="int" resultType="com.test.springtest.dao.MUser">
select * from `student` where id = #{id}
select>
<insert
id="saveUser" parameterType="com.test.springtest.User" useGeneratedKeys="true">
insert into student(NAME,AGE) values (#{name},#{age})
insert>
mapper>