济南产品网站建设外包,北京网站建设哪里好,国内电商推广,iis搭建网站目录 一、Mybatis快速入门1.创建Springboot工程#xff0c;数据库表user#xff0c;实体类User2.引入Mybaties相关依赖3.编写Sql语句 二、lombok1.基本概念2.使用方法 三、基础操作1.环境准备a.数据库准备b.创建员工实体类Emp数据类型对比命名对比 c.Mapper接口创建 2.删除操… 目录 一、Mybatis快速入门1.创建Springboot工程数据库表user实体类User2.引入Mybaties相关依赖3.编写Sql语句 二、lombok1.基本概念2.使用方法 三、基础操作1.环境准备a.数据库准备b.创建员工实体类Emp数据类型对比命名对比 c.Mapper接口创建 2.删除操作代码测试有返回值的删除日志输出参数占位符 3.添加操作3.1 插入的sql语句3.2 定义接口方法3.3 测试3.4 主键返回 4.修改操作4.1 sql语句4.2 接口实现4.3测试 5.查询操作根据id查询5.1 sql语句5.2 接口文档5.3 测试5.4 数据封装解决命名不一致 6. 查询操作条件查询6.1 sql语句6.2 接口6.3测试6.4优化 四、动态sql1.if 一、Mybatis快速入门
1.创建Springboot工程数据库表user实体类User
首先我们要先创建springboot工程选择mysql和mybatis驱动
然后创建sql表插入数据
create database spring;
use spring;
create table student( id int auto_increment primary key , name char(20), age int, gender int, phone char(20)
);
insert into student(name, age, gender, phone) value (rosen,19,0,10086);
insert into student(name, age, gender, phone) value (rose,18,0,10087);实体类的创建,pojo包
package com.rosen.pojo; public class User { private Integer id; private String name; private Short age; private Short gender; private String phone; public User() { } public User(Integer id, String name, Short age, Short gender, String phone) { this.id id; this.name name; this.age age; this.gender gender; this.phone phone; } public Integer getId() { return id; } public void setId(Integer id) { this.id id; } public String getName() { return name; } public void setName(String name) { this.name name; } public Short getAge() { return age; } public void setAge(Short age) { this.age age; } public Short getGender() { return gender; } public void setGender(Short gender) { this.gender gender; } public String getPhone() { return phone; } public void setPhone(String phone) { this.phone phone; }
}2.引入Mybaties相关依赖 #驱动类名
spring.datasource.driver-class-namecom.mysql.jdbc.Driver
#连接数据库的url
spring.datasource.urljdbc:mysql://localhost:3306/spring
#连接数据库的用户名
spring.datasource.usernameroot
#连接数据库的密码
spring.datasource.password1234563.编写Sql语句
在mapper文件夹相当于dao层编写UserMapper接口
Mapper会自动进入容器,注释Select来进行编写
package com.rosen.mapper; import com.rosen.pojo.User;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select; import java.util.List; Mapper
public interface UserMapper { Select(select * from student) public ListUser list();
}在测试类中进行单元测试
SpringBootTest
class SpringMybatisApplicationTests { Autowired private UserMapper userMapper; Test public void testUser() { ListUser userListuserMapper.list(); userList.stream().forEach(user - { System.out.println(user.toString()); }); } }二、lombok
我们看见User类是不是除了属性还要写getset方法tostring方法等是不是很麻烦也显得类很臃肿我们只需要lombok给的注解就可以简化
1.基本概念
Lombok是一个实用的Java类库能够通过注解的形成自动生成构造器并且自动化生成日志变量简化开发
2.使用方法
因此一般直接在类上面加上Data就可以
首先要maven导包 不用指定版本springboot会自动选择
dependency groupIdorg.projectlombok/groupId artifactIdlombok/artifactId
/dependency原有代码
package com.rosen.pojo; public class User { private Integer id; private String name; private Short age; private Short gender; private String phone; public User() { } public User(Integer id, String name, Short age, Short gender, String phone) { this.id id; this.name name; this.age age; this.gender gender; this.phone phone; } public Integer getId() { return id; } public void setId(Integer id) { this.id id; } public String getName() { return name; } public void setName(String name) { this.name name; } public Short getAge() { return age; } public void setAge(Short age) { this.age age; } public Short getGender() { return gender; } public void setGender(Short gender) { this.gender gender; } public String getPhone() { return phone; } public void setPhone(String phone) { this.phone phone; } Override public String toString() { return User{ id id , name name \ , age age , gender gender , phone phone \ }; }
}注解修改可以看到代码量减少非常多
Data
NoArgsConstructor
AllArgsConstructor
public class User { private Integer id; private String name; private Short age; private Short gender; private String phone;
}lombok会在编译的时候自动生成对应java代码
三、基础操作
1.环境准备
a.数据库准备
-- 部门管理create table dept(id int unsigned primary key auto_increment comment 主键ID,name varchar(10) not null unique comment 部门名称,create_time datetime not null comment 创建时间,update_time datetime not null comment 修改时间) comment 部门表;insert into dept (id, name, create_time, update_time) values(1,学工部,now(),now()),(2,教研部,now(),now()),(3,咨询部,now(),now()), (4,就业部,now(),now()),(5,人事部,now(),now());-- 员工管理create table emp (id int unsigned primary key auto_increment comment ID,username varchar(20) not null unique comment 用户名,password varchar(32) default 123456 comment 密码,name varchar(10) not null comment 姓名,gender tinyint unsigned not null comment 性别, 说明: 1 男, 2 女,image varchar(300) comment 图像,job tinyint unsigned comment 职位, 说明: 1 班主任,2 讲师, 3 学工主管, 4 教研主管, 5 咨询师,entrydate date comment 入职时间,dept_id int unsigned comment 部门ID,create_time datetime not null comment 创建时间,update_time datetime not null comment 修改时间) comment 员工表;INSERT INTO emp(id, username, password, name, gender, image, job, entrydate,dept_id, create_time, update_time) VALUES(1,jinyong,123456,金庸,1,1.jpg,4,2000-01-01,2,now(),now()),(2,zhangwuji,123456,张无忌,1,2.jpg,2,2015-01-01,2,now(),now()),(3,yangxiao,123456,杨逍,1,3.jpg,2,2008-05-01,2,now(),now()),(4,weiyixiao,123456,韦一笑,1,4.jpg,2,2007-01-01,2,now(),now()),(5,changyuchun,123456,常遇春,1,5.jpg,2,2012-12-05,2,now(),now()),(6,xiaozhao,123456,小昭,2,6.jpg,3,2013-09-05,1,now(),now()),(7,jixiaofu,123456,纪晓芙,2,7.jpg,1,2005-08-01,1,now(),now()),(8,zhouzhiruo,123456,周芷若,2,8.jpg,1,2014-11-09,1,now(),now()),(9,dingminjun,123456,丁敏君,2,9.jpg,1,2011-03-11,1,now(),now()),(10,zhaomin,123456,赵敏,2,10.jpg,1,2013-09-05,1,now(),now()),(11,luzhangke,123456,鹿杖客,1,11.jpg,5,2007-02-01,3,now(),now()),(12,hebiweng,123456,鹤笔翁,1,12.jpg,5,2008-08-18,3,now(),now()),(13,fangdongbai,123456,方东白,1,13.jpg,5,2012-11-01,3,now(),now()),(14,zhangsanfeng,123456,张三丰,1,14.jpg,2,2002-08-01,2,now(),now()),(15,yulianzhou,123456,俞莲舟,1,15.jpg,2,2011-05-01,2,now(),now()),(16,songyuanqiao,123456,宋远桥,1,16.jpg,2,2010-01-01,2,now(),now()),(17,chenyouliang,123456,陈友谅,1,17.jpg,NULL,2015-03-21,NULL,now(),now());dept部门表
emp员工表
b.创建员工实体类Emp
Data
NoArgsConstructor
AllArgsConstructor
public class Emp { private Integer id; private String username; private String password; private String name; private Short gender; private String image; private Short job; private LocalDate entrydate; private Integer deptId; private LocalDateTime createTime; private LocalDateTime updateTime;
}数据类型对比
LocalDate对应date LocalDateTime对应datetime sql中 date:日期YYYY-MM-DD datetime:日期时间YYYY-MM-DD HH:MM:SS Java中 LocalDate年月日 LocalTime时分秒 LocalDateTime年月日时分秒
命名对比
sql中无下划线username-usernamesql中由下划线create_time-createTime下划线的下一个字母大写就好
c.Mapper接口创建
Mapper
public interface EmpMapper {
}2.删除操作
代码
我们为了动态的删除不可能只删除一个数据比如id2可以用#{id}变成动态的参数了
Mapper
public interface EmpMapper { Delete(delete from emp where id#{id}) public void delete(Integer id);
}测试
在测试单元测试可以通过
SpringBootTest
class SpringMybatisApplicationTests { Autowired private EmpMapper empMapper; Test public void test() { empMapper.delete(17); }
}有返回值的删除
Mapper
public interface EmpMapper { Delete(delete from emp where id#{id}) public int delete(Integer id);
}测试之后发现输出0因为已经删除过了所以再次删除失败返回0反之返回1
SpringBootTest
class SpringMybatisApplicationTests { Autowired private EmpMapper empMapper; Test public void test() { int deleteempMapper.delete(17); System.out.println(delete); }
}日志输出
打开配置文件
配置日志这样就可以在控制台上看到到底执行了哪些sql
mybatis.configuration.log-implorg.apache.ibatis.logging.stdout.StdOutImpl可以看到已经可以看到日志了0代表没有真正删除 底下的带有的sql语句代表预编译sql执行的时候参数和预编译sql一同发送给数据库
为什么不直接代替问号呢 预编译sql优势
性能更高更加安全防止sql注入通过操作输入的数据来修改事先定义好的sql语句达到执行代码对服务器进行攻击的方法 比如
输入账户rosen 密码 123456
select count(*) from emp where usernamerosen and password123456
成功则进入
但是如果账户rosen密码为or11这个会发现
select count(*) from emp where usernamerosen and passwordor11
这个表达式不管怎么样都是成立的因为11一直成立所以sql注入执行流程 因为缓存区如果有sql语句那么就会直接拿取缓存而每次如果id不同的数字那么缓存会一直没有那么编译次数增加那很慢如果预编译sql不会看id多少会在缓存找到那么拼接后就会找到那么不久加快了
参数占位符
可以看出$会产生sql注入而#则不会一般使用#
3.添加操作
3.1 插入的sql语句
id自增长不需要插入 密码又默认不需要插入 create time和uodate_tima需要当前时间
insert into emp(username, name, gender, image, job, entrydate, dept_id, create_time, update_time)
values(Tom,汤姆,1,1.jpg,1,2005-01-01,1,now(),now());3.2 定义接口方法
我们还利用删除时候创建的接口 我们会发现如果还是像delete参数是自己设置的变量的话那么要设置很多变量所有我们传入一个对应类占位符里面是这个类的属性名
Mapper
public interface EmpMapper { Delete(delete from emp where id#{id}) public int delete(Integer id); Insert(insert into emp(username, name, gender, image, job, entrydate, dept_id, create_time, update_time) values(#{username},#{name},#{gender},#{image},#{job},#{entrydate},#{deptId},#{createTime},#{updateTime});) public void insert(Emp emp);
}3.3 测试
SpringBootTest
class SpringMybatisApplicationTests { Autowired private EmpMapper empMapper; Test public void testInsert() { //构造员工对象 Emp empnew Emp(); emp.setUsername(Tom); emp.setName(汤姆); emp.setImage(1.jpg); emp.setGender((short)1); emp.setJob((short)1); emp.setEntrydate(LocalDate.of(2000,1,1)); emp.setCreateTime(LocalDateTime.now()); emp.setUpdateTime(LocalDateTime.now()); emp.setDeptId(1); //新增操作 empMapper.insert(emp); }
}
测试成功
3.4 主键返回
在添加成功的时候需要获取插入数据库的主键 如添加套餐数据的时候需要添加套餐还有一个表是菜品套餐对应菜品需要知道套餐是说明才能选择菜品因此需要返回主键 代码实现 在插入方法上面加上注解Options
KeyProperty:代表插入到这个类的哪一个属性useGeneratedKeys true:是否返回主键
public interface EmpMapper { Delete(delete from emp where id#{id}) public int delete(Integer id); //获取主键会封装到对象的id属性中true是获取主键
Options(keyProperty id,useGeneratedKeys true)
Insert(insert into emp(username, name, gender, image, job, entrydate, dept_id, create_time, update_time) values(#{username},#{name},#{gender},#{image},#{job},#{entrydate},#{deptId},#{createTime},#{updateTime});)
public void insert(Emp emp);
}测试
Test
public void testInsert()
{ //构造员工对象 Emp empnew Emp(); emp.setUsername(Tom1); emp.setName(汤姆3); emp.setImage(1.jpg); emp.setGender((short)1); emp.setJob((short)1); emp.setEntrydate(LocalDate.of(2000,1,1)); emp.setCreateTime(LocalDateTime.now()); emp.setUpdateTime(LocalDateTime.now()); emp.setDeptId(1); //新增操作 empMapper.insert(emp); System.out.println(emp.getId());
}4.修改操作
4.1 sql语句
update emp set username ,name,gender,image,job,entrydate,dept_id,update_time where id1;4.2 接口实现
Update(update emp set username #{username},name#{name},gender#{gender},image#{image},job#{job},entrydate#{entrydate},dept_id#{deptId},update_time#{updateTime} where id#{id};)
public void update(Emp emp);4.3测试
Test
public void testUpdate()
{ //构造员工对象 Emp empnew Emp(); emp.setId(18); emp.setUsername(Tom6); emp.setName(汤姆6); emp.setImage(1.jpg); emp.setGender((short)1); emp.setJob((short)1); emp.setEntrydate(LocalDate.of(2000,2,2)); emp.setUpdateTime(LocalDateTime.now()); emp.setDeptId(1); //新增操作 empMapper.update(emp); System.out.println(emp.getId());
}5.查询操作根据id查询
5.1 sql语句
select * from emp where id20;5.2 接口文档
查询是由返回值的,返回对象就行
Select(select * from emp where id#{id};)
public Emp getById(Integer id);5.3 测试
Test
public void select(){ Emp emp empMapper.getById(20); System.out.println(emp);
}但是发现有三个值没有进行封装为什么呢
如果数据库和实体类的字段名一致因此mybatis会自动封装 如何解决问题——数据封装
5.4 数据封装解决命名不一致
方案1 sql起别名
方案2 注解起别名
方案3 配置文件设置驼峰命名
mybatis.configuration.map-underscore-to-camel-casetrue成功展示
6. 查询操作条件查询
6.1 sql语句
包括模糊查询时间排序范围查询
select *from emp where name like %张% and
gender 1 and entrydate between 2010-01-01 and 2020-01-02 order by update_time desc ;6.2 接口
因为模糊查询里面的引号不能使用注入因此用$进行拼接处理。
Select(select *from emp where name like %${name}% and gender #{gender} and entrydate between #{begin} and #{end} order by update_time desc )
public ListEmp list(String name, Short gender, LocalDate begin, LocalDate end);6.3测试
Test
public void select2()
{ ListEmp empList empMapper.list(张, (short) 1, LocalDate.of(2010, 1, 1), LocalDate.of(2020, 1, 1)); System.out.println(empList);
}发现欸这样用$符号还是有问题啊会sql注入不安全咋办呢用sql的函数
6.4优化
contact字符串连接
Select(select *from emp where name like concat(%,#{name},%) and gender #{gender} and entrydate between #{begin} and #{end} order by update_time desc )
public ListEmp list(String name, Short gender, LocalDate begin, LocalDate end);可以看到已经成功了
xml操作部分和动态sqljavaweb进行部分的描述不在进行赘述
四、动态sql
xml配置在之前的非进阶学习过直接给例子进行动态sql
1.if
可能多个属性但是只用传输过来的条件 在resource创建对应的xml文件 com/rosen/mapper/EmpMapper.xml 注意名字要一样
上面是固定的namespace“com.rosen.mapper.EmpMapper”代表接口的位置id‘list’方法名resulttype返回类型因为如果是用where的话可能多一个and或多一个where因此where会自动去除
?xml version1.0 encodingUTF-8 ?
!DOCTYPE mapper PUBLIC -//mybatis.org//DTD Mapper 3.0//EN https://mybatis.org/dtd/mybatis-3-mapper.dtd mapper namespacecom.rosen.mapper.EmpMapper select idlist resultTypecom.rosen.pojo.Emp select * from emp where if testname!null name like concat(%,#{name},%) /if if testgender!null and gender#{gender} /if if testbegin!null and end!null and entrydate between #{begin} and #{end} /if order by update_time desc /where /select/mapper## 2.foreach
删除对应数据用foreach实现动态sqlcollections:参数 item拿出来的实体自己取名separator以什么分割open左边拼接close右边拼接
xml
mapper namespacecom.rosen.mapper.EmpMapper delete iddelete delete from where emp id in foreach collectionids itemid separator, open( close) #{id} /foreach /delete /select/mapper