網(wǎng)站備案流程實(shí)名認(rèn)證東莞網(wǎng)站制作外包
目錄
環(huán)境準(zhǔn)備
①Emp.sql
②Emp.java
一、刪除
①M(fèi)apper層
②測(cè)試類
③預(yù)編譯SQL(查看mybatis日志)
1.性能
2.安全
④總結(jié)
二、新增
①M(fèi)apper層
②測(cè)試類
③結(jié)果
④新增(主鍵返回)
1.Mapper層
2.測(cè)試類
⑤總結(jié)?編輯
三、更新(修改)
案例
①M(fèi)apper層
②測(cè)試類
四、查詢
(一)根據(jù)主鍵ID查詢數(shù)據(jù)回顯展示
①M(fèi)apper層
②測(cè)試類
③解決數(shù)據(jù)無(wú)法封裝的問(wèn)題
方案一:給字段起別名,讓別名與實(shí)體類屬性一致
結(jié)果?編輯
方案二:通過(guò)mybatis中的@Results,@Result注解手動(dòng)映射封裝
結(jié)果?編輯
方案三:Mybatis駝峰命名自動(dòng)映射的開關(guān) a-column =》 aColumn
結(jié)果
總結(jié)
思考?
(二)根據(jù)條件查詢數(shù)據(jù)回顯展示
①M(fèi)apper層
②測(cè)試類
③結(jié)果
④Concat()
1.Mapper層
2.結(jié)果
五、XML映射文件(配置文件)
①EmpMapper.xml
②Mapper層
③測(cè)試類
④思考
⑤總結(jié)
環(huán)境準(zhǔn)備
①Emp.sql
-- 部門管理
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 '創(chuàng)建時(shí)間',update_time datetime not null comment '修改時(shí)間'
) comment '部門表';insert into dept (id, name, create_time, update_time) values(1,'學(xué)工部',now(),now()),(2,'教研部',now(),now()),(3,'咨詢部',now(),now()), (4,'就業(yè)部',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 '性別, 說(shuō)明: 1 男, 2 女',image varchar(300) comment '圖像',job tinyint unsigned comment '職位, 說(shuō)明: 1 班主任,2 講師, 3 學(xué)工主管, 4 教研主管, 5 咨詢師',entrydate date comment '入職時(shí)間',dept_id int unsigned comment '部門ID',create_time datetime not null comment '創(chuàng)建時(shí)間',update_time datetime not null comment '修改時(shí)間'
) 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','張無(wú)忌',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','紀(jì)曉芙',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','宋遠(yuǎn)橋',1,'16.jpg',2,'2010-01-01',2,now(),now()),(17,'chenyouliang','123456','陳友諒',1,'17.jpg',NULL,'2015-03-21',NULL,now(),now());
②Emp.java
package com.itheima.pojo;import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.time.LocalDate;
import java.time.LocalDateTime;@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;//日期時(shí)分秒private LocalDateTime updateTime;
}
一、刪除
mybatis的參數(shù)占位符#{}
①M(fèi)apper層
package com.itheima.mapper;import org.apache.ibatis.annotations.*;@Mapper
public interface EmpMapper {
// 根據(jù)ID刪除數(shù)據(jù)@Delete("delete from emp where id=#{id}")
// public void deltte(Integer id);//返回值代表此次操作影響的記錄數(shù)public int delete(Integer id);
}
②測(cè)試類
package com.itheima;import com.itheima.mapper.EmpMapper;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;@SpringBootTest
class SpringbootMybatisCrudApplicationTests {@Autowiredprivate EmpMapper empMapper;@Testpublic void testDelete(){int delete= empMapper.delete(17);System.out.println(delete);}
}
③預(yù)編譯SQL(查看mybatis日志)
?
1.性能
在JAVA項(xiàng)目中,要想執(zhí)行SQL語(yǔ)句,需要鏈接上數(shù)據(jù)庫(kù),然后把SQL語(yǔ)句發(fā)送給數(shù)據(jù)庫(kù)服務(wù)器,數(shù)據(jù)庫(kù)服務(wù)器并不是立即執(zhí)行SQL語(yǔ)句,而是先對(duì)SQL語(yǔ)句進(jìn)行語(yǔ)法解析檢查=》優(yōu)化SQL=》編譯SQL(編譯為可執(zhí)行函數(shù))=》執(zhí)行SQL語(yǔ)句
為了提高效率,數(shù)據(jù)庫(kù)服務(wù)器會(huì)把優(yōu)化編譯的SQL緩存起來(lái),下次再執(zhí)行SQL,會(huì)先檢查是否已有SQL緩存
然而因?yàn)槿龡l語(yǔ)句的id不一致,數(shù)據(jù)庫(kù)服務(wù)器會(huì)三次執(zhí)行編譯3次
如果采用預(yù)編譯的SQL,不會(huì)把字段值直接拼接到SQL語(yǔ)句,而是使用?占位符,把SQL語(yǔ)句和字段值發(fā)送給數(shù)據(jù)庫(kù)服務(wù)器,先對(duì)SQL語(yǔ)句進(jìn)行語(yǔ)法解析檢查=》優(yōu)化SQL=》編譯SQL(編譯為可執(zhí)行函數(shù))=》執(zhí)行SQL語(yǔ)句
執(zhí)行SQL語(yǔ)句的時(shí)候,會(huì)用參數(shù)值替代掉占位符
為了提高效率,數(shù)據(jù)庫(kù)服務(wù)器會(huì)把優(yōu)化編譯的SQL緩存起來(lái),下次再執(zhí)行SQL,會(huì)先檢查是否已有SQL緩存
三條語(yǔ)句的id不一致,但是緩存中的SQL語(yǔ)句是一致的,數(shù)據(jù)庫(kù)服務(wù)器只會(huì)執(zhí)行編譯1次
2.安全
預(yù)編譯防止SQL注入的原理就是將敏感字符轉(zhuǎn)義成普通字符
④總結(jié)
二、新增
當(dāng)傳遞參數(shù)有多個(gè)的時(shí)候,可以用實(shí)體類來(lái)傳遞,占位符里寫的是實(shí)體類的屬性名(駝峰命名)
①M(fèi)apper層
package com.itheima.mapper;import com.itheima.pojo.Emp;
import org.apache.ibatis.annotations.*;@Mapper
public interface EmpMapper {@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);
}
②測(cè)試類
package com.itheima;import com.itheima.mapper.EmpMapper;
import com.itheima.pojo.Emp;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;import java.time.LocalDate;
import java.time.LocalDateTime;@SpringBootTest
class SpringbootMybatisCrudApplicationTests {@Autowiredprivate EmpMapper empMapper;@Testpublic void testInsert(){//構(gòu)造員工對(duì)象Emp emp=new Emp();emp.setUsername("Tom");emp.setName("tom");emp.setImage("1.jpg");emp.setGender((short)1);emp.setJob((short)1);emp.setEntrydate(LocalDate.of(200,1,1));emp.setCreateTime(LocalDateTime.now());emp.setUpdateTime(LocalDateTime.now());emp.setDeptId(1);//執(zhí)行新增員工信息操作empMapper.insert(emp);
}
}
③結(jié)果
④新增(主鍵返回)
1.Mapper層
package com.itheima.mapper;import com.itheima.pojo.Emp;
import org.apache.ibatis.annotations.*;@Mapper
public interface EmpMapper {@Options(useGeneratedKeys = true,keyProperty = "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);
}
需要在插入后獲得返回的主鍵,在方法上面加Options注解,指定兩個(gè)屬性,userGeneratedKeys=true代表我們要返回的主鍵,keyProperty代表把返回的主鍵往emp的Id屬性封裝
2.測(cè)試類
package com.itheima;import com.itheima.mapper.EmpMapper;
import com.itheima.pojo.Emp;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;import java.time.LocalDate;
import java.time.LocalDateTime;@SpringBootTest
class SpringbootMybatisCrudApplicationTests {@Autowiredprivate EmpMapper empMapper;@Testpublic void testInsert(){//構(gòu)造員工對(duì)象Emp emp=new Emp();emp.setUsername("Tom4");emp.setName("tom4");emp.setImage("1.jpg");emp.setGender((short)1);emp.setJob((short)1);emp.setEntrydate(LocalDate.of(200,1,1));emp.setCreateTime(LocalDateTime.now());emp.setUpdateTime(LocalDateTime.now());emp.setDeptId(1);//執(zhí)行新增員工信息操作empMapper.insert(emp);System.out.println(emp.getId());
}
}
⑤總結(jié)
三、更新(修改)
案例
業(yè)務(wù)
第一步,根據(jù)主鍵ID查詢數(shù)據(jù)回顯展示
第二步,在界面數(shù)據(jù)修改完畢后點(diǎn)擊保存,此時(shí)進(jìn)行修改操作,(根據(jù)主鍵ID修改,因?yàn)樗粫?huì)改變)
點(diǎn)擊編輯,會(huì)根據(jù)當(dāng)前這條數(shù)據(jù)的主鍵Id來(lái)查詢數(shù)據(jù),并且將該記錄回顯展示出來(lái),此時(shí)我們就可以在原有數(shù)據(jù)的基礎(chǔ)上對(duì)其進(jìn)行修改,操作完畢點(diǎn)擊保存按鈕,就會(huì)將該表單數(shù)據(jù)提交到服務(wù)端,最終修改表中的字段值
根據(jù)主鍵修改員工信息
①M(fèi)apper層
package com.itheima.mapper;import com.itheima.pojo.Emp;
import org.apache.ibatis.annotations.*;@Mapper
public interface EmpMapper {@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);
}
②測(cè)試類
package com.itheima;import com.itheima.mapper.EmpMapper;
import com.itheima.pojo.Emp;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;import java.time.LocalDate;
import java.time.LocalDateTime;@SpringBootTest
class SpringbootMybatisCrudApplicationTests {@Autowiredprivate EmpMapper empMapper;//更新員工@Testpublic void testUpdate(){//構(gòu)造員工對(duì)象Emp emp=new Emp();emp.setId(18);emp.setUsername("Tom1");emp.setName("Tom1");emp.setImage("1.jpg");emp.setGender((short)1);emp.setJob((short)1);emp.setEntrydate(LocalDate.of(2000,1,1));emp.setUpdateTime(LocalDateTime.now());//執(zhí)行更新員工操作empMapper.update(emp);}
}
四、查詢
(一)根據(jù)主鍵ID查詢數(shù)據(jù)回顯展示
①M(fèi)apper層
package com.itheima.mapper;import com.itheima.pojo.Emp;
import org.apache.ibatis.annotations.*;@Mapper
public interface EmpMapper {//根據(jù)ID查詢員工信息@Select("select * from emp where id=#{id};")public Emp getById(Integer id);
}
②測(cè)試類
package com.itheima;import com.itheima.mapper.EmpMapper;
import com.itheima.pojo.Emp;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;import java.time.LocalDate;
import java.time.LocalDateTime;@SpringBootTest
class SpringbootMybatisCrudApplicationTests {@Autowiredprivate EmpMapper empMapper; //根據(jù)ID查詢員工信息@Testpublic void testGetById(){Emp emp=empMapper.getById(20);System.out.println(emp);}
}
③解決數(shù)據(jù)無(wú)法封裝的問(wèn)題
方案一:給字段起別名,讓別名與實(shí)體類屬性一致
修改Mapper層的接口中的SQL即可
public void update(Emp emp);//根據(jù)ID查詢員工信息@Select("select id, username, password, name, gender, image, job, entrydate, dept_id deptId, create_time createTime, " +"update_time updateTime from emp where id=#{id};")public Emp getById(Integer id);
結(jié)果
方案二:通過(guò)mybatis中的@Results,@Result注解手動(dòng)映射封裝
修改Mapper層的接口中的SQL即可
//根據(jù)ID查詢員工信息@Results({@Result(column = "dept_id",property ="deptID"),@Result(column = "create_time",property ="createTime"),@Result(column = "update_time",property ="updateTime")})@Select("select * from emp where id=#{id}")public Emp getById(Integer id);
@Results注解中的Values是@Result數(shù)組,每一個(gè)@Result表示映射一個(gè)字段和屬性,column是表中的字段名,property是類中的屬性名
結(jié)果
方案三:Mybatis駝峰命名自動(dòng)映射的開關(guān) a-column =》 aColumn
前提:表中字段名帶下劃線分割,實(shí)體中的屬性名是駝峰命名
將字段名帶下劃線的自動(dòng)封裝為實(shí)體類中的駝峰式屬性
在application.properties中配置Mybatis駝峰命名自動(dòng)映射的開關(guān),原來(lái)的Mapper層接口不需要修改
加入以下代碼
#開啟Mybatis駝峰命名自動(dòng)映射的開關(guān)
mybatis.configuration.map-underscore-to-camel-case=true
結(jié)果
總結(jié)
思考?
思考:為什么Java中實(shí)體類的屬性名不更改為和數(shù)據(jù)庫(kù)一樣的下劃線呢?
約定俗成,Java中實(shí)體類的屬性名應(yīng)該是駝峰命名
思考:為什么數(shù)據(jù)庫(kù)中字段名不更改為與Java相同的駝峰命名呢?
數(shù)據(jù)庫(kù)不區(qū)分大小寫,在數(shù)據(jù)庫(kù)用不了駝峰,如果你Java用了駝峰就映射不上
思考:數(shù)據(jù)庫(kù)字段為什么要用下劃線命名??
數(shù)據(jù)庫(kù)字段使用下劃線命名是一種規(guī)范化命名方法,目的是使數(shù)據(jù)命名更加清晰,易讀性更強(qiáng),并且易于被程序識(shí)別。
(二)根據(jù)條件查詢數(shù)據(jù)回顯展示
①M(fèi)apper層
package com.itheima.mapper;import com.itheima.pojo.Emp;
import org.apache.ibatis.annotations.*;import java.time.LocalDate;
import java.util.List;@Mapper
public interface EmpMapper {//條件查詢員工信息@Select("select * from emp where name like '%${name}%' and gender=#{gender} and " +"entrydate between #{begin} and #{end} order by update_time desc ;")public List<Emp> list(String name, Short gender, LocalDate begin,LocalDate end);
}
entryDate是一個(gè)范圍,而屬性entrydate是一個(gè)值,無(wú)法封裝范圍,故而直接用參數(shù)傳遞
? ? '%#{name}%' ?單引號(hào)中的%表示要進(jìn)行模糊匹配,而#{name}進(jìn)行預(yù)編譯后會(huì)被?取代,?是不能被放入單引號(hào)內(nèi)的,
? ? 所以要把#改為$,$是字符串拼接,直接將傳遞過(guò)來(lái)的name和兩個(gè)字符串%拼接起來(lái)就可以了
②測(cè)試類
package com.itheima;import com.itheima.mapper.EmpMapper;
import com.itheima.pojo.Emp;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List;@SpringBootTest
class SpringbootMybatisCrudApplicationTests {@Autowiredprivate EmpMapper empMapper;@Testpublic void testList(){List<Emp> empList= empMapper.list("z",(short)1,LocalDate.of(2010,1,1),LocalDate.of(2020,1,1));System.out.println(empList);}
}
③結(jié)果
④Concat()
然而使用$拼接字符串存在安全問(wèn)題并且效率不高
故而可以使用mybatis中的concat()函數(shù)對(duì)字符進(jìn)行拼接
concat('%',#{name},'%') ,這樣#{name}就不會(huì)出現(xiàn)在單引號(hào)內(nèi)
1.Mapper層
package com.itheima.mapper;import com.itheima.pojo.Emp;
import org.apache.ibatis.annotations.*;import java.time.LocalDate;
import java.util.List;@Mapper
public interface EmpMapper {@Select("select * from emp where name like concat('%',#{name},'%') and gender=#{gender} and " +"entrydate between #{begin} and #{end} order by update_time desc ;")public List<Emp> list(String name, Short gender, LocalDate begin,LocalDate end);}
2.結(jié)果
這里生成的就是預(yù)編譯的SQL
五、XML映射文件(配置文件)
源文件放在java中,而配置文件放在resources中
官網(wǎng):mybatis – MyBatis 3 | 簡(jiǎn)介
①EmpMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.itheima.mapper.EmpMapper">
<!-- resultType:單條記錄所封裝的類型--><select id="list" resultType="com.itheima.pojo.Emp">select * from emp where name like concat('%',#{name},'%') and gender=#{gender} andentrydate between #{begin} and #{end} order by update_time desc</select>
</mapper>
②Mapper層
package com.itheima.mapper;import com.itheima.pojo.Emp;
import org.apache.ibatis.annotations.*;import java.time.LocalDate;
import java.util.List;@Mapper
public interface EmpMapper {public List<Emp> list(String name, Short gender, LocalDate begin,LocalDate end);}
③測(cè)試類
package com.itheima;import com.itheima.mapper.EmpMapper;
import com.itheima.pojo.Emp;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;import java.util.List;@SpringBootTest
class SpringbootMybatisCrudApplicationTests {@Autowiredprivate EmpMapper empMapper;@Testpublic void testList(){List<Emp> empList= empMapper.list("z",(short)1,LocalDate.of(2010,1,1),LocalDate.of(2020,1,1));System.out.println(empList);}
}
④思考
mapper映射文件還有一個(gè)好處,修改sql語(yǔ)句不用重啟項(xiàng)目
在方法上實(shí)現(xiàn)動(dòng)態(tài)的條件查詢就會(huì)使接口過(guò)于臃腫
如果操作語(yǔ)句多了,直接也在注解上面比較混亂
如果要做手動(dòng)映射封裝實(shí)體類的時(shí)候 xml方便,項(xiàng)目中會(huì)常用
用xml,因?yàn)椴樵兊臈l件會(huì)變化,直接寫在注解里面的話會(huì)使接口過(guò)于臃腫
這兩個(gè)各自找各自對(duì)應(yīng)的,原來(lái)是注解綁定,現(xiàn)在是通過(guò)路徑和方法名綁定
多條件查詢要寫動(dòng)態(tài)sql用映射文件比較合適,簡(jiǎn)單的可以直接注解方式
終于找到問(wèn)題了,xml里的sql語(yǔ)句不能拼接,只能是一長(zhǎng)條,運(yùn)行才不報(bào)錯(cuò)
執(zhí)行l(wèi)ist()方法時(shí),根據(jù)全限定類名找到對(duì)應(yīng)的namespace ,再找到id為這個(gè)方法的SQL語(yǔ)句就可以執(zhí)行了