mybatis 最佳实战
目录
1. 依赖导入
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.3</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
2. 配置文件
spring:
datasource:
url: jdbc:mysql://49.233.186.242:3389/shop?useUnicode=true&characterEncoding=utf-8&useSSL=false
username: root
password: 123456
driver-class-name: com.mysql.cj.jdbc.Driver
mybatis:
mapper-locations: classpath:generator/*.xml
logging:
level:
com.yangtao.demo: debug
3 关联查询
关联查询有两种实现方式, 一种是关联查询 ( association ), 一种是关联结果查询(collection) ,
关联查询: 会产生N+ 1 问题,因为同样一条sql 语句, 他会产生多条SQl 查询语句, 带来性能的浪费。 可以通过设置 配置懒加载(延迟加载)
注意: 在数据库里面一对多的关系是通过主外键去关联,在对象里面使用一对多的查询,需要引用它的类
3.1 一对多关联查询
<resultMap id="BaseResultMap4" type="com.yangtao.demo.model.TbOrder">
<id column="id" jdbcType="INTEGER" property="id" />
<result column="CODE" jdbcType="VARCHAR" property="code" />
<result column="total" jdbcType="DOUBLE" property="total" />
<result column="user_id" jdbcType="INTEGER" property="userId" />
<association property="tbUser" javaType="com.yangtao.demo.model.TbUser">
<id column="id" jdbcType="INTEGER" property="id" />
<result column="username" jdbcType="VARCHAR" property="username" />
<result column="loginname" jdbcType="VARCHAR" property="loginname" />
<result column="PASSWORD" jdbcType="VARCHAR" property="password" />
<result column="phone" jdbcType="VARCHAR" property="phone" />
<result column="address" jdbcType="VARCHAR" property="address" />
</association>
</resultMap>
<select id="selectCodeByUid" parameterType="java.lang.Integer" resultMap="BaseResultMap2">
select o.CODE,o.total from tb_user u,tb_order o
where u.id=o.user_id and u.id=#{uid}
</select>
3.2 一对多关联结果查询 (推荐使用)
<resultMap id="BaseResultMap3" type="com.yangtao.demo.dto.CodeTestDto">
<result column="CODE" jdbcType="VARCHAR" property="code" />
<result column="total" jdbcType="DOUBLE" property="total" />
<collection property="codeTestDto" javaType="ArrayList"
column="id" ofType="com.yangtao.demo.dto.CodeTestDto" select="com.yangtao.demo.dao.TbOrderDao.selectCodeByUidAndReturnList"
fetchType="lazy">
<result column="CODE" property="code" />
<result column="total" property="total"/>
</collection>
</resultMap>
4. CRUD 标签
<select id="selectCodeByUidAndReturnList2" parameterType="java.lang.Integer" resultMap="BaseResultMap4">
select * from tb_user u,tb_order o
where u.id=o.user_id and u.id=#{uid}
</select>
<delete id="deleteByPrimaryKey" parameterType="java.lang.Integer">
delete from tb_order
where id = #{id,jdbcType=INTEGER}
</delete>
<insert id="insert" keyColumn="id" keyProperty="id" parameterType="com.yangtao.demo.model.TbOrder" useGeneratedKeys="true">
insert into tb_order (CODE, total, user_id)
values (#{code,jdbcType=VARCHAR}, #{total,jdbcType=DOUBLE}, #{userId,jdbcType=INTEGER})
</insert>
<update id="updateByPrimaryKey" parameterType="com.yangtao.demo.model.TbOrder">
update tb_order
set CODE = #{code,jdbcType=VARCHAR},
total = #{total,jdbcType=DOUBLE},
user_id = #{userId,jdbcType=INTEGER}
where id = #{id,jdbcType=INTEGER}
</update>
5. 动态SQL
1.IF 选择执行
<select id="getBlogByConditionDynamic" resultMap="oneToManyNested">
select t1.id blog_id, t1.title, t2.id post_id, t2.section
from blog t1 left outer join post t2 on t1.id = t2.blog_id
<where>
<if test="title != null and title !=\'\'">
and t1.title like \'%\'||#{title}||\'%\'
</if>
<if test="section != null and section != \'\'">
and t2.section like \'%\'||#{section}||\'%\'
</if>
</where>
</select>
@Test
public void testGetBlogByConditionDynamic() throws Exception {
List<Blog> blogList = blogMapper.getBlogByConditionDynamic("", "section");
Assert.assertNotNull(blogList);
}
<select id="getBlogByTitleOrSection" resultMap="oneToManyNested">
select t1.id blog_id, t1.title, t2.id post_id, t2.section
from blog t1 left outer join post t2 on t1.id = t2.blog_id where 1=1
<choose>
<when test="title != null and title !=\'\'">
and t1.title like \'%\'||#{title}||\'%\'
</when>
<when test="section != null and section != \'\'">
and t2.section like \'%\'||#{section}||\'%\'
</when>
<otherwise>
and t1.title is not null and t2.section is not null
</otherwise>
</choose>
</select>
2. trim 消除多余的符号
mybatis的trim标签一般用于去除sql语句中多余的and关键字,逗号,或者给sql语句前拼接 “where“、“set“以及“values(“ 等前缀,或者添加“)“等后缀,可用于选择性插入、更新、删除或者条件查询等操作。
where 有同样的效果
<select id="getBlogByConditionDynamicTrim" resultMap="oneToManyNested">
select t1.id blog_id, t1.title, t2.id post_id, t2.section
from blog t1 left outer join post t2 on t1.id = t2.blog_id
<trim prefix="where" prefixOverrides="and | or">
<if test="title != null and title !=\'\'">
and t1.title like \'%\'||#{title}||\'%\'
</if>
<if test="section != null and section != \'\'">
and t2.section like \'%\'||#{section}||\'%\'
</if>
</trim>
</select>
3. set
<update id="updateBlogTitleSet" parameterType="blog">
update blog
<set>
<if test="title != null and title != \'\'">
title = #{title}
</if>
<if test="id != null and id != \'\'">
, id = #{id}
</if>
</set>
where id = #{id}
</update>
4. foreach
<select id="dynamicForeach2Test" resultType="Blog">
select * from t_blog where id in
<foreach collection="array" index="index" item="item" open="(" separator="," close=")">
#{item}
</foreach>
</select>
6. 参数传递
List<Blog> getBlogByConditionDynamic(@Param("title") String title, @Param("section") String section);