第1集 SpringBoot一天速成 (SpringBoot)

說明:SpringBoot一天速成不是口號,而在於您的基礎。
1.此演示目的就是爲了讓大家速成。口號:“快快快狠”。
2.具備半年以上"SSM框架+Maven"實戰經驗的開發人員
3.跟着此係列博文《SpringBoot一天速成》練習一遍
4.這套演練包括工程的:持久層、服務層、web層,採用Intellej idea工具。
5.所有源碼和資料免費提供給讀者,需要的留言。
6.筆者將實踐過程中遇到的問題與大家分享,讓大家少走彎路。(請閱讀註釋部分)

SpringBoot是幹嘛的?"簡化開發,獨立運行",瞄準的目標:微服務。下面是官方原話:
	  Spring Boot makes it easy to create stand-alone, production-grade Spring based 
Applications that you can "just run". We take an opinionated view of 
the Spring platform and third-party libraries so you can get started with minimum fuss. 
Most Spring Boot applications need very little Spring configuration.

====>>> 持久層–>服務層 演練開始……
採用逆向工程的方式來演示《SpringBoot一天速成演練》,先從數據庫開始最後到web層
聲明:@author:拈花爲何不一笑,“這是一套演練對於細節方面,需要讀者自己完善。”

 1.準備Intellij idea工具(此工具集成了Spring Initializr比eclipse更高效,缺點是佔用大量內存接近900M)
		1.1 下載ideaIU-2018.2.6.exe
		1.2 破解方法(此工具是收費的,若果是學習用可以使用破解版,企業用建議購買)
		這些資源,有需要的筆者都可以提供,請留言。

在這裏插入圖片描述

 2.Intellij Idea工具中創建工程
	File菜單--> New -->Project-->彈出對話框:選擇Spring Initializr(用來初始化構建工程的環境),
	接下來的操作看圖,更清楚,如下:

在這裏插入圖片描述

在這裏插入圖片描述

在這裏插入圖片描述

 3.在Mysql(版本:MySQL-5.5.61)中創建數據庫和建表等
	sql腳本:createTable.sql,有需要的筆者可以分享出來...
	3.1 數據庫名稱;testsb2mybatis
	3.2 表兩張:dept和emp
			截一張表結構圖,如下:

|在這裏插入圖片描述

4.編寫Mapper接口和相關配置文件
	4.1.在resources目錄下創建以下目錄結構,如圖:

在這裏插入圖片描述

	4.2.創建mybatis配置文件mybatis.xml和EmpMapper.xml文件(注意存放位置)

====>>> mybatis.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>
    <!-- mybatis中加載的數據源datasource,由於與springboot進行整合,那麼數據源交由Spring來管理,則配置在application.properties文件中了-->

    <!-- 配置 mybatis sql日誌輸出 STDOUT_LOGGING
        <settings>
            <setting name="logImpl" value="SLF4J" />
        </settings>
    -->
</configuration>

====>>> EmpMapper.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">
<!-- namespace指向mapper包中的相應的接口,這是Mybatis-Mapper方式的規則之一 -->
<mapper namespace="org.it.springboot4.mapper.EmpMapper">

<sql id="empfields">
    empno,ename,job,mgr,hiredate,sal,comm,deptno
</sql>

<!-- id與mapper接口方法名相同,resultType與mapper接口的方法的返回類型相同,這是Mybatis-Mapper方式的規則之二 -->
<!-- parameterType相當於itatis中的parameterClass,
	若參數爲基本數據類型,佔位符(#{參數名})可以是任意參數名;
	若參數爲java對象,如User那麼佔位符中的參數名,取名要與User中的屬性對應,因爲通過getXXX從User中取值的 -->
<select id="findEmpById"  parameterType="java.lang.Integer" resultType="org.it.springboot4.entity.Emp">
    select
      <include refid="empfields"/>
     from emp where empno = #{拈花爲何不一笑}
</select>

<!-- 模糊查詢拼接符 '%${}%',基本數據類型的模糊查詢拼接符只能使用'%${value}%',
	            不能這樣'%${username}%',防止拼接注入'%${username}% or 1=1' -->

<!-- 查詢研發部所有薪資大於或等於6600的員工,返回類型resultType直接映射成Map
    注意返回類型不是resultMap。
    1.resultType表示基本數據類型和包裝類及自定義類,還有這裏的java.util.Map接口下的實現類,
    若在此處誤用resultMap是會因Map無法映射,而拋出異常:
        java.lang.IllegalArgumentException: Result Maps collection does not contain value for java.util.Map
    2.默認使用的是HashMap來實現Map,採用的是hash值對鍵進行排序,映射的數據順序就有點亂,
        可以直接指定LinkedHashMap來排序按插入(sql查詢字段的順序)排序特性並去重複的字段(如這裏的deptno,排在前面的保留)
    3.resultMap通常用於查詢出多表關聯數據與java類與類之間的關聯關係進行映射,即通常所說的的一對多,多對多這類的映射關係。
-->
<select id="findEmpByDeptnoSal" parameterType="org.it.springboot4.entity.custom.EmpCustom" resultType="java.util.LinkedHashMap">
    SELECT
        e.empno,
        e.ename,
        e.hiredate,
        e.job,
        e.mgr,
        e.sal,
        e.deptno,
        e.comm,

        d.deptno,
        d.dname,
        d.location
    FROM emp e, dept d
    WHERE e.deptno = d.deptno
    <!-- mybatis動態sql,根據參數有無來動態添加查詢條件,如果是Map作爲查詢條件的參數,則在if test中直接使用key名判斷即可-->
   <if test="dname != null and dname !=''">
       AND d.dname = #{dname}
   </if>
    <if test="sal != null and sal !=''">
        AND sal &gt;= #{sal}
    </if>
</select>

<!-- 添加一個新員工,無需顯示指明返回類型,mybatis自動把影響到的記錄數據作爲Integer返回 -->
<insert id="createEmp" parameterType="org.it.springboot4.entity.Emp" >
    insert  into emp(ename,hiredate,job,mgr,sal,comm,deptno)
    values (#{ename},#{hiredate},#{job},#{mgr},#{sal},#{comm},#{deptno})
</insert>

<!-- 創建並映射當前新增加的員工編號(返回的還是影響的記錄數) -->
<!-- 通過mysql數據庫提供的函數last_insert_id(),獲取由數據庫mysql自動生成的主鍵並映射到Emp的empno屬性中 -->
<!-- 注意:1.返回的是一個整數不能是Emp對象 2.selectKey 中的order屬性值必須大寫AFTER 3.如果使用resultType會報一個坑人的異常提示:
	必須爲元素類型 "insert" 聲明屬性 "resultType"。 -->
<insert id="createGetEmp"  parameterType="org.it.springboot4.entity.Emp">
    <selectKey keyColumn="empno" keyProperty="empno" order="AFTER" resultType="java.lang.Integer">
        SELECT LAST_INSERT_ID()
    </selectKey>
    insert  into emp(ename,hiredate,job,mgr,sal,comm,deptno)
    values (#{ename},#{hiredate},#{job},#{mgr},#{sal},#{comm},#{deptno})

</insert>

<!-- 刪除員工,使用Map接收刪除條件,其中currentEmpno爲Map設置的鍵名 -->
<delete id="deleteEmp" parameterType="java.util.Map">
    delete from emp where empno = #{currentEmpno}
</delete>

<!-- 更新員工,這裏使用if標籤構建動態sql,防止空數據覆蓋表中字段數據。其中set標籤可以去最後面一個字段的逗號防止sql語法錯誤 -->
<update id="updateEmp" parameterType="org.it.springboot4.entity.Emp">
    update emp
    <set>
       <if test="ename != null and ename !=''">
            ename = #{ename},
        </if>

        <if test="hiredate != null and hiredate !=''">
             hiredate = #{hiredate},
        </if>

        <if test="job != null and job !=''">
            job = #{job},
        </if>
        <if test="mgr != null and mgr !=''">
            mgr = #{mgr},
        </if>
        <if test="sal != null and sal !=''" >
            sal = #{sal},
        </if>
        <if test="comm != null and comm !=''" >
            comm = #{comm},
        </if>
        <if test="deptno != null and deptno !=''" >
            deptno = #{deptno},
        </if>
    </set>
      where empno =#{empno}
        <if test="deptno != null and deptno !=''">
            and deptno = #{deptno}
        </if>
        <if test="mgr != null and mgr !=''">
            and mgr = #{mgr}
        </if>

</update>

</mapper>

繼續…

4.3.創建實體類:Dept.java和Emp.java 及EmpCustom(擴展Emp,用於包裝前端參數)

====>>> Dept .java

package org.it.springboot4.entity;
public class Dept {


private Integer deptno;

private String dname;

private String location;

public Dept() {//無參構造函數
}

public Integer getDeptno() {
    return deptno;
}

public void setDeptno(Integer deptno) {
    this.deptno = deptno;
}

public String getDname() {
    return dname;
}

public void setDname(String dname) {
    this.dname = dname;
}

public String getLocation() {
    return location;
}

public void setLocation(String location) {
    this.location = location;
}
}

====>>> Emp.java

package org.it.springboot4.entity;

import java.util.Date;


public class Emp {
private Integer empno;

private String ename;
private String job;
private Integer mgr;
private Date hiredate;
private Float sal;
private Float comm;

private Integer deptno;

public Emp() {
}

public Integer getEmpno() {
    return empno;
}

public void setEmpno(Integer empno) {
    this.empno = empno;
}

public String getEname() {
    return ename;
}

public void setEname(String ename) {
    this.ename = ename;
}

public String getJob() {
    return job;
}

public void setJob(String job) {
    this.job = job;
}

public Integer getMgr() {
    return mgr;
}

public void setMgr(Integer mgr) {
    this.mgr = mgr;
}

public Date getHiredate() {
    return hiredate;
}

public void setHiredate(Date hiredate) {
    this.hiredate = hiredate;
}

public Float getSal() {
    return sal;
}

public void setSal(Float sal) {
    this.sal = sal;
}

public Float getComm() {
    return comm;
}

public void setComm(Float comm) {
    this.comm = comm;
}

public Integer getDeptno() {
    return deptno;
}

public void setDeptno(Integer deptno) {
    this.deptno = deptno;
}
}

====>>> EmpCustom.java

package org.it.springboot4.entity.custom;

import org.it.springboot4.entity.Emp;

/**
 * 自定義Emp擴展類,用於Emp屬性的擴展
 */
public class EmpCustom extends Emp {

    private String dname;

    public String getDname() {
        return dname;
    }

    public void setDname(String dname) {
        this.dname = dname;
    }
}

繼續…

	4.4.這裏採用Mybatis-Mapper接口的開發方式,使用Mybatis。
	(還有一種方式是向下兼容itatis,推薦Mybatis-Mapper)
	  編寫EmpMapper接口,這裏有一定的規則,要與EmpMapper.xml中的配置相對應,裏面有註釋說明。

====>>> EmpMapper.java(看清楚了,這個後綴是java)

package org.it.springboot4.mapper;

import org.it.springboot4.entity.Emp;
import org.it.springboot4.entity.custom.EmpCustom;

import java.util.List;
import java.util.Map;

/**
 * mapper包相當於dao層包
 *  這裏演示Mybatis-Mapper方式使用mybatis
 *      這個接口中的方法是需要遵守一定的規範的
 *  springboot自動掃描會掃描mapper包(未與sprngboot整合時,包的掃描是由mybatis來掃描的且mapper映射文件與java mapper接口放在同一個包中)
 */
public interface EmpMapper {

    //查詢員工根據員工編號(按實際開發過程中,service層方法是要求拋出異常的,這裏簡單演示就省略了)
    Emp findEmpById(Integer empno);

    // 查詢研發部所有薪資大於或等於6600的員工(也可以使用Map作爲參數,mapper.xml中取參數值方式#{map設置的key名})
    List<Map> findEmpByDeptnoSal(EmpCustom empCustom);

    //增加一個員工並返回影響的記錄數
    Integer createEmp(Emp emp);

    //創建並映射當前新增加的員工編號(返回的還是影響的記錄數)
    Integer createGetEmp(Emp emp);

    //刪除員工
    Integer deleteEmp(Map paramMap);

    //更新員工
    Integer updateEmp(Emp emp);
}

繼續

	4.5.創建application.properties配置文件,springboot入口類啓動時會加載此配置文件
		此配置在這裏,筆者將其分成三塊:a.基礎配置信息 b.數據源配置 c.ybatis配置
	  配置文件內容,如下:

====>>> application.properties

##########基礎配置信息 ##########
#debug=ture
#server.servlet.context-path=/myspringboot4
server.port=8080
spring.http.encoding.charset=UTF-8
spring.jackson.time-zone=GMT+8
spring.jackson.date-format=yyyy-MM-dd HH:mm:ss SSS
spring.mvc.date-format=yyyy-MM-dd
#json縮進排版
spring.jackson.serialization.indent-output=true
##########數據源配置##########
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
#這裏有個時區問題,需要注意,GMT+8 ,其中%2B表示"+"
spring.datasource.url=jdbc:mysql://localhost:3306/testsb2mybatis?useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2B8
spring.datasource.username=root
spring.datasource.password=root
#spring.jpa.show-sql=true
######mybatis配置 ######
mybatis.config-location=classpath:/mybatis/mybatis.xml
mybatis.mapper-locations=classpath:/mybatis/mapper/*.xml

繼續

5.編寫服務層,調用持久層接口(Mapper接口,比如EmpMapper.java)

	
	5.1 創建EmpService接口,源碼如下:

====>>> EmpService.java

package org.it.springboot4.service;

import org.it.springboot4.entity.Emp;
import org.it.springboot4.entity.custom.EmpCustom;

import java.util.List;
import java.util.Map;

public interface EmpService {
    
Emp getEmpById(Integer empno);

List<Map> getEmpByDeptnoSal(EmpCustom empCustom);

Integer insertEmp(Emp emp);

Integer insertGetEmp(Emp emp);

Integer deleteEmp(Map paramMap);

Integer updateEmp(Emp emp);
}

繼續

5.2 創建EmpService接口的實現類EmpServiceImpl並且通過註解開啓事務和進行事務控制
(不需要像以前一樣再去配置Spring的事務配置文件了,只需要這個註解就OK,是不是方便了許多),源碼如下(下面的事務簡述很重要,記得要看):

====>>> EmpServiceImpl.java

package org.it.springboot4.service;

import org.it.springboot4.entity.Emp;
import org.it.springboot4.entity.custom.EmpCustom;
import org.it.springboot4.mapper.EmpMapper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;

@Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRED,isolation = Isolation.DEFAULT)
@Service
public class EmpServiceImpl implements EmpService{

@Resource//注入EmpMapper實現類(mybatis默認使用Cglib動態代理生成的EmpMapper接口的實現類)
private EmpMapper empMapper;

@Transactional(readOnly=true)
public Emp getEmpById(Integer empno) {
    Emp emp = this.empMapper.findEmpById(empno);
    return emp;

}

//查詢研發部中薪資大於或等於6600的員工
@Override
public List<Map> getEmpByDeptnoSal(EmpCustom empCustom) {
    List<Map>  maps =  this.empMapper.findEmpByDeptnoSal(empCustom);
    return maps;
}

//添加一個新入職的員工
@Override
public Integer insertEmp(Emp emp) {
    //影響的表中記錄的條數,默認爲0
    Integer num = 0;
    num = this.empMapper.createEmp(emp);
    return num;
}

// 創建並映射當前新增加的員工編號(返回的還是影響的記錄數)
public Integer insertGetEmp(Emp emp) {
    Integer iInsert = 0;
    iInsert = this.empMapper.createGetEmp(emp);
    return iInsert;
}

//刪除員工
@Override
public Integer deleteEmp(Map paramMap) {
    Integer iDel = 0;
    iDel = this.empMapper.deleteEmp(paramMap);
    return iDel;
}


//更新員工
@Override
public Integer updateEmp(Emp emp) {
    Integer iUpdate = 0;
    iUpdate = this.empMapper.updateEmp(emp);
    return iUpdate;
}

}

繼續

		在這裏進行事務簡述,@Transactional的常用方法(什麼ACID概念的就不說了):
		 先來看看這個註解,
		@Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRED,isolation = Isolation.DEFAULT)
		說明:
		a.只讀:readOnly() ,通常用於在查詢方法上@Transactional(readOnly=true),是可以提高
		   		效率的,默認爲false
		
		b.事務的傳播特性:propagation(),說的直白一點"就是方法在調用的時候是開啓一個新事
			務,還是使用原來的事務這一類的操作"
			感覺有點朦朧?這個東西在分佈式數據源中就會發揮出明顯的威力。
			記得在EJB JPA中若果不開啓事務,對於修改一類的操作是不成功的。但是在SSM中沒有這個要求。
		
		c.事務的隔離級別:isolation(),這個東西是來幹嘛的?
			若果你拿它來與線程中的概念進行對比,它就類似於java多線程和併發操作時DB所
			採取的策略。	這個東西,好像需要DB來支持的,不能隨意指定隔離級別,你得查看
			你的DB所支持哪些隔離級別。
		
		d.指定的異常及子異常進行事務回滾:rollbackFor(),
		 這個東西筆者常聽人說,"哎呀,我這個業務操作失敗了怎麼部分數據還保存到DB中了"
		若果你指定是的RuntimeException.class像java.text.ParseException是回滾不了的,
		因爲它不是RuntimeException的子類。

6.編寫Web層(Controller+視圖層)
請看博文"第2集 SpringBoot一天速成",地址:https://blog.csdn.net/Netaa001/article/details/84722496

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章