springboot 入門教程(1 )-helloword前端
springboot 入門教程-Thymeleaf(2)java
springboot 入門教程(3)-運行原理、關鍵註解和配置mysql
springboot 入門教程(4)--web開發(spring mvc和Thymeleaf模板,帶源碼)jquery
若是沒看前面例子的同窗建議先看下,咱們這篇直接基於前面搭建的開發框架進行擴展。web
準備工做或知識儲備:maven、spring、spring mvc 、mybatis,jquery、Bootstrap、sql,druid鏈接池spring
上一篇咱們已經完成了基於Thymeleaf模板的整合,爲了下降門檻,咱們這個ssm的demo前端使用Bootstrap+jquery+BootStrap Table來實現。(BootStrap Table和VUE.js有點像,理解和學習起來相對容易,從開始接觸到使用到實際項目也就半天時間,官方文檔和demo都比較完善,雖然是英文,直接照葫蘆畫瓢就行)sql
後臺源碼(有小bug):springBoot+mybatis實現CRUD源碼 完整源碼:springBoot+mybatis實現CRUD源碼-完整版 數據庫
=========================華麗分割線==============================apache
先說步驟json
注:本篇不對單個框架進行深刻介紹,若是點贊關注多我再補充單個框架更詳細的系列教程。
一、引入須要的jar包(mysql驅動、mybatis)
二、建庫建表
三、編寫實體bean
四、整合spring+mybatis(dao、servcei層)
五、使用spring mvc提供rest服務(controller)
六、前端框架整合調用rest服務
接下來開始擼代碼吧
有坑(spring-tx必須引用,要不找不到DaoSurport)
<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 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.pxk.springboot</groupId> <artifactId>SpringBootDemo</artifactId> <version>0.0.1-SNAPSHOT</version> <build> <sourceDirectory>src</sourceDirectory> <plugins> <plugin> <artifactId>maven-compiler-plugin</artifactId> <version>3.3</version> <configuration> <source>1.8</source> <target>1.8</target> </configuration> </plugin> </plugins> </build> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.6.RELEASE</version> <relativePath /> </parent> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <!-- web容器 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <version>1.5.6.RELEASE</version> </dependency> <!-- 須要單獨引用否則會報 java.lang.NoClassDefFoundError: org/springframework/dao/support/DaoSupport --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-tx</artifactId> <version>4.3.10.RELEASE</version> </dependency> <!-- spring jdbc支持, 不引用會報相似,具體類可能不一樣NoClassDefFoundError: org/springframework/jdbc/datasource/TransactionAwareDataSour --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>4.3.10.RELEASE</version> </dependency> <!-- mybatis --> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.4.0</version> </dependency> <!-- mybatis-spring --> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>1.3.0</version> </dependency> <!-- mysql驅動 --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.40</version> </dependency> <!--日誌 --> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.17</version> </dependency> <!-- druid鏈接池 --> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.0.18</version> </dependency> </dependencies> </project>
數據使用的是myql5.5,客戶端工具是Navicat 8(i表結構會包含在源碼中)
一張普通的用戶表,id採用數據庫自增加,隨便補充十條數據
get、set方法就不貼出來了,省得浪費篇幅
有個坑哦(構造函數必須有)
package com.pxk.springboot.domain; import java.util.Date; import com.fasterxml.jackson.annotation.JsonFormat; public class User { private Integer id; private String name; private Integer age; private String passWord; private char gender; //json日期格式化 @JsonFormat(pattern="yyyy-MM-dd HH:mm:ss",timezone = "GMT+8") private Date regestDate; //默認構造函數不能少 ,若是沒有會報ibatis.executor.ExecutorException: No constructor found public User() { super(); }
首先介紹下mybatis,用過的同窗應該都知道它是一個半自動的ORM框架,比Hibernate更靈活,可是開發效率沒有Hibernate高,不過如今有不少開源的插件封裝了crud操做,效率也還能夠,目前開源中國比較熱的是mybatis-plus,我也用過基本能知足需求,就是源代碼沒註釋,文檔少,遇到坑的時候就就比較浪費時間去理源碼。
本文主要是在spring+mybatis的基礎上使用springboot的整合方式而已,如搭建過常規spring+mybatis框架的就很好理解。
這部分也是本文的核心,首先咱們要編寫mapper、而後定義接口,spring會自動調用接口對應的mapper中的方法(實現原理就是使用的反射--框架開發利器)
新建UserMapper接口(若是使用自動掃描接口名必須和xml的mapper文件名對應)
package com.pxk.springboot.dao; import java.util.List; import org.apache.ibatis.annotations.Param; import com.pxk.springboot.domain.User; public interface UserMapper { List<User> findUserByPage(@Param("startIndex")int startIndex ,@Param("pageSize")int pageSize); User getUserById(int id); int updateUser(User user); int deleteUser(User user); int addUser(User user); }
這部分就是mybatis中的內容了,沒有用到什麼高級的特性,只是普通的單表操做,sql不嚴謹沒必要糾結哈(動態sql,resultMap關聯等都沒用)
爲了能讓spring經過接口調用咱們的mapper中的sql語句,咱們必須讓spring將mapper和接口對應上,那咱們在調用接口的時候,spring才知道去找哪一個mapper中的那個sql啊。首先,保證mapper的文件名和接口名要一致,不然是匹配不上的(固然咱們若是採用配置文件的方式是能夠配置對應關係的,但這又和咱們使用SpringBoot的零配置思想背離了,因此我仍是認爲約定優於配置)。其次,採用java配置,讓Spring掃描mapper文件,我知道的至少有三種方式我這裏就隨便選了一種(注意:直接在springBootApplication上配置mapperScan後期打包部署的時候會有jar包掃描不到的問題,我跳的過坑,建議你們像我同樣用別去採坑了,浪費了我一個下午的時間,開發環境能啓動,打包後就不行了,這是mybaitis的一個bug,不知道後來修復沒有)。我採用的是新建一個configration類的方式進行配置,詳見下面代碼:MyBatisConfig .java
UserMapper.xml(所在目錄SpringBootDemo/src/main/resources/com/pxk/springboot/dao,這目錄就是要被掃描的)
<?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.pxk.springboot.dao.UserMapper"> <!-- 使用別名的目的是讓查詢結果屬性名稱和實體bean的屬性名對應,要不讓綁定不上數據。要麼就寫resultMap這個你們本身搞了 --> <select id="findUserByPage" resultType="User"> select name,age,gender,pass_word passWord,regest_date regestDate from user limit #{startIndex},#{pageSize}; </select> <insert id="addUser" parameterType="User"> insert into User <trim prefix="(" suffix=")" suffixOverrides=","> <if test="name != null and name!=''"> name, </if> <if test="gender != null and gender!=''"> gender, </if> <if test="password != null and password!=''"> pass_word, </if> <if test="regestDate != null"> regest_date, </if> </trim> <trim prefix="values (" suffix=")" suffixOverrides=","> <if test="name != null and name!=''"> #{name,jdbcType=VARCHAR}, </if> <if test="gender != null and gender!=''"> #{gender,jdbcType=CHAR}, </if> <if test="password != null and password''"> #{pass_word,jdbcType=VARCHAR}, </if> <if test="regestDate != null "> #{regest_date,jdbcType=Date}, </if> </trim> </insert> <select id="getUserById" parameterType="int" resultType="User"> select * from user where id=#{id} </select> <delete id="deleteUser" parameterType="User"> delete from user where id=#{id} </delete> </mapper>
MyBatisConfig .java
package com.pxk.springboot.config; import org.mybatis.spring.mapper.MapperScannerConfigurer; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; /** * mybatis 配置文件 * @author Administrator * */ @Configuration public class MyBatisConfig { @Bean public MapperScannerConfigurer mapperScannerConfigurer() { MapperScannerConfigurer mapperScannerConfigurer = new MapperScannerConfigurer(); //指定掃描的mapper.xml文件所在目錄 mapperScannerConfigurer.setBasePackage("com.pxk.springboot.dao"); return mapperScannerConfigurer; } }
爲何配置實體類呢,由於spring經過反射調用接口之後要知道你返回的結果是什麼類型啊,這些實體也須要託管到spring容器他纔會給你封裝好啊,因此咱們仍是得像spring+mybatis同樣配置TypeAliases,只是配置方式不一樣而已。那麼採用springBoot集成該怎麼作能,只須要在APPlication中覆蓋默認配置sqlSessionFactory的方法,指定實體類所在路徑便可,springBoot內部也是經過掃描的方式去加載的。具體代碼以下:
Application.java
package com.pxk.springboot; import javax.sql.DataSource; import org.apache.ibatis.session.SqlSessionFactory; import org.apache.log4j.lf5.util.Resource; import org.mybatis.spring.SqlSessionFactoryBean; import org.mybatis.spring.annotation.MapperScan; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Bean; import com.alibaba.druid.pool.DruidDataSource; @SpringBootApplication //@MapperScan(basePackages = { "com.pxk.springboot.dao" })//這種掃描會有bug哦 public class Application { private final static Logger log=LoggerFactory.getLogger(Application.class); @Bean @ConfigurationProperties(prefix = "spring.datasource") //覆蓋默認數據源 使用druid數據源 public DataSource dataSource() { return new DruidDataSource(); } @Bean public SqlSessionFactory sqlSessionFactory() { try { SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean(); sessionFactory.setDataSource(dataSource()); //掃描實體類所在包 sessionFactory.setTypeAliasesPackage("com.pxk.springboot.domain"); return sessionFactory.getObject(); } catch (Exception e) { return null; } } public static void main(String[] args) { SpringApplication.run(Application.class, args); log.info("啓動成功"); } }
service層比較簡單就是依賴注入之後調用沒有任何業務邏輯,直接上代碼
UserServiceImpl.java
package com.pxk.springboot.serivce.imp; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.pxk.springboot.dao.UserMapper; import com.pxk.springboot.domain.User; import com.pxk.springboot.serivce.UserService; @Service//注入成service public class UserServiceImpl implements UserService { @Autowired private UserMapper userMapper; @Override public User getUser(String name) { return new User(name); } @Override public List<User> findUserByPage(int pageSize, int pageNum) { return userMapper.findUserByPage((pageNum-1)*pageSize, pageSize); } @Override public User getUserById(int id) { return userMapper.getUserById(id); } @Override public int updateUser(User user) { return userMapper.updateUser(user); } @Override public int deleteUser(User user) { return userMapper.deleteUser(user); } @Override public int addUser(User user) { return userMapper.addUser(user); } }
也沒什麼特殊的,直接上代碼(你們有點spring mvc基礎就能看懂的)
UserController.java(代碼片斷,先作個測試)
@RequestMapping("/findUserByPage") @ResponseBody//返回json格式數據 protected List<User> findUserByPage(int pageSize,int pageNum){ return userService.findUserByPage(pageSize, pageNum); }
運行程序,輸入http://localhost:8081/user/findUserByPage?pageSize=5&pageNum=1測試controller的findUserByPage方法,結果以下