springboot入门(项目)
springboot 第一天
- 第一步—— 創建springboot項目。
- **用戶-創建數據表**
- **創建實體類**:
- 配置application.properties
- 單元測試
- 附:
- pom.xml
- 設計接口與抽象方法
- UserMapper
- StoreApplication
- UserMapper.xml
- application.properties
- UserMapperTests測試類
- 規劃并創建異常類
- ServiceException
- UsernameDuplicateException
- InsertException
- UserServiceImpl
- 單元測試
- 附:
- 接口與抽象方法
- 附碼:
初次學習springboot所以第一步配置環境。因為不習慣用Idea,個人比較依賴eclipse。
最近eclipse無法配置springboot環境(可能個人問題或網絡問題。我本人在新疆)
用的軟件是【Spring Tool Suite 4】。界面跟eclipse一樣,相當于spring的eclipse版本。
個人是自學的,最近的到了一個達內學員的springboot學習日記和源碼。所以根據那個開始做了自己的測試項目。登錄注冊頁面是根據嗶哩嗶哩教程視頻自己創建的。源碼: 登錄注冊頁面-下載
資源:( springboot筆記含源碼…)
配置以下環境:
- jdk環境搭配
- Spring Tool Suite 4(eclipse)
- MySQL
eclipse 配置:(版本可以個人習慣自己選)
- Tomcat8.5
- maven 3.5.3
- MySQL 8.0.19
第一步—— 創建springboot項目。
我沒有選war。因為我認為jar比較好(但選war或jar)都可以的沒有太大關系
這依賴關系我也不太懂,所以模糊添加幾個重要因素
創建好了項目,第二部創建數據庫
用戶-創建數據表
創建數據庫:
CREATE DATABASE store;使用該數據庫:
USE store;再創建用戶數據表:
CREATE TABLE t_user (uid INT AUTO_INCREMENT COMMENT '用戶id',username VARCHAR(20) NOT NULL UNIQUE COMMENT '用戶名',password CHAR(32) NOT NULL COMMENT '密碼',salt CHAR(36) COMMENT '鹽值',gender INT COMMENT '性別:0-女,1-男',phone VARCHAR(20) COMMENT '電話號碼',email VARCHAR(30) COMMENT '電子郵箱',avatar VARCHAR(100) COMMENT '頭像',is_delete INT COMMENT '是否刪除:0-未刪除,1-已刪除',created_user VARCHAR(20) COMMENT '日志-創建人',created_time DATETIME COMMENT '日志-創建時間',modified_user VARCHAR(20) COMMENT '日志-最后修改執行人',modified_time DATETIME COMMENT '日志-最后修改時間',PRIMARY KEY (uid)) DEFAULT CHARSET=utf8mb4;創建實體類:
在cn.cyjt.shoot.entity里創建兩個實體類
- BaseEntity 有日志相關的4個屬性,所以,在創建實體類之前,應該先創建這些實體類的基類,將4個日志屬性聲明在基類中:- User entity.User用戶數據的實體類 /**實體類的基類BaseEntity */public class BaseEntity implements Serializable {private static final long serialVersionUID = 6613396591482385844L;private String createdUser;//創建改人private Date createdTime;//創建時間private String modifiedUser;//修改人private Date modifiedTime;//修改時間//get,set,string方法 public class User extends BaseEntity{/*** 用戶數據的實體類*/private static final long serialVersionUID = 3414303419311561404L;private Integer uid;private String username;private String password;private String salt;private Integer gender;private String phone;private String email;private String avatar;private Integer isDelete;//get,set,string方法配置application.properties
首先,需要在application.properties中配置連接數據庫的相關信息:
spring.datasource.url=jdbc:mysql://localhost:3306/shoot?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghaispring.datasource.username=rootspring.datasource.password=rootmybatis.mapper-locations=classpath:mappers/*.xml#解決返回亂碼問題#spring.http.encoding.charset=UTF-8#spring.http.encoding.force=true#spring.http.encoding.enabled=trueserver.servlet.encoding.charset=UTF-8server.servlet.encoding.force=trueserver.servlet.encoding.enabled=true單元測試
配置完成后,應該在src/test/java下的cn.cyjt.shoot.StoreApplicationTests類中編寫并執行“獲取數據庫連接”的單元測試:
@Autowiredpublic DataSource dataSource;@Testpublic void getConnection() throws SQLException {Connection conn = dataSource.getConnection();System.err.println("dataSource.getConnection() conn:::"+conn);}第一步,springboot連接數據庫測試完成了
附:
pom.xml
我的pom.xml文件:
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.3.4.RELEASE</version><relativePath /> <!-- lookup parent from repository --></parent><groupId>cn.cyjt</groupId><artifactId>shoot</artifactId><version>0.0.1-SNAPSHOT</version><name>shoot</name><description>Demo project for Spring Boot</description><properties><java.version>1.8</java.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-jdbc</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-jpa</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-jdbc</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>2.1.3</version></dependency><!-- mysql --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><scope>runtime</scope></dependency><!-- 數據庫連接池jar包坐標 --><dependency><groupId>commons-dbcp</groupId><artifactId>commons-dbcp</artifactId><version>1.4</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope><exclusions><exclusion><groupId>org.junit.vintage</groupId><artifactId>junit-vintage-engine</artifactId></exclusion></exclusions></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>設計接口與抽象方法
UserMapper
創建cn.cyjt.shoot.mapper.UserMapper接口,并在接口中添加抽象方法:
/*** 處理用戶數據的持久層接口*/public interface UserMapper {/*** 插入用戶數據* @param user 用戶數據* @return 受影響的行數*/Integer insert(User user);/*** 根據用戶名查詢用戶數據* @param username 用戶名* @return 匹配的用戶數據,如果沒有匹配的數據,則返回null*/User findByUsername(String username);}StoreApplication
由于這是第1次創建接口,還應該配置接口的位置,所以,需要在啟動類(StoreApplication)的聲明之前添加配置:
@SpringBootApplication @MapperScan("cn.cyjt.shoot.mapper")//由于這是第1次創建接口,還應該配置接口的位置,所以,需要在啟動類(StoreApplication)的聲明之前添加配置 public class ShootApplication {public static void main(String[] args) {SpringApplication.run(ShootApplication.class, args);}}UserMapper.xml
在src/main/resources下創建mappers文件夾,在該文件夾下粘貼得到UserMapper.xml文件,并進行配置:
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//ibatis.apache.org//DTD Mapper 3.0//EN" "http://ibatis.apache.org/dtd/ibatis-3-mapper.dtd"><mapper namespace="cn.cyjt.shoot.mapper.UserMapper"><resultMap id="UserEntityMap"type="cn.cyjt.shoot.entity.User"><id column="uid" property="uid" /><result column="is_delete" property="isDelete" /><result column="created_user" property="createdUser" /><result column="created_time" property="createdTime" /><result column="modified_user" property="modifiedUser" /><result column="modified_time" property="modifiedTime" /></resultMap><!-- 插入用戶數據 --><!-- Integer insert(User user) --><insert id="insert" useGeneratedKeys="true" keyProperty="uid">INSERTINTO t_user (username, password,salt, gender,phone, email,avatar, is_delete,created_user, created_time,modified_user, modified_time) VALUES (#{username}, #{password},#{salt}, #{gender},#{phone}, #{email},#{avatar}, #{isDelete},#{createdUser}, #{createdTime},#{modifiedUser}, #{modifiedTime})</insert><!-- 根據用戶id更新用戶密碼 --><!-- Integer updatePasswordByUid( @Param("uid") Integer uid, @Param("password") String password, @Param("modifiedUser") String modifiedUser, @Param("modifiedTime") Date modifiedTime) --><update id="updatePasswordByUid">UPDATEt_userSETpassword=#{password},modified_user=#{modifiedUser},modified_time=#{modifiedTime}WHEREuid=#{uid}</update><!-- 根據用戶id查詢用戶數據 --><!-- User findByUid(Integer uid) --><select id="findByUid" resultMap="UserEntityMap">SELECT*FROMt_userWHEREuid=#{uid}</select><!-- 根據用戶名查詢用戶數據 --><!-- User findByUsername(String username) --><select id="findByUsername" resultMap="UserEntityMap">SELECT*FROMt_userWHEREusername=#{username}</select></mapper>application.properties
由于是第1次使用,所以,需要在application.properties中配置XML文件的位置:
mybatis.mapper-locations=classpath:mappers/*.xmlUserMapperTests測試類
最后,在src/test/java下,創建cn.cyjt.shoot.mapper.UserMapperTests測試類,在測試類的聲明之前添加@RunWith(SpringRunner.class)和@SpringBootTest注解,并在測試類中聲明持久層對象,通過自動裝配來注入值:
@RunWith(SpringRunner.class)@SpringBootTestpublic class UserMapperTests {@AutowiredUserMapper userMapper;}然后,編寫2個測試方法,對以上完成的2個功能進行測試
@RunWith(SpringRunner.class)@SpringBootTestpublic class UserMapperTests {@Autowiredprivate UserMapper mapper;@Testpublic void insert() {User user = new User();user.setUsername("root");user.setPassword("1234");Integer rows = mapper.insert(user);System.err.println("rows=" + rows);}@Testpublic void findByUsername() {String username = "root";User user = mapper.findByUsername(username);System.err.println(user);}}規劃并創建異常類
ServiceException
凡操作失敗都應該拋出某種異常,為了便于管理自定義的異常,應該先創建這些異常的基類cn.cyjt.shoot.service.ex.ServiceException,繼承自RuntimeException。
package cn.cyjt.shoot.service.ex;public class ServiceException extends RuntimeException {private static final long serialVersionUID = -2879099986352308425L;public ServiceException() {super();}public ServiceException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {super(message, cause, enableSuppression, writableStackTrace);}public ServiceException(String message, Throwable cause) {super(message, cause);}public ServiceException(String message) {super(message);}public ServiceException(Throwable cause) {super(cause);} }UsernameDuplicateException
本次“注冊”之前,需要先檢查用戶名是否已經被占用,如果已經被占用,則需要拋出“用戶名被占用”的異常,則需要創建cn.cyjt.shoot.service.ex.UsernameDuplicateException異常類,繼承自ServiceException;
public class UsernameDuplicateException extends ServiceException {private static final long serialVersionUID = 3164055183124220212L;public UsernameDuplicateException() {super();}public UsernameDuplicateException(String message, Throwable cause, boolean enableSuppression,boolean writableStackTrace) {super(message, cause, enableSuppression, writableStackTrace);}public UsernameDuplicateException(String message, Throwable cause) {super(message, cause);}public UsernameDuplicateException(String message) {super(message);}public UsernameDuplicateException(Throwable cause) {super(cause);} }InsertException
在執行“注冊”時,需要向數據表中插入數據,則可能失敗,則需要創建cn.cyjt.shoot.service.ex.InsertException異常類,繼承自ServiceException。
public class InsertException extends ServiceException{/*** */private static final long serialVersionUID = 878421569126542322L;public InsertException() {super();}public InsertException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {super(message, cause, enableSuppression, writableStackTrace);}public InsertException(String message, Throwable cause) {super(message, cause);}public InsertException(String message) {super(message);}public InsertException(Throwable cause) {super(cause);} }UserServiceImpl
創建cn.cyjt.shoot.service.impl.UserServiceImpl業務層實現類,實現以上IUserService接口,在類的聲明之前添加@Service注解,并重寫接口中的抽象方法:
@Servicepublic abstract class UserServiceImpl implements IUserService{@Autowiredprivate UserMapper userMapper;@Overridepublic void reg(User user) {// 從參數user中獲取username// 根據username查詢用戶數據:User result = userMapper.findByUsername(username)// 判斷查詢結果是否不為null// 拋出異常:throw new UsernameDuplicateException();// 執行插入用戶數據,獲取返回值:Integer rows = userMapper.insert(user)// 判斷返回的受影響行數是否不為1// 拋出異常:throw new InsertException();// 從參數user中獲取usernameString username = user.getUsername();// 根據username查詢用戶數據:User result = userMapper.findByUsername(username)User result = userMapper.findByUsername(username);// 判斷查詢結果是否不為nullif (result != null) {// 拋出異常:throw new UsernameDuplicateException();throw new UsernameDuplicateException("嘗試注冊的用戶名(" + username + ")已經被占用");}// 補全數據-加密后的密碼、鹽值// 1. 生成鹽值String salt = UUID.randomUUID().toString().toUpperCase();// 2. 取出用戶提交的原始密碼String password = user.getPassword();// 3. 執行加密String md5Password = getMd5Password(password, salt);// 4. 將鹽值和加密后的密碼補全到user對象中user.setSalt(salt);user.setPassword(md5Password);// 補全數據-isDelete:0user.setIsDelete(0);// 補全數據-4項日志Date now = new Date();user.setCreatedUser(username);user.setCreatedTime(now);user.setModifiedUser(username);user.setModifiedTime(now);// 執行插入用戶數據,獲取返回值:Integer rows = userMapper.insert(user)Integer rows = userMapper.insert(user);// 判斷返回的受影響行數是否不為1if (rows != 1) {// 拋出異常:throw new InsertException();throw new InsertException("插入用戶數據時出現未知錯誤!請聯系系統管理員");}}單元測試
最后,創建cn.cyjt.shoot.service.UserServiceTests測試類,在類的聲明之前添加2個注解,在類中聲明業務層對象,編寫并執行單元測試:
@RunWith(SpringRunner.class)@SpringBootTestpublic class UserServiceTests {@AutowiredIUserService service;@Testpublic void reg() {try {User user = new User();user.setUsername("xxx");user.setPassword("xxx");service.reg(user);System.err.println("OK.");} catch (ServiceException e) {System.err.println(e.getClass());}}} 如果測試時,提示測試方法無法運行,可能因為:測試類不在根包中,測試類之前沒有添加2個注解,測試方法之前沒有@Test注解,測試方法的權限不是public,測試方法的返回值不是void,測試方法有參數。附:
CHAR與VARCHAR的區別
CHAR是定長的,即固定長度,VARCHAR是變長的,即長度可變。
無論是使用CHAR還是VARCHAR,都必須指定長度值。
假設使用20作為長度值,使用CHAR(20)時,如果存入的數據不足20字符,則MySQL會補足空格至20個字符,使用VARCHAR(20)時,以實際存入的字符為準!無論使用哪一種,不允許存入超出長度的字符!
在使用CHAR(20)時,占用的長度是固定的!使用VARCHAR(20)時,除了存入的字符占據的長度以外,默認情況下,MySQL還會另使用1個字節記錄實際字符長度!假設在VARCHAR(20)的字段中,存入"David",則MySQL會另使用1個字節記錄5這個值!由于1個字節可以表示的數字最大是255,如果實際存入的字符數量超過255,MySQL會自動擴為使用2個字節來記錄實際存入的字符數!(最多使用2個字節記錄)
*有不明白的地方可以評論留言或者聯系QQ2085345123 *
接口與抽象方法
應該為業務層設計接口,將需要實現的功能都聲明為接口中的抽象方法!
所以,需要先創建****.service.IUserService業務層接口,并在接口中聲明實現“注冊”功能的抽象方法。
業務接口中的抽象方法的設計原則:
返回值:僅以操作成功為前提來設計返回值類型;
方法名稱:與業務功能相關即可,例如“注冊”功能可以使用reg作為名稱,而“登錄”功能可以使用login作為名稱,一般,不推薦與持久層接口中的名稱完全相同;
參數列表:必須保證足以調用持久層中的方法,且這些參數都是控制器層可以獲取的(控制器中,數據的來源可能是用戶提交的);
所以,關于“注冊”功能的抽象方法可以是:
void reg(User user);// ---------- 關于登錄方法設計的示例 ----------User login(String username, String password) throws 異常1, 異常2;try {User user = service.login(xx, xx);// ... } catch (異常1 e) {// ... } catch (異常2 e) {// ... }附碼:
文章不太完整,但這源碼有注釋和數據庫10.20pm里。
若有價值,點個贊
總結
以上是生活随笔為你收集整理的springboot入门(项目)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Git ----fatal: unabl
- 下一篇: springboot设置UTF-8