Mybatis
动态SQL
普通式
<insert id="insertRole" parameterType="com.edu.ssm.po.Role"> <!--<selectKey keyProperty="id" order="AFTER" resultType="java.lang.Integer"> select LAST_INSERT_ID() </selectKey>--> insert into Role(username,birthday,sex,address) values(#{username},#{birthday},#{sex},#{address}) </insert>
使用动态sql trim标签,集齐了where set的强大标签
<insert id="insertRole" parameterType="com.edu.ssm.po.Role"> insert into Role <trim prefix="(" suffix=")" suffixOverrides=","> <if test="id != null and id!='' "> id, </if> <if test="username != null"> username, </if> <if test="birthday != null"> birthday, </if> <if test="sex != null"> sex, </if> <if test="address != null"> address, </if> </trim> <trim prefix="values (" suffix=")" suffixOverrides=","> <if test="id != null"> #{id,jdbcType=INTEGER}, </if> <if test="username != null"> #{username,jdbcType=VARCHAR}, </if> <if test="birthday != null"> #{birthday,jdbcType=DATE}, </if> <if test="sex != null"> #{sex,jdbcType=CHAR}, </if> <if test="address != null"> #{address,jdbcType=VARCHAR}, </if> </trim> </insert>
使用注解的方式注入对象
List<Role> findRoleByOj(@Param("role") Role role);
<select id="findRoleByOj" parameterType="com.edu.ssm.po.Role" resultType="com.edu.ssm.po.Role"> select * from role <where> <if test="role.id!=null and role.id!='' "> <!--这个要注意--> and id = #{role.id} </if> </where> </select>
没有注解的方式
List<Role> findRoleByOj(Role role);
<select id="findRoleByOj" parameterType="com.edu.ssm.po.Role" resultType="com.edu.ssm.po.Role"> select * from role <where> <if test="id!=null and id!='' "> <!--这个要注意--> and id = #{id} </if> </where> </select>
模板
mapper.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.edu.ssm.mapper.RoleMapper"> </mapper>
src/SqlMapConfig.xml
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <!-- 和spring整合后 environments配置将废除--> <environments default="development"> <environment id="development"> <!-- 使用jdbc事务管理--> <transactionManager type="JDBC" /> <!-- 数据库连接池--> <dataSource type="POOLED"> <property name="driver" value="com.mysql.jdbc.Driver" /> <property name="url" value="jdbc:mysql://localhost:3306/springmvc?characterEncoding=utf-8" /> <property name="username" value="root" /> <property name="password" value="123456" /> </dataSource> </environment> </environments> <mappers> <mapper resource="com/edu/ssm/mapper/ItemsMapper.xml"/> <mapper resource="com/edu/ssm/mapper/RoleMapper.xml"/> </mappers> </configuration>
当 SQL 语句中的元数据(如表名或列名)是动态生成的时候,字符串替换将会非常有用。 举个例子,如果你想通过任何一列从表中 select 数据时,不需要像下面这样写:
@Select("select * from user where id = #{id}") User findById(@Param("id") long id); @Select("select * from user where name = #{name}") User findByName(@Param("name") String name); @Select("select * from user where email = #{email}") User findByEmail(@Param("email") String email); // and more "findByXxx" method可以只写这样一个方法: @Select("select * from user where ${column} = #{value}") User findByColumn(@Param("column") String column, @Param("value") String value);其中 ${column} 会被直接替换,而 #{value} 会被使用 ? 预处理。 因此你就可以像下面这样来达到上述功能: User userOfId1 = userMapper.findByColumn("id", 1L); User userOfNameKid = userMapper.findByColumn("name", "kid"); User userOfEmail = userMapper.findByColumn("email", "noone@nowhere.com");
动态sql
choose
when
when
otherwise
与if不同的是
choose只能是单选
执行完一个就不在找了
if还在继续执行
where 元素只会在至少有一个子元素的条件返回 SQL 子句的情况下才去插入“WHERE”子句。而且,若语句的开头为“AND”或“OR”,where 元素也会将它们去除。
如果 where 元素没有按正常套路出牌,我们可以通过自定义 trim 元素来定制 where 元素的功能。比如,和 where 元素等价的自定义 trim 元素为:
<trim prefix="WHERE" prefixOverrides="AND |OR "> ... </trim>
使用if 如果有的值吗没有传就多出来一个and
所以使用<where>来取消前面多于的and</where>
<select id="findActiveBlogLike" resultType="Blog"> SELECT * FROM BLOG <where> <if test="state != null and state !='' "> state = #{state} </if> <if test="title != null"> AND title like #{title} </if> <if test="author != null and author.name != null"> AND author_name like #{author.name} </if> </where> </select>
ResultMap 通常在联合查询使用
<resultMap id="BaseResultMap" type="com.example.mybatis.entity.Items"> <result column="id" jdbcType="INTEGER" property="id" /> <result column="name" jdbcType="VARCHAR" property="name" /> <result column="price" jdbcType="REAL" property="price" /> <result column="pic" jdbcType="VARCHAR" property="pic" /> <result column="createtime" jdbcType="TIMESTAMP" property="createtime" /> </resultMap>
增
INSERT INTO table_name ( field1, field2,...fieldN ) VALUES ( value1, value2,...valueN );
<insert id="insert"> insert into school <trim prefix="(" suffix=")" suffixOverrides=","> <if test="province != null"> province, </if> <if test="code != null"> code, </if> <if test="major != null"> major, </if> <if test="schoolcode != null"> schoolcode, </if> <if test="schoolname != null"> schoolname, </if> <if test="year != null"> year, </if> </trim> <trim prefix="values (" suffix=")" suffixOverrides=","> <if test="province != null"> #{province}, </if> <if test="code != null"> #{code}, </if> <if test="major != null"> #{major}, </if> <if test="schoolcode != null"> #{schoolcode}, </if> <if test="schoolname != null"> #{schoolname}, </if> <if test="year != null"> #{year}, </if> </trim> </insert>
删
DROP TABLE table_name ; 删除整个表,包括表结构
删除表内数据,用 delete。格式为: delete from 表名 where 删除条件; 实例:删除学生表内姓名为张三的记录。 delete from student where T_name = "张三"; 清除表内数据,保存表结构,用 truncate。格式为: truncate table 表名; 实例:清除学生表内的所有数据。 truncate table student;
改
UPDATE table_name SET field1=new-value1, field2=new-value2 [WHERE Clause]
<update id="update"> update school <set> <if test="province != null"> province=#{province}, </if> <if test="code != null"> code=#{code}, </if> <if test="major != null"> major=#{major}, </if> <if test="schoolcode != null"> schoolcode=#{schoolcode}, </if> <if test="schoolname != null"> schoolname= #{schoolname}, </if> <if test="year != null"> year=#{year}, </if> </set> where id=#{id} </update>
查
模糊查询
<select id="selectprovince" resultType="com.edu.entity.School"> select * from school where province like concat('%',#{province},'%'); </select>
SELECT column_name,column_name FROM table_name [WHERE Clause] [LIMIT N][ OFFSET M]
select _column,_column from _table [where Clause] [limit N][offset M] select * : 返回所有记录 limit N : 返回 N 条记录 offset M : 跳过 M 条记录, 默认 M=0, 单独使用似乎不起作用 limit N,M : 相当于 limit M offset N , 从第 N 条记录开始, 返回 M 条记录 实现分页: select * from _table limit (page_number-1)*lines_perpage, lines_perpage 或 select * from _table limit lines_perpage offset (page_number-1)*lines_perpage
/*websites 表名 NAME alexa url country 字段*/ SELECT * FROM websites; /* 查询表所有数据 */ SELECT NAME FROM websites; /* 查询表字段数据 */ SELECT * FROM websites where name = "广西"; /* 查询表字段下条件数据 */ SELECT * from websites where name like "_o%"; /* 模糊查询表下数据 */ SELECT * FROM websites where id BETWEEN "1" AND "5"; /* 查询表下字段范围数据 */ SELECT * FROM websites WHERE name in ("广西","百度"); /* 查询表字段下固定条件数据 */ SELECT DISTINCT country FROM Websites; /* 查询去重值 */ SELECT * FROM Websites WHERE country = "CN" AND alexa > 50; /*查询表下范围条件数据*/ SELECT * FROM Websites WHERE country = "USA" OR country="sh"; /* 查询表下条件不同值 */ SELECT * FROM Websites ORDER BY alexa; /* 查询表下值排序结果 */ SELECT * FROM Websites ORDER BY alexa DESC; /* 查询表下排序结果降序 */ SELECT * FROM Websites LIMIT 2; /* 查询表下范围数据 */ SELECT name as zzz from websites; /*别名查询表下数据*/
多表关联查询
select 字段 from 表1 left join 表2 on 条件 (一般为表1与表2的关联条件)
请求数据的几种方式已经springmvc的接受
一. form表单提交
GET方式
前端表单传参
<form action="http://localhost:8080/test" method="get"> <input type="text" name="username" /> <input type="text" name="password"/> <input type="submit" value="Submit" /> </form>
后端参数接收,因为 form 表单使用 get 方法的时候,Content type 的值默认为空。所以后台接收代码不需要指定 consumes 属性
@ResponseBody @RequestMapping(value = "/test", method = RequestMethod.GET) public String test1(@RequestParam(value="username") String username, @RequestParam(value="password") String password){ System.out.println("======GET======"); System.out.println("username=" + username); System.out.println("password=" + password); return "SUCCESS"; }
打印结果:
======GET====== username=wangbo password=123456
可以看出 FORM 表单发出的 GET 请求直接通过注解 @RequestParam 进行参数接口即可。
POST方式
前端表单传参
<form action="http://localhost:8080/test" method="post"> <input type="text" name="username" /> <input type="text" name="password"/> <input type="submit" value="Submit" /> </form>
后端参数接收,
因为 form 表单使用 post 方法的时候,
Content type 的值默认为 application/x-www-form-urlencoded;charset=UTF-8。
所以后台接收代码需要指定 consumes 属性。
consumes = "application/x-www-form-urlencoded;charset=UTF-8"
@ResponseBody @RequestMapping(value = "/test", method = RequestMethod.POST, consumes = "application/x-www-form-urlencoded;charset=UTF-8") public String test(@RequestParam(value="username") String username, @RequestParam(value="password") String password, User user){ System.out.println("======POST======"); System.out.println("username=" + username); System.out.println("password=" + password); System.out.println("user=" + user); return "SUCCESS"; }
打印结果
======POST====== username=wangbo password=123456 user=username=wangbo; password=123456
可以看出,FORM 表单发出的 POST 请求可以直接通过注解 @RequestParam 进行参数接收,
也可以使用字段对应封装的 Java Bean 对象来接收参数。注意 Java Bean 对象上不需要注解。
User 代码,为了更清楚的打印对象,重写了 toString 代码。
二. resuful风格的获取get的提交
@PathVariable
只能接收 URL 路径里的参数。
function update(e) { window.location.href="/selectItem/"+e; }
@GetMapping(value ="/selectItem/{id}") public String selectItem(@PathVariable("id") Integer id,Model model){ School school= schoolService.selectItem(id); model.addAttribute("school",school); return "updatelist"; }
@RequestParam
只能接收 URL 问号后跟着的参数,不管是 GET 还是 POST,虽然一般只有 GET 请求才会在 URL 后边跟参数,问号 ? 后面的部分,使用 & 区分参数。
http://localhost:8080/api/user/login/test?username=2222222&pass=333333333 @RequestParam("username")String username, @RequestParam("pass")String pass
三. Post请求
@RequestBody
只能接收请求体中的参数,也就是只能是 POST 请求才有请求体,GET 请求没有请求体,请求体分两种情况参数
(1)使用String接收
比如前端参数在请求体中传的是 username=18514335982&pass=12345,Content type 为 text/plain;charset=UTF-8
则后台接收到的 param 即为 username=18514335982&pass=12345 格式
@RequestBody String param
(2)使用封装的 bean 或者 JSONObject 接收(常用)
前端必须使用 JSON 格式的数据,Content-Type 必须为 application/json,请求体中参数为 {"username":"18514335982","pass":"12345"}
@RequestBody User user @RequestBody JSONObject jsonObject
@PostMapping("/login/test") public ResultBuilder userLogin1(@RequestHeader(Constants.ACCEPT_VERSION)String version, @RequestHeader(Constants.ACCESS_TOKEN)String token, @RequestParam("username")String username, @RequestParam("pass")String pass, @RequestBody User user){ logger.debug("username======" + username); logger.debug("pass======" + pass); logger.debug("user---username==" + user.getUsername()); logger.debug("user---pass==" + user.getPass()); return new ResultBuilder(StatusCode.SUCCESS); }
四.ajax发送请求
var data = {'id':id,'name':name}; $.ajax({ type:"POST", url:"user/saveUser", dataType:"json", //contentType:"application/json", //不能添加这个头 data:data, //这里不能进行JSON.stringify,发送请求的数据在:form data success:function(data){ } });
//看成单值 @RequestMapping(value = "save", method = {RequestMethod.POST }) @ResponseBody public void save(@RequestParam int id,String name) { //这里字段要跟前端一致,@RequsetParam 可以不加,默认调用的就是它 } //看成对象 @RequestMapping(value = "save", method = {RequestMethod.POST }}) @ResponseBody public void save(User user) { //前端字段跟对象属性一致 //自动转化成改对象 }
json对象转成字符串后传值
function addcart(productid,number,price){ var cart={ "userid":1, "productid":123, "number":213, "price":3 } $.ajax({ type : "POST", url : "${pageContext.request.contextPath}/useraddCart", dataType:"json", contentType:"application/json", data:JSON.stringify(cart), success : function(data){ console.log(data) } }) }
@RequestMapping(value="/useraddCart",method=RequestMethod.POST) @ResponseBody public HappyFarmCart useraddCart(@RequestBody HappyFarmCart happyFarmCart){ System.out.println(happyFarmCart.toString()); return happyFarmCart; }
将对象JSON.stringify后,以第一种方式传递,可实现对象中存对象 {'userList':users,'key1':value1}
var user = {'id':id,'name':name}; var jsonStrGoods = JSON.stringify({'gid':gid,...}); $.ajax({ type:"POST", url:"user/saveUser", dataType:"json", // contentType:"application/json", //不添加这个头 data:{'user':JSON.stringify(user),'goods':jsonStrGoods }, //发送请求的数据在request payload success:function(data){ } });
//看成单值 @RequestMapping(value = "save", method = {RequestMethod.POST }}) @ResponseBody public void save(@RequestParam String user,String goods) { //这里字段要跟前端一致,@RequsetParam 可以不加,默认调用的就是它 User u= JSON.parseObject(user, User .class);//alibaba.fastjson转换成对象 } //看成对象 @RequestMapping(value = "save", method = {RequestMethod.POST }}) @ResponseBody public void save(UserAndGoods ug) { //没试过,猜测应该是这样,前端字段跟对象属性一致 //自动转化成改对象 }
传数组
var arr = str.split(','); $.ajax({ url:'/appollo-console/manage/user/names/validation', data:{ names:arr }, traditional: true,//必须 type:'post', dataType:'json', success:function(res){ alert(res); } })
@PostMapping("/names/validation") @ResponseBody public List<String> validateUserName(String[] names){ List<String> notValidNames = Lists.newArrayList(); notValidNames = userService.findNotValidNames(Arrays.asList(names)); return notValidNames; }
总结:
1.如果用JSON.stringify()将对象转成字符串,就需要在ajax请求中指定contentType 为 application/json,且后台需添加 @RequestBody注解;
2.如果直接传json对象则跟上面的相反,不能指定contentType为 application/json,其默认类型是 application/x-www-form-urlencoded
五.axios请求方式
get请求
testGet: function () { axios({ method: 'get', url: '/test/greeting', params: { firstName: 'Fred', lastName: 'Flintstone' } }).then(function (response) { console.log(response); }).catch(function (error) { console.log(error); }); },
post请求
testPost: function () { var params = new URLSearchParams(); params.append('name', 'hello jdmc你好'); params.append('id', '2'); axios({ method: 'post', url: '/test/greeting2', data:params // data: {id: '3', name: 'abc'} }).then(function (response) { console.log(response); }).catch(function (error) { console.log(error); }) }
注意:
在使用post方式的时候传递参数有两种方式,一种是普通方式,一种是json方式,如果后台接受的是普通方式,那么使用上述方式即可。
普通的formed方式
var params = new URLSearchParams(); params.append('name', 'hello jdmc你好'); params.append('id', '2'); data:params
后台接收参数:
public Student greeting2(int id,String name)
json方式
data: {id: '3', name: 'abc'}
后台接收参数
public Object greeting2(@RequestBody Object data)
在jsp页面请求之后渲染到html
web请求静态资源上下文
${pageContext.request.contextPath}
yml基本模板
server: port: 8080 spring: datasource: username: root password: 123456 url: jdbc:mysql://localhost:3306/springmvc?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=UTC driver-class-name: com.mysql.cj.jdbc.Drivermybatis: #一定不能错,要不然Mapper扫描不到,在主类配置MapperScan mapper-locations: classpath:mapper/*.xml type-aliases-package: com.edu.entity resources: static-locations: ["/templates/","/static/",] thymeleaf: prefix: classpath:/templates/ suffix: .html cache: false
Mysql
SQL HAVING 子句
HAVING 子句
在 SQL 中增加 HAVING 子句原因是,WHERE 关键字无法与聚合函数一起使用。
HAVING 子句可以让我们筛选分组后的各组数据。
SQL HAVING 语法
SELECT column_name, aggregate_function(column_name) FROM table_name WHERE column_name operator value GROUP BY column_name HAVING aggregate_function(column_name) operator value;
springmvc
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd"> <!-- @Controller注解扫描,里面的类标上注解可以识别 ,识别controller下的类--> <context:component-scan base-package="cn.itheima.controller"></context:component-scan> <!-- 注解驱动: 根据 扫面 @RequestMapping等注解 替我们显示的配置了最新版的注解的处理器映射器和处理器适配器 --> <mvc:annotation-driven></mvc:annotation-driven> <!-- 配置视图解析器 作用:在controller中指定页面路径的时候就不用写页面的完整路径名称了,可以直接写页面去掉扩展名的名称 --> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <!-- 真正的页面路径 = 前缀 + 去掉后缀名的页面名称 + 后缀 --> <!-- 前缀 --> <property name="prefix" value="/WEB-INF/jsp/"></property> <!-- 后缀 --> <property name="suffix" value=".jsp"></property> </bean> <!-- 配置自定义转换器 注意: 一定要将自定义的转换器配置到注解驱动上 --> <!-- 指定自定义转换器的全路径名称 --> <!-- <bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean"> <property name="converters"> <set> <bean class="cn.itheima.controller.converter.CustomGlobalStrToDateConverter"/> </set> </property> </bean>--> <!-- 与静态文件的加载有关 <mvc:resources location="/,classpath:/META-INF/publicResources/" mapping="/resources/**"/> 以上配置将Web根路径"/"及类路径下 /META-INF/publicResources/ 的目录映射为/resources路径。假设Web根路径下拥有images、js这两个资源目录,在images下面有bg.gif图片,在js下面有test.js文件, 则可以通过 /resources/images/bg.gif 和 /resources/js/test.js 访问这二个静态资源。 假设WebRoot还拥有images/bg1.gif 及 js/test1.js, 则也可以在网页中通过 /resources/images/bg1.gif 及 /resources/js/test1.js 进行引用。 --> <!-- 处理不了的交给tomcat,也就是静态文件的映射 --> <mvc:default-servlet-handler/> <!-- 映射静态文件的路径 --> <mvc:resources location="/js/" mapping="/js/**"/> </beans>