springboot笔记(三)

小白第三次写博客,在这里记录下个人认为比较重要的知识整理,有错求评论指出.

1.springboot整合mybatis

1.1 依赖

<dependency>
                <groupId>org.mybatis.spring.boot</groupId>
                <artifactId>mybatis-spring-boot-starter</artifactId>
                <version>2.1.1</version>
</dependency>

注意:在添加此依赖时,一定指定其版本(version),因为在springboot默认配置中没有设置mybatis框架版本。

我们添加了mybatis依赖以后,spring框架启动时会对mybatis进行自动配置。例如SqlSessionFactory工厂对象的创建。

1.2 配置

假如需要对mybatis框架进行简易配置,可以打开application.properties文件,在此文件中进行基本配置(可选,暂时可以不配置),例如:

mybatis.configuration.default-statement-timeout=30
mybatis.configuration.map-underscore-to-camel-case=true

配置mybatis中的sql日志的输出:(com.cy为我们写的项目的根包)

logging.level.com.cy=DEBUG

1.3具体代码

第三步:定义商品业务数据层接口及业务方法。

import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface GoodsDao {
         @Delete("delete from tb_goods where id=#{id}")
         int deleteById(Integer id);
}

其中:@Mapper是由MyBatis框架中定义的一个描述数据层接口的的注解(所有的注解只起到一个描述性的作用),用于告诉Spring框架此接口的实现由mybatis创建,并将其实现类对象存储到spring容器.
第四步:定义测试类,对GoodsDao对象进行应用测试

@SpringBootTest
public class GoodsDaoTests {    
   @Autowired
   private GoodsDao goodsDao;
        @Test
        public void testDeleteById() {
                int rows=goodsDao.deleteById(10);
                System.out.println("rows="+rows);
        }
}

1.4自定义sql语句

在MyBatis框架中定义SQL映射的方式有两种:一种是将SQL映射定义在我们的xml映射文件中,一种方式是借助注解将其声明在接口方法上。我们在实际项目中对于简单的SQL映射可以直接以注解方式进行声明即可,复杂SQL还是要写到xml中,充分利用动态SQL进行设计会更好一些。
第一步,在GoodsMapper中定义删除方法

int deleteObjects(@Param("ids")Integer... ids);

第二部:在src/main/resources目录下创建mapper/goods目录,然后在其目录中添加GoodsMapper.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 namespace="com.cy.pj.goods.dao.GoodsDao">
   <delete id="deleteObjects">
       delete from tb_goods
       where id in <!-- (1,2,3,4,5) -->
       <foreach collection="ids"
                open="("
                close=")"
                separator=","
                item="id">
               #{id}
       </foreach>
   </delete>
</mapper>

这里涉及复杂sql语句,暂时不做讲解.
第三步:在application.properties文件中添加如下配置:
mybatis.mapper-locations=classpath:/mapper//.xml
第四步:在GoodsMapperTests类中添加如下单元测试方法进行单元测试:

@Test
public void testDeleteObjects() {
                int rows=goodsMapper.deleteObjects(17,18);
                System.out.println(rows);
}

ps:以下为mybatis+thymeleaf常用设置(server,datasource,mybatis,mvc)

#server
server:
  port: 80
  servlet:
    context-path: /
  tomcat:
    max-threads: 1000
#spring
spring:
  datasource:
    url: jdbc:mysql:///jtsys?serverTimezone=GMT
    username: root
    password: root
  thymeleaf:
    prefix: classpath:/templates/pages/
    suffix: .html
#mybatis
mybatis:
  configuration:
    default-statement-timeout: 30
    map-underscore-to-camel-case: true
  mapper-locations:
  - classpath:/mapper/*/*.xml
#lOG
logging:
  level:
	com.xx: DEBUG

1.5sql标签与复杂sql语句

 <sql id="queryWhereId">
         from sys_Logs
          <where>
            <if test="username!=null and username!=''">
               username like concat("%",#{username},"%")
            </if>
          </where>
 </sql>

<sql>标签,表示以下sql语句为易重复片段的单独抽取
<where>标签,替代sql语句的where,当内容为空时,则自动删除where
<if>,判断标签,test中为判断内容,若为真则包含其中的sql语句

 <select id="getRowCount"
            resultType="int">
          select count(*) 
          <include refid="queryWhereId"/>
    </select>

<select>,表示该语句为查询语句
<include>,复用其他的sql语句,refid填写重复的sql语句标签中的id
resultType属性,表示返回结果用什么对象封装,返回结果为集合时依旧是指定泛型中的集合对象类型

 <delete id="deleteObjects">
       delete from sys_Logs
       where id in 
       <foreach collection="ids"
                open="("
                close=")"
                separator=","
                item="id">
               #{id} 
        </foreach>
</delete>

<delete>标签,表示该sql语句为删除操作
<foreach>标签,遍历ids集合对象,单个对象用id表示,结果sql如下
… delete from sys_Logs
where id in in (id1,id2,id2…)
由于ids集合可能为空,可做以下修改:

<delete id="deleteObjects">
        delete from sys_logs
        <if test="ids!=null and ids.length>0">
          where id in  
            <foreach collection="ids"
                 open="("
                 close=")"
                 separator=","
                 item="id">
                 #{id}
            </foreach>
        </if>
        <if test="ids==null or ids.length==0">
           where 1=2
        </if>
</delete>

从SQL执行性能角度分析,一般在SQL语句中不建议使用in表达式,可以参考如下代码进行实现(重点是forearch中or运算符的应用):

delete from sys_logs id=#{id} where 1=2

说明:这里的choose元素也为一种选择结构,when元素相当于if,otherwise相当于else的语法。

<insert id="insertObject">
       insert into sys_logs
       (username,operation,method,params,time,ip,createdTime)
       values
(#{username},#{operation},#{method},#{params},#{time},#{ip},#{createdTime})
</insert>

标签,表示该sql语句为新增操作

<update id="updateObject"
            parameterType="com.cy.pj.sys.entity.SysMenu">
         update sys_menus
         set
           name=#{name},
           type=#{type},
           sort=#{sort},
           url=#{url},
           parentId=#{parentId},
           permission=#{permission},
           modifiedUser=#{modifiedUser},
           modifiedTime=now()
        where id=#{id}
    </update>

<upsate>,表示该sql语句为更新操作

<insert id="insertObject"
            parameterType="com.cy.pj.sys.entity.SysRole"
useGeneratedKeys="true"
keyProperty="id">
         insert into sys_roles 
         (id,name,note,createdTime,modifiedTime,
         createdUser,modifiedUser) 
         values
         (null,#{name},#{note},now(),now(),
         #{createdUser},#{modifiedUser})
</insert>

在非分布式架构中,新增数据的id由数据库生成,当添加以下两条属性后,会返回新增的数据对象的主键id

useGeneratedKeys="true"
keyProperty="id"

关于resultMap标签使用,关键代码如下:

   <select id="findObjectById"
           resultMap="sysRoleMenuVo">
           select id,name,note
           from sys_roles
           where id=#{id}        
   </select>
   <!-- resultMap一般用于自定义映射或一些关联查询中 -->
   <resultMap type="com.cy.pj.sys.vo.SysRoleMenuVo" 
              id="sysRoleMenuVo">
        <!-- 假如基于id做再次执行查询,又希望将id值存储到值对象,
                           可以对id进行专门映射 -->
        <id property="id" column="id"/>
        <!-- collection一般应用于one2many查询 -->
        <collection property="menuIds"
                    select="com.cy.pj.sys.dao.SysRoleMenuDao.findMenuIdsByRoleId"
                    column="id">
        </collection>
   </resultMap>
  <select id="findMenuIdsByRoleId"
              resultType="int">
            select menu_id
            from sys_role_menus
            where role_id=#{id} 
  </select>

sql语句执行顺序如下:
1.先执行查询语句,id为findMenuIdsByRoleId,返回ids集合
2.在<collection>标签中指定子查询来源,会得到ids集合,并且通过property属性指定存到实体类的menuIds属性中,由于含有column属性,会根据id查询
3. <resultMap type="com.cy.pj.sys.vo.SysRoleMenuVo" id="sysRoleMenuVo">中type为映射的实体类对象,id为自定义id,用于其他sql语句中的resultMap属性,以下再提供一个完整版本供自行参考理解:

<resultMap type="com.cy.pj.sys.entity.SysUserMenu" id="sysUserMenu">
         <id property="id" column="id"/>
         <result property="name" column="name"/>
         <result property="url" column="url"/>
         <collection property="childs" 
                     ofType="com.cy.pj.sys.entity.SysUserMenu">
                    <id property="id" column="cid"/>
                    <result property="name" column="cname"/>
                    <result property="url" column="curl"/> 
         </collection>
     </resultMap>
  
     <select id="findMenusByIds" resultMap="sysUserMenu">
         select p.id,p.name,p.url,c.id cid,c.name cname,c.url curl
         from sys_menus p  join sys_menus c
         on c.parentId=p.id
         where p.parentId is null and c.id in 
         <foreach collection="menuIds" separator="," 
                  open="(" close=")" item="menuId">
                  #{menuId}
         </foreach>
     </select>

1.6多表查询

篇幅关系请看以下地址的例子:
https://niaobulashi.com/archives/mybatis-summary.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值