Mybatis与http相关请求
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>
