文章目录
一,SpringBoot简介
SpringBoot 只是一个配置工具,整合工具,辅助工具. 基于“约定优于配置”的思想。
设计目的是用来简化新Spring应用的初始搭建以及开发过程。
特点:
- 创建独立的Spring应用程序
- 嵌入的Tomcat,无需部署WAR文件
- 简化Maven配置
- 自动配置Spring
- 提供生产就绪型功能,如指标,健康检查和外部配置
- 绝对没有代码生成并且对XML也没有配置要求
1.Spring注解
-
bean的分类标识:
@Service
@Controller
@Repository:语义化注入标签
@Component: 表示通用bean -
bean注入:
@Autowired:基于byType自动注入
@Qualifier(“bean的名字”) 按名称装配Bean,与@Autowired组合使用,解决按类型匹配找到多个Bean问题。
@Resource: 基于byName自动注入 -
其他
@Bean: 方法上,声明是一个Bean
@Value:变量上,从配置文件读取,如yml,properties
@Configuration //配置类,等同于spring的XML配置文件
@MapperScan(“com.vcyber.ccqc.mapper”) //扫描的Mapper类的包的路径
- @Data:简化编码,为类提供get,set,还提供equals(),hashCode(),toString()方法,需要安装 lombok 插件
- @Transactional事物注解
参考:@Transactional 注解管理事务
事务保证几个操作是原子性的,要么同时成功,要么同时失败。
1.@Transactional 只能应用到 public 方法才有效
2.默认传播特性REQUIRES_NEW:当前存在事务则加入该事务;当前没有事务则创建一个新的事务。
2.SpringBoot注解:
-
@SpringBootApplication:
@ComponentScan+@Configuration+@EnableAutoConfiguration:启动类,约定优于配置 -
@ComponentScan:在类上,扫描指定包名下标注了@Controller,Service等注解的类,注册为bean
-
@Configuration:配置类,相当于spring的配置文件
-
@EnableAutoConfiguration 自动配置。
-
@ConfigurationProperties 赋值,将注解转换成对象
-
@RestController:@Controller + @ResponseBody的合集
-
@GetMapping(value="/hello"): 组合注解@RequestMapping(value="/hello",method = RequestMethod.GET)缩写
3.SpringMVC控制层注解:
参考博客:SpringMVC-@RequestMapping的参数和用法
-
@RequestMapping:获取请求报文是做对应的
a:value,指定请求的地址?
b:method 请求方法类型 这个不写的话,自适应:get或者post
c:params 指定request中必须包含某些参数值时,才让该方法处理。 -
@PathVariable(“id”) Integer id 获取url中的数据
-
@RequestParam //获取请求参数值
-
@RequestParam(value=“id”,required=false,defaultValue=“1”) Integer id //required=false 表示url中可以不传入id参数,此时就使用默认参数
-
@RequestBody 接收来自请求体的参数,GET请求因为没有HttpEntity,所以@RequestBody并不适用。
POST请求中,通过HttpEntity传递的参数,必须要在请求头中声明数据的类型Content-Type,SpringMVC通过使用HandlerAdapter 配置的HttpMessageConverters来解析HttpEntity中的数据,绑定到相应的bean上。
4.Mybatis 注解:
@Param:dao层使用该注解传递多个参数
Spring中的@param在xml需要如下这样引用变量: #{1,jdbcType=INTEGER},#{1,jdbcType=INTEGER}
mybatis @param在xml中则是如下这样引用变量: #{businessId},#{memberId}
不使用@Param注解时,参数只能有一个,并且是Javabean。在SQL语句里可以引用JavaBean的属性,而且只能引用JavaBean的属性。
parameterType:
注意:基本数据作为传参(int,String,Date等),只能传入一个。通过#{参数名} 即可获取传入的值
复杂数据类型:包含JAVA实体类、Map。 通过#{属性名}或#{map的KeyName}即可获取传入的值
如果想传入一个collection怎么办呢?
传入List或Array作为参数,会自动包装到一个Map对象中,List使用list作为键名,而Array用array作为键名。
当您想传入collection时,并不能直接传入collection对象,要将其先转换为list,然后才能传入。
传入list时parameterType是可以不配置的,mybatis会自动传入的
@Param: mapper接口方法一般接受一个参数,可以通过使用@Param将多个参数绑定到一个map做为输入参数。
@Mapper:扫描Mapper接口,每个接口都加比较麻烦,@MapperScan可指定要扫描类的包路径
Mybatis代理是通过创建接口的动态代理对象实现
@Select,@Insert,@Update:Sql基于注解开发
二,代码开发回顾
控制层:
@Controller
public class AdvisoryReportController {
//基于byType自动注入
@Autowired
private AdvisoryReportService advisoryReportService;
/**
* 查询咨询报告列表
* @return
*/
@RequestMapping("/selectAdvisoryReportList")
//返回json
@ResponseBody
public BaseResult<List<AdvisoryReport>> selectAdvisoryReportList(@RequestParam("id") Integer id){
return advisoryReportService.selectAdvisoryReportList(id);
}
持久层:
一般使用mapper动态代理,遵循的规范:
1、mapper接口和mapper配置文件同名且在同一目录(在mapper的包扫描的形式下必须遵守)
2、mapper配置文件的namespace是接口全路径
3、mapper接口的方法名和mapper配置文件的id对应
4、mapper接口中方法的参数、返回类型和配置文件中对应
<?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">
<!--2、mapper配置文件的namespace是接口全路径-->
<mapper namespace="com.zr.mapper.EmployeeMapper">
<!--
结果集的封装和映射:定义映射employeeMap类型是Employee类型
注意,没映射的属性不能绑定值,property=属性名称,column=关联查询返回列名称
-->
<resultMap id="employeeMap" type="com.zr.entity.Employee">
<!-- 配置主键 -->
<id property="id" column="id"></id>
<result property="lastName" column="lastName"/>
<result property="email" column="email"/>
<result property="gender" column="gender"/>
<result property="birth" column="birth"/>
<!--
一对一:association
一对多:connection
-->
<association property="department" javaType="com.zr.entity.Department">
<id property="id" column="department_id"></id>
<result property="departmentName" column="departmentName"></result>
</association>
</resultMap>
<!--3、mapper接口的方法名和mapper配置文件的id对应-->
<!--4、mapper接口中方法的参数、返回类型和配置文件中对应-->
<!--
id="getAll"方法名,
ParameterType:传入的参数类型
ResultType:返回的参数类型,
RusultMap:结果集的封装和映射、
如下:进行关联查询,返回结果映射employeeMap
-->
<select id="getAll" resultType="com.zr.entity.Employee" resultMap="employeeMap">
SELECT e.id,e.lastName,e.email,e.gender,e.birth,e.department_id,d.departmentName FROM t_employee e,t_department
d where e.department_id=d.id
</select>
<select id="get" resultType="com.zr.entity.Employee" resultMap="employeeMap">
SELECT * FROM t_employee WHERE id=#{id}
</select>
<insert id="save" parameterType="com.zr.entity.Employee">
INSERT INTO t_employee(lastName,email,gender,department_id,birth) VALUES
(#{lastName},#{email},#{gender},#{department.id},#{birth})
</insert>
<delete id="delete" parameterType="java.lang.Integer">
DELETE FROM t_employee WHERE id=#{id}
</delete>
</mapper>
三,ssm整体复习
1.Mybatis
1.关联映射:一对一:association
一对多:connection
一对一 <association>
<id column="id" property="id"></id>
<result culumn="name" property="name"></result>
</association>
一对多
<!-- 配置一对多的关系 --> javaType指定属性的类型,ofType指定集合中的类型
<collection property="orders" javaType="list" ofType="order">
<!-- 配置主键,是关联Order的唯一标识 -->
<id property="id" column="oid" />
<result property="number" column="number" />
<result property="createtime" column="createtime" />
<result property="note" column="note" />
</collection>
#与$区别是什么?
#{}:表示一个占位符号,通过#{}可以实现preparedStatement向占位符中设置值,
自动进行java类型和jdbc类型转换。#{}可以有效防止sql注入。
#{}可以接收简单类型值或pojo属性值。
如果parameterType传输单个简单类型值,#{}括号中可以是value或其它名称。
${}:表示拼接sql串,过${}可以将parameterType传入的内容拼接在sql中
2.动态SQL
常用:
if
where //where标签可以自动添加where,同时处理sql语句中第一个and关键字
foreach //进行遍历
if标签:
<select id="queryUserByWhere" parameterType="user" resultType="user">
SELECT id, username, birthday, sex, address FROM `user`
WHERE 1=1
<if test="sex != null and sex != ''">
AND sex = #{sex}
</if>
<if test="username != null and username != ''">
AND username LIKE '%${username}%'
</if>
</select>
where标签:
<!-- 根据条件查询用户 -->
<select id="queryUserByWhere" parameterType="user" resultType="user">
SELECT id, username, birthday, sex, address FROM `user`
<!-- where标签可以自动添加where,同时处理sql语句中第一个and关键字 -->
<where>
<if test="sex != null">
AND sex = #{sex}
</if>
<if test="username != null and username != ''">
AND username LIKE '%${username}%'
</if>
</where>
</select>
sql片段:----------------------------------------------------------------------------------------------
Sql中可将重复的sql提取出来,使用时用include引用即可,最终达到sql重用的目的。
把上面例子中的id, username, birthday, sex, address提取出来,作为sql片段,如下:
<!-- 根据条件查询用户 -->
<select id="queryUserByWhere" parameterType="user" resultType="user">
<!-- SELECT id, username, birthday, sex, address FROM `user` -->
<!-- 使用include标签加载sql片段;refid是sql片段id -->
SELECT <include refid="userFields" /> FROM `user`
<!-- where标签可以自动添加where关键字,同时处理sql语句中第一个and关键字 -->
<where>
<if test="sex != null">
AND sex = #{sex}
</if>
<if test="username != null and username != ''">
AND username LIKE '%${username}%'
</if>
</where>
</select>
<!-- 声明sql片段 -->
<sql id="userFields">
id, username, birthday, sex, address
</sql>
如果要使用别的Mapper.xml配置的sql片段,可以在refid前面加上对应的Mapper.xml的namespace
foreach标签:----------------------------------------------------------------------------------------------
向sql传递数组或List,mybatis使用foreach解析,如下:
根据多个id查询用户信息
查询sql:
SELECT * FROM user WHERE id IN (1,10,24)
1 、
在pojo中定义list属性ids存储多个用户id,并添加getter/setter方法
public class QueryVo{
private List<Integer> ids;
}
2、
<select id="queryUserByIds" parameterType="queryVo" resultType="user">
SELECT * FROM `user`
<where>
<!-- foreach标签,进行遍历 -->
<!-- collection:遍历的集合,这里是QueryVo的ids属性 -->
<!-- item:遍历的项目,可以随便写,,但是和后面的#{}里面要一致 -->
<!-- open:在前面添加的sql片段 -->
<!-- close:在结尾处添加的sql片段 -->
<!-- separator:指定遍历的元素之间使用的分隔符 -->
<foreach collection="ids" item="item" open="id IN (" close=")"
separator=",">
#{item}
</foreach>
</where>
</select>
2.代码开发常用注解
控制层:
参考:@Valid注解是什么
@ResponseBody
@RequestMapping(value = "/getAccessToken", method = RequestMethod.POST)
public JSONObject getAccessToken(@Valid @RequestBody GetAccessTokenRest rest){
}
业务层:
//传播特性默认 隔离级别 超时时间 触发事务回滚的异常类
@Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.READ_UNCOMMITTED, timeout = 30, rollbackFor = Exception.class)
持久层:
参考:Mybatis的Mapper文件中用注解方式写动态Sql语句演示
参考:Mybatis调用MySQL存储过程
参考:mybatis 中关于jdbcType=VARCHAR
MyBatis 插入空值时,需要指定JdbcType,否则会报异常
参考:@Results用法总结
//注解写动态sql的话会用到 <script> </scrpit>标签
@Select(value = { "<script>" +
"SELECT count(*) FROM sh_wechat_register_record " +
"<where>" +
" <if test=\" null != patName and '' != patName \">" + "AND patName like concat('%',#{patName},'%') " + "</if>" +
"</where>" +
" </script>" })
public int queryWechatRegisterCount(JSONObject queryJsonObject);
//注意:statementType=”CALLABLE” 必须为CALLABLE,告诉MyBatis去执行存储过程, 否则会报错
//mode=IN 输入参数 mode=OUT输出参数 jdbcType为数据库定义的字段类型。
@Select("call sp_name (#{data},#{message,mode=OUT,jdbcType=VARCHAR})")
@Options(statementType = StatementType.CALLABLE)
public GetRegisterNotifyTemplateMsg getRegisterNotifyTemplate(ProcInfo input);
//@Results注解来映射查询结果集到实体类属性。
//@Results注解设置id=info,然后使用@ResultMap注解来复用这段代码。
//@One执行另外一个方法来查询关联的内容,一对一关系时,可以使用@One注解来便捷的实现
//@Many与@One类似,@One查询到的结果是多行,会抛出TooManyResultException异常,应该使用的是@Many注解,实现一对多的查询
//FetchType.LAZY:懒加载,加载一个实体时,定义懒加载的属性不会马上从数据库中加载
//FetchType.EAGER:急加载,加载一个实体时,定义急加载的属性会立即从数据库中加载
@Results(id="info",value = {
@Result(property = "docName", column = "docId", many = @Many(select = "queryByDocIdName", fetchType = FetchType.EAGER)),
@Result(property = "docTitle", column = "docId", many = @Many(select = "queryByDocIdTitle", fetchType = FetchType.EAGER)),
})