1、什么是dubbo?
(1)dubbo是阿里开发,贡献给apache项目基金会
(2)dubbo是高性能的,轻量级的java开发开源的RPC框架(远程调用 remote preducer call)
(3)dubbo提供了三大核心:
①面向接口的风格
②容错和负载均衡
③自动的注册服务和服务发现
(4)面向接口的风格
①restful是controller调用controller
②dubbo是controllerservice(只需定义接口,不要实现)
(5)容错
在项目运行中即使出现错误,也可以继续的方案,就是容错
(6)自动的注册服务和服务发现
使用到了zookeeper注册中心,使用zookeeper来实现自动的注册服务和发现
2.为什么要用dubbo?
(1)因为项目之间需要相互调用,达到某种预期的效果
eg:门户网站必须知道用户的登录状态,但是用户的登录状态在登录项目中,所以门户网站必须要请求登陆项目来获取用户的登录状态,使用的restful
restful需要把用户的登录状态暴露在http中,一旦被截获,导致整个项目运行出故障,除非http做的非常安全
restful并不符合MVC的思想:
MVC:controller-->service-->mapper-->model
restful:controller-->controller
3.dubbo图解
4.代码部分
实现增删改查(ajax)
两个项目分别是provider(实现service)和consumer(实现controller)
provider:
(1)所依赖的jar包:
<!--springboot的jar--> <!--springboot-web-starter--> <!--springboot-mybatis整合包--> <!--mysql驱动包--> <!--druid(连接池)--> <!--dubbo和spring的整合包--> <!--zookeeper的服务器端包(zkServer)--> <!--zookeeper的客户端包(zkClient)--> <!--netty(封装了io流的框架)--> <!--IO流是创始于jdk1.4版本--> <!--NIO是在jdk的1.5版本诞生--> <!--netty最终整合了NIO,对NIO做很好的封装--> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.10.RELEASE</version> </parent> <dependencies> <!-- springboot-starter-web --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- dubbo-spring-boot-starter --> <dependency> <groupId>com.alibaba.spring.boot</groupId> <artifactId>dubbo-spring-boot-starter</artifactId> <version>2.0.0</version> </dependency> <!-- netty start --> <dependency> <groupId>org.jboss.netty</groupId> <artifactId>netty</artifactId> <version>3.2.6.Final</version> </dependency> <!-- netty end --> <dependency> <groupId>org.apache.zookeeper</groupId> <artifactId>zookeeper</artifactId> <version>3.4.6</version> </dependency> <dependency> <groupId>com.github.sgroschupf</groupId> <artifactId>zkclient</artifactId> <version>0.1</version> </dependency> <!-- springboot-mybatis整合包 --> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>1.3.0</version> </dependency> <!-- mysql的驱动包 --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.38</version> </dependency> <!-- druid连接池 --> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.1.10</version> </dependency> </dependencies>
(2)整体目录
(3)application.properties配置
servcer.port=8081 server.context-path=/ spring.datasource.driver-class-name=com.mysql.jdbc.Driver spring.datasource.url=jdbc:mysql://localhost:3306/zk?useSSL=false spring.datasource.username=root spring.datasource.password=995812 spring.datasource.type=com.alibaba.druid.pool.DruidDataSource mybatis.type-aliases-package=com.aaa.zk.dubbo.model mybatis.mapper-locations=classpath:mapper/*Mapper.xml #dubbo的配置 #配置dubbo的应用名(在dubbo的admin项目,可以非常直观的看出是什么项目) #dubbo-admin-->生产者/消费者 -->application.name需要根据当前项目进行命名 dubbo.application.name=user-provider #protocol:协议 #配置该项目远程调用的时候所使用的协议-->dubbo(tcp,udp) dubbo.prorocol.name=dubbo #配置dubbo端口 dubbo.protocol.port=20881 #zookeeper的通信地址 dubbo.registry.address=zookeeper://192.168.21.135:2181 # provider项目必须要让zookeeper知道具体是哪一个类/哪一些类需要注册进zookeeper中 dubbo.scan.base-packages=com.aaa.zk.dubbo.service.impl
(4)实体类
package com.aaa.zk.dubbo.model; import java.io.Serializable; public class Book implements Serializable { private Integer id; private String bookName; private Double bookPrice; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getBookName() { return bookName; } public void setBookName(String bookName) { this.bookName = bookName == null ? null : bookName.trim(); } public Double getBookPrice() { return bookPrice; } public void setBookPrice(Double bookPrice) { this.bookPrice = bookPrice; } }
(5)mapper
package com.aaa.zk.dubbo.mapper; import com.aaa.zk.dubbo.model.Book; import org.apache.ibatis.annotations.Mapper; import java.util.List; @Mapper public interface BookMapper { int deleteByPrimaryKey(Integer id); int insert(Book record); int insertSelective(Book record); Book selectByPrimaryKey(Integer id); int updateByPrimaryKeySelective(Book record); int updateByPrimaryKey(Book record); List<Book> selectAll(); }
(6)service及impl
package com.aaa.zk.dubbo.service; import com.aaa.zk.dubbo.model.Book; import java.util.Map; public interface BookService { Map<String,Object> selectAll(); Map<String,Object> insert(Book record); Map<String,Object> delete(Integer id); Map<String,Object> update(Book record); Map<String,Object> selectById(Integer id); }
package com.aaa.zk.dubbo.service.impl; import com.aaa.zk.dubbo.mapper.BookMapper; import com.aaa.zk.dubbo.model.Book; import com.aaa.zk.dubbo.service.BookService; import com.alibaba.dubbo.config.annotation.Service; import org.springframework.beans.factory.annotation.Autowired; import java.util.HashMap; import java.util.List; import java.util.Map; @Service(timeout = 5000) public class BookServiceImpl implements BookService { @Autowired private BookMapper bookMapper; private Map<String,Object> resultMap=new HashMap<String, Object>(); @Override public Map<String, Object> selectAll() { List<Book> bookList= bookMapper.selectAll(); if (bookList.size()>0){ resultMap.put("code",200); resultMap.put("result",bookList); }else { resultMap.put("code",404); } return resultMap; } @Override public Map<String, Object> insert(Book record) { int i=bookMapper.insert(record); if (i>0){ resultMap.put("code",200); }else { resultMap.put("code",404); } return resultMap; } @Override public Map<String, Object> delete(Integer id) { int i=bookMapper.deleteByPrimaryKey(id); if (i>0){ resultMap.put("code",200); }else { resultMap.put("code",404); } return resultMap; } @Override public Map<String, Object> update(Book record) { int i=bookMapper.updateByPrimaryKeySelective(record); if (i>0){ resultMap.put("code",200); }else { resultMap.put("code",404); } return resultMap; } @Override public Map<String, Object> selectById(Integer id) { Book book=bookMapper.selectByPrimaryKey(id); if (book!=null){ resultMap.put("code",200); resultMap.put("result",book); }else { resultMap.put("code",404); } return resultMap; } }
(7)启动项
package com.aaa.zk.dubbo; import com.alibaba.dubbo.config.spring.context.annotation.EnableDubbo; import org.mybatis.spring.annotation.MapperScan; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication @MapperScan("com.aaa.zk.dubbo.mapper") @EnableDubbo public class ApplicationRun8081 { public static void main(String[] args) { SpringApplication.run(ApplicationRun8081.class, args); } }
(8)sql
<?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.aaa.zk.dubbo.mapper.BookMapper"> <resultMap id="BaseResultMap" type="com.aaa.zk.dubbo.model.Book"> <id column="id" jdbcType="INTEGER" property="id" /> <result column="book_name" jdbcType="VARCHAR" property="bookName" /> <result column="book_price" jdbcType="DOUBLE" property="bookPrice" /> </resultMap> <sql id="Base_Column_List"> id, book_name, book_price </sql> <select id="selectByPrimaryKey" parameterType="java.lang.Integer" resultMap="BaseResultMap"> select <include refid="Base_Column_List" /> from book where id = #{id,jdbcType=INTEGER} </select> <delete id="deleteByPrimaryKey" parameterType="java.lang.Integer"> delete from book where id = #{id,jdbcType=INTEGER} </delete> <insert id="insert" parameterType="com.aaa.zk.dubbo.model.Book" > insert into book (book_name, book_price ) values (#{bookName,jdbcType=VARCHAR}, #{bookPrice,jdbcType=DOUBLE} ) </insert> <insert id="insertSelective" parameterType="com.aaa.zk.dubbo.model.Book"> insert into book <trim prefix="(" suffix=")" suffixOverrides=","> <if test="id != null"> id, </if> <if test="bookName != null"> book_name, </if> <if test="bookPrice != null"> book_price, </if> </trim> <trim prefix="values (" suffix=")" suffixOverrides=","> <if test="id != null"> #{id,jdbcType=INTEGER}, </if> <if test="bookName != null"> #{bookName,jdbcType=VARCHAR}, </if> <if test="bookPrice != null"> #{bookPrice,jdbcType=DOUBLE}, </if> </trim> </insert> <update id="updateByPrimaryKeySelective" parameterType="com.aaa.zk.dubbo.model.Book"> update book <set> <if test="bookName != null"> book_name = #{bookName,jdbcType=VARCHAR}, </if> <if test="bookPrice != null"> book_price = #{bookPrice,jdbcType=DOUBLE}, </if> </set> where id = #{id,jdbcType=INTEGER} </update> <update id="updateByPrimaryKey" parameterType="com.aaa.zk.dubbo.model.Book"> update book set book_name = #{bookName,jdbcType=VARCHAR}, book_price = #{bookPrice,jdbcType=DOUBLE} where id = #{id,jdbcType=INTEGER} </update> <select id="selectAll" resultMap="BaseResultMap" > select * from book </select> </mapper>
consummer:
(1)所依赖jar包
<dependencies> <!-- springboot-starter-web --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <version>1.5.10.RELEASE</version> </dependency> <!-- dubbo-spring-boot-starter --> <dependency> <groupId>com.alibaba.spring.boot</groupId> <artifactId>dubbo-spring-boot-starter</artifactId> <version>2.0.0</version> </dependency> <!-- netty start --> <dependency> <groupId>org.jboss.netty</groupId> <artifactId>netty</artifactId> <version>3.2.6.Final</version> </dependency> <!-- netty end --> <dependency> <groupId>org.apache.zookeeper</groupId> <artifactId>zookeeper</artifactId> <version>3.4.6</version> </dependency> <dependency> <groupId>com.github.sgroschupf</groupId> <artifactId>zkclient</artifactId> <version>0.1</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> <version>1.5.10.RELEASE</version> </dependency> <dependency> <groupId>net.sourceforge.nekohtml</groupId> <artifactId>nekohtml</artifactId> <version>1.9.21</version> </dependency> </dependencies>
(2)图示:
(3)实体类:同provider
(4)service:
package com.aaa.zk.dubbo.service; import com.aaa.zk.dubbo.model.Book; import java.util.List; import java.util.Map; public interface BookService { Map<String,Object> selectAll(); Map<String,Object> insert(Book record); Map<String,Object> delete(Integer id); Map<String,Object> update(Book record); Map<String,Object> selectById(Integer id); }
(5)controller
package com.aaa.zk.dubbo.controller; import com.aaa.zk.dubbo.model.Book; import com.aaa.zk.dubbo.model.User; import com.aaa.zk.dubbo.service.BookService; import com.aaa.zk.dubbo.service.UserService; import com.alibaba.dubbo.config.annotation.Reference; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import java.util.Map; @Controller public class BookController { @Reference private BookService bookService; @Reference private UserService userService; /** * 跳转登录界面 * @return */ @RequestMapping("/login") public String Login(){ return "login"; } /** * 只等登录操作 * @param user * @return */ @RequestMapping("/doLogin") public String doLogin(User user){ Map<String,Object> resultMap=userService.queryAll(user); if((Integer) resultMap.get("code")==200){ return "redirect:/show"; }else { return "404"; } } /** * 查询并返回ajax页面 * @param * @return */ @RequestMapping("/show") public String selectAllAjax(){ return "index"; } /** * 查询全部 * @return */ @RequestMapping("/bookSelectAll") @ResponseBody public Map<String, Object> bookSelectAll() { return bookService.selectAll(); } /** * 添加 * @param book * @return */ @RequestMapping("/bookInsert") @ResponseBody public String bookInsert(Book book){ Map<String,Object> resultMap=bookService.insert(book); if ((Integer) resultMap.get("code")==200){ return "ok"; } return "404"; } /** * 删除 * @param id * @return */ @RequestMapping("/bookDelete") @ResponseBody public String bookDelete(Integer id){ Map<String, Object> resultMap = bookService.delete(id); if ((Integer) resultMap.get("code")==200){ return "ok"; }else { return "404"; } } /** * 修改 * @param book * @return */ @RequestMapping("/bookUpdate") @ResponseBody public String bookUpdate(Book book){ Map<String, Object> resultMap = bookService.update(book); if ((Integer) resultMap.get("code")==200){ return "ok"; }else { return "404"; } } @RequestMapping("/bookSelectById") @ResponseBody public Book bookSelectById(Integer id){ Map<String, Object> resultMap=bookService.selectById(id); if ((Integer) resultMap.get("code")==200){ Book book= (Book) resultMap.get("result"); System.out.println(book); return book; }else { return null; } } }
(6)启动项:
package com.aaa.zk.dubbo; import com.alibaba.dubbo.config.spring.context.annotation.EnableDubbo; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication @EnableDubbo public class ApplicationRun8082 { public static void main(String[] args) { SpringApplication.run(ApplicationRun8082.class,args); } }
(7)application.properties
server.port=8082 server.context-path=/ dubbo.application.name=user-consumer #dubbo协议名称 dubbo.protocol.name=dubbo #dubbo的端口号 dubbo.protocol.port=20881 dubbo.registry.address=zookeeper://192.168.21.135:2181 spring.thymeleaf.cache=false spring.thymeleaf.mode=LEGACYHTML5
(8)resources-->static-->jQuery
(9)templates:
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org" xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity4"> <head> <meta charset="UTF-8"> <title>ShowPage</title> <script type="text/javascript" src="/jquery-1.12.4.js"></script> <script type="text/javascript"> function bookSelectAll() { $.get("/bookSelectAll", function (data) { var bookList = data.result; var tr = ""; if (data.code == 200) { for (var i = 0; i < bookList.length; i++) { tr += "<tr>" + "<td>" + bookList[i].id + "</td>" + "<td>" + bookList[i].bookName + "</td>" + "<td>" + bookList[i].bookPrice + "</td>" + "<td><input type='button' οnclick='bookDelete(" + bookList[i].id + ")' value='删除'/><input type='button' οnclick='selectById(" + bookList[i].id + ")' value='修改' /></td>" + "</tr>" } //取到了值 $("#show_table").append("<table border='1px solid black'>" + "<thead>" + "<tr>" + "<th>图书编码</th>" + "<th>图书名称</th>" + "<th>图书价格</th>" + "<th>操作</th>" + "</tr>" + "</thead>" + "<tbody>" + tr + "</tbody>" + "</table>"); } }); } function insert() { $.ajax({ type: "post", url: "/bookInsert", data: $("#bookInsertAjax").serialize(), success: function (data) { alert(data); if (data == "ok") { alert("添加成功"); $("#show_table").empty(); bookSelectAll(); } else { alert("添加失败"); } } }); } function bookDelete(id) { $.ajax({ type: "post", url: "/bookDelete", data: {"id": id}, success: function (data) { if (data == "ok") { alert("删除成功"); $("#show_table").empty(); bookSelectAll(); } else { alert("删除失败"); } } }); } function bookUpdate() { $.ajax({ type: "post", url: "/bookUpdate", data: $("#bookUpdateById").serialize(), success: function (data) { if (data == "ok") { alert("修改成功"); $("#show_table").empty(); bookSelectAll(); } else { alert("修改失败"); } } }); } function selectById(id) { $.ajax({ type: "get", url: "/bookSelectById", data: {"id": id}, success: function (data) { $("#bookUpdateById").empty(); alert(data); var book = data; $("#bookUpdateById").append( "<div>" + "<input name='id' value='" + book.id + "'/></div>" + "<div>图书名称" + "<input type='text' name='bookName' value='" + book.bookName + "' /></div>" + "<div>图书价格" + "<input type='text' name='bookPrice' value='" + book.bookPrice + "'/></div>" + "<div><input type='button' value='修改' οnclick='bookUpdate()'/></div>" ) } }); } $(function () { bookSelectAll(); }) </script> </head> <body> <div id="show_table"></div> <form id="bookInsertAjax"> <h2>添加数据</h2> <div>名称:<input type="text" name="bookName"/></div> <div>价格:<input type="text" name="bookPrice"/></div> <input type="button" value="添加" οnclick="insert()"/> </form> <form id="bookUpdateById"> </form> </body> </html>