Springboot整合dubbo构建maven多模块项目(四) - 集成mybatis
原文地址:https://blog.****.net/liyanlei5858/article/details/79066790
完整代码下载:http://download.****.net/download/liyanlei5858/10206852
在Springboot整合dubbo构建maven多模块项目(三) - 把server分为api(服务接口定义)和server(服务实现)两个子module中,我们配置了一个dubbo项目,包含三个模块springboot-dubbo-api、springboot-dubbo-server和springboot-dubbo-client,并且在springboot-dubbo-server和springboot-dubbo-client的pom中都添加了对dubbo、zk及springboot-dubbo-api的依赖。
下面我们一起来实践下dubbo服务端及客户端的简单设置,以及在dubbo admin中查看服务的注册及消费情况。
1 环境搭建
dubbo环境的搭建可参考文章环境搭建(一):Dubbo环境搭建,包括基于docker的zookeeper安装及dubbo admin的安装。
2 dubbo服务提供方配置
-- ----------------------------
-- Table structure for user
-- ----------------------------
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`user_name` varchar(20) DEFAULT '' COMMENT '登录名',
`real_name` varchar(10) DEFAULT '' COMMENT '真实姓名',
`park_code` char(8) DEFAULT '' COMMENT '园区编号',
`park_name` varchar(20) DEFAULT '' COMMENT '园区',
`pwd` varchar(20) DEFAULT '' COMMENT '密码',
`state` tinyint(4) DEFAULT '0' COMMENT '状态,0-无效,1-有效',
`role` tinyint(4) DEFAULT '0' COMMENT '角色,0-园区管理员,1-系统管理员',
`last_date` timestamp NULL DEFAULT NULL COMMENT '最近一次访问时间',
`last_ip` int(10) unsigned DEFAULT '0' COMMENT '最后一次登录的IP',
`login_count` int(6) DEFAULT '0' COMMENT '登录次数',
`date_add` timestamp NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '添加时间',
`date_upd` timestamp NULL DEFAULT NULL COMMENT '修改时间',
PRIMARY KEY (`id`),
KEY `fk_user_park` (`park_code`),
CONSTRAINT `fk_user_park` FOREIGN KEY (`park_code`) REFERENCES `park` (`code`) ON DELETE NO ACTION ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=27 DEFAULT CHARSET=utf8;
2.1 在springboot-dubbo-api中创建实体类及服务接口
BaseEntity.java:
package com.example.demo.model; import java.io.Serializable; import java.util.Date; /** * @author liyanlei * @Description:实体公共属性 * @date 2018-01-15 16:15 */ public class BaseEntity implements Serializable { /** * 删除标记(0:正常;1:删除;2:审核;) */ // public static final String DEL_FLAG_NORMAL = "0"; // public static final String DEL_FLAG_DELETE = "1"; // public static final String DEL_FLAG_AUDIT = "2"; /** 添加时间 */ private Date dateAdd; /** 修改时间 */ private Date dateUpd; // private String delFlag; //0 有效 1 删除 public BaseEntity() { } public BaseEntity(Date dateAdd, Date dateUpd) { this.dateAdd = dateAdd; this.dateUpd = dateUpd; } public Date getDateAdd() { return dateAdd; } public void setDateAdd(Date dateAdd) { this.dateAdd = dateAdd; } public Date getDateUpd() { return dateUpd; } public void setDateUpd(Date dateUpd) { this.dateUpd = dateUpd; } }User.java
package com.example.demo.model; import java.util.Date; public class User extends BaseEntity { /** 主键ID,自增 */ private Integer id; /** 登录名 */ private String userName; /** 真实姓名 */ private String realName; /** 园区编号 */ private String parkCode; /** 园区 */ private String parkName; /** 密码 */ private String pwd; /** 状态,0-无效,1-有效 */ private Byte state; /** 角色,0-园区管理员,1-系统管理员 */ private Byte role; /** 最近一次访问时间 */ private Date lastDate; /** 最后一次登录的IP */ private String lastIp; /** 登录次数 */ private Integer loginCount; public User() { } public User(Integer id, String userName, String realName, String parkCode, String parkName, String pwd, Byte state, Byte role, Date lastDate, String lastIp, Integer loginCount, Date dateAdd, Date dateUpd) { super(dateAdd, dateUpd); this.id = id; this.userName = userName; this.realName = realName; this.parkCode = parkCode; this.parkName = parkName; this.pwd = pwd; this.state = state; this.role = role; this.lastDate = lastDate; this.lastIp = lastIp; this.loginCount = loginCount; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public String getRealName() { return realName; } public void setRealName(String realName) { this.realName = realName; } public String getParkCode() { return parkCode; } public void setParkCode(String parkCode) { this.parkCode = parkCode; } public String getParkName() { return parkName; } public void setParkName(String parkName) { this.parkName = parkName; } public String getPwd() { return pwd; } public void setPwd(String pwd) { this.pwd = pwd; } public Byte getState() { return state; } public void setState(Byte state) { this.state = state; } public Byte getRole() { return role; } public void setRole(Byte role) { this.role = role; } public Date getLastDate() { return lastDate; } public void setLastDate(Date lastDate) { this.lastDate = lastDate; } public String getLastIp() { return lastIp; } public void setLastIp(String lastIp) { this.lastIp = lastIp; } public Integer getLoginCount() { return loginCount; } public void setLoginCount(Integer loginCount) { this.loginCount = loginCount; } }Pagination.java
package com.example.demo.vo.queryVo; /** * 分页实体类 */ public class Pagination { //第几页 从0开始 private int pageNo = 0; //每页多少条数据 private int pageSize = 10; private int totalCount = 0; private int skip = 0; public int getPageNo() { return pageNo; } public void setPageNo(int pageNo) { this.pageNo = pageNo; } public int getPageSize() { return pageSize; } public void setPageSize(int pageSize) { this.pageSize = pageSize; } public int getSkip() { return this.pageNo * this.pageSize; } public void setSkip(int skip) { this.skip = skip; } }UserQuery.java
package com.example.demo.vo.queryVo; import java.io.Serializable; /** * 查询条件 */ public class UserQuery extends Pagination implements Serializable { private static final long serialVersionUID = 1609252883937908952L; //查询条件 private int notId = -1; /** 园区编号 */ private String parkCode; /** 登录名 or 真实姓名 */ private String name; /** 登录名 or 真实姓名 模糊查询 */ private String nameLike; //查询条件 public int groupId = -1; //组ID public int getNotId() { return notId; } public void setNotId(int notId) { this.notId = notId; } public int getGroupId() { return groupId; } public void setGroupId(int groupId) { this.groupId = groupId; } public static long getSerialVersionUID() { return serialVersionUID; } public String getParkCode() { return parkCode; } public void setParkCode(String parkCode) { this.parkCode = parkCode; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getNameLike() { return nameLike; } public void setNameLike(String nameLike) { this.nameLike = nameLike; } }PageModel.java
package com.example.demo.vo.resultVo; import java.io.Serializable; import java.util.List; /** * 分页,返回数据 */ public class PageModel<T> implements Serializable{ //结果集 private List<T> datas; //每页多少条数据 private int pageSize = 10; //第几页 从0开始 private int pageNo = 0; //总条数 private long totalCount = 0; //总页数 private int totalPages = 0; private int last_index = 0; public List<T> getDatas() { return datas; } public void setDatas(List<T> datas) { this.datas = datas; } public int getPageSize() { return pageSize; } public void setPageSize(int pageSize) { this.pageSize = pageSize; } public int getPageNo() { return pageNo; } public void setPageNo(int pageNo) { this.pageNo = pageNo; } public long getTotalCount() { return totalCount; } public void setTotalCount(long totalCount) { this.totalCount = totalCount; } public int getTotalPages() { return (int) (totalCount % pageSize >0 ? (totalCount/pageSize+1) :(totalCount / pageSize)); } public void setTotalPages(int totalPages) { this.totalPages = totalPages; } public int getLast_index() { return last_index; } public void setLast_index(int last_index) { this.last_index = last_index; } }UserService.java
package com.example.demo.api; import com.example.demo.model.User; import com.example.demo.vo.queryVo.UserQuery; import com.example.demo.vo.resultVo.PageModel; import java.util.List; /** * @author liyanlei * @Description: 用户Service * @date 2018-01-15 16:15 */ public interface UserService { /** * 根据id查询 * @param id 用户ID * @return 商户订单 */ User findOneById(Integer id); /** * 根据用户名密码查询 * @param userName * @param pwd * @return */ User findOneByNameAndPwd(String userName, String pwd); /** * 根据用户名称查询 * @param userName * @return */ User findOneByUserName(String userName); /** * 根据组ID查询 * @param groupId * @return */ List<User> findListByGroupId(int groupId); /** * 根据角色列表查询 * @param roleTypes * @return */ List<User> findListByRoles(String roleTypes); /** * 根据条件分页查询 * @param query 查询条件 * @return 分页信息 */ PageModel<User> findPageByQuery(UserQuery query); /** * 根据条件查询记录总条数 * @param query 查询条件 * @return 符合条件的记录数 */ int findCountByQuery(UserQuery query); /** * 查询账号是否存在 * @param userName 账号 * @param notId != ID * @return 0:不存在,其他:存在。 */ int findCountByUserName(String userName, Integer notId); /** * 添加一个用户 * @param user * @return */ int insertOne(User user); /** * 插入(插入属性不为空的值) * @param user * @return */ int insertSelective(User user); /** * 根据ID修改用户信息 * @param user * @return */ int updateById(User user); /** * 根据ID修改组信息 * @param user * @return */ int updateByIdSelective(User user); int delById(Integer id); // PageModel<User> getCarrierPage(Integer pageIndex, Integer pageSize, CarrierVo carrierVo); }
2.2 springboot-dubbo-server中实现springboot-dubbo-api接口
目录结构:
2.2.1 集成mybatis - pom.xml中引入jar包
<dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>1.3.1</version> </dependency>
2.2.2 集成mybatis - application.properties 数据库连接配置
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/XXX?useUnicode=true&characterEncoding=UTF-8 spring.datasource.username=xxx spring.datasource.password=xxx spring.datasource.driver-class-name=com.mysql.jdbc.Driver spring.datasource.max-active=10 spring.datasource.max-idle=5 spring.datasource.min-idle=0xxx需要修改为自己数据库的配置
2.2.3 集成mybatis - UserMapper.java
package com.example.demo.dao; import com.example.demo.model.User; import com.example.demo.vo.queryVo.UserQuery; import org.apache.ibatis.annotations.*; import java.util.List; public interface UserMapper { /** * 根据条件分页查询 * @param query 查询条件 * @return 分页数据 */ List<User> selectListByQuery(UserQuery query); /** * 根据条件查询记录总条数 * @param query 查询条件 * @return 符合条件的记录数 */ int selectCountByQuery(UserQuery query); @Delete({ "delete from user", "where id = #{id,jdbcType=INTEGER}" }) int deleteByPrimaryKey(Integer id); @Insert({ "insert into user (user_name, real_name, ", "park_code, park_name, ", "pwd, state, role, ", "last_date, last_ip, ", "login_count, date_add, ", "date_upd)", "values (#{userName,jdbcType=VARCHAR}, #{realName,jdbcType=VARCHAR}, ", "#{parkCode,jdbcType=CHAR}, #{parkName,jdbcType=VARCHAR}, ", "#{pwd,jdbcType=VARCHAR}, #{state,jdbcType=TINYINT}, #{role,jdbcType=TINYINT}, ", "#{lastDate,jdbcType=TIMESTAMP}, INET_ATON(#{lastIp,jdbcType=INTEGER}), ", "#{loginCount,jdbcType=INTEGER}, #{dateAdd,jdbcType=TIMESTAMP}, ", "#{dateUpd,jdbcType=TIMESTAMP})" }) // @SelectKey(statement="VALUES IDENTITY_VAL_LOCAL()", keyProperty="id", before=false, resultType=Integer.class) int insert(User record); int insertSelective(User record); @Select({ "select", "id, user_name, real_name, park_code, park_name, pwd, state, role, last_date, ", "INET_NTOA(last_ip) last_ip, login_count, date_add, date_upd", "from user", "where id = #{id,jdbcType=INTEGER}" }) @ResultMap("BaseResultMap") User selectByPrimaryKey(Integer id); @Select({ "select", "id, user_name, real_name, park_code, park_name, pwd, state, role, last_date, ", "INET_NTOA(last_ip) last_ip, login_count, date_add, date_upd", "from user", "where user_name = #{userName,jdbcType=VARCHAR} and pwd = #{pwd,jdbcType=VARCHAR}" }) @ResultMap("BaseResultMap") User selectOneByNameAndPwd(String userName, String pwd); @Select({ "select", "id, user_name, real_name, park_code, park_name, pwd, state, role, last_date, ", "INET_NTOA(last_ip) last_ip, login_count, date_add, date_upd", "from user", "where user_name = #{userName,jdbcType=VARCHAR}" }) @ResultMap("BaseResultMap") User selectOneByUserName(String userName); /** * 查询账号是否存在 * @param userName 账号 * @param notId != ID * @return 0:不存在,其他:存在。 */ @Select({ "select count(*) from `user` ", "where user_name = #{userName,jdbcType=VARCHAR} and id != #{notId,jdbcType=INTEGER}" }) // @ResultType("java.lang.Integer") int selectCountByUserName(@Param("userName") String userName, @Param("notId") Integer notId); int updateByPrimaryKeySelective(User record); @Update({ "update user", "set user_name = #{userName,jdbcType=VARCHAR},", "real_name = #{realName,jdbcType=VARCHAR},", "park_code = #{parkCode,jdbcType=CHAR},", "park_name = #{parkName,jdbcType=VARCHAR},", "pwd = #{pwd,jdbcType=VARCHAR},", "state = #{state,jdbcType=TINYINT},", "role = #{role,jdbcType=TINYINT},", "last_date = #{lastDate,jdbcType=TIMESTAMP},", "last_ip = INET_ATON(#{lastIp,jdbcType=INTEGER}),", "login_count = #{loginCount,jdbcType=INTEGER},", "date_add = #{dateAdd,jdbcType=TIMESTAMP},", "date_upd = #{dateUpd,jdbcType=TIMESTAMP}", "where id = #{id,jdbcType=INTEGER}" }) int updateByPrimaryKey(User record); }
2.2.4 集成mybatis - UserMapper.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" > <mapper namespace="com.example.demo.dao.UserMapper" > <resultMap id="BaseResultMap" type="com.example.demo.model.User" > <constructor > <idArg column="id" jdbcType="INTEGER" javaType="java.lang.Integer" /> <arg column="user_name" jdbcType="VARCHAR" javaType="java.lang.String" /> <arg column="real_name" jdbcType="VARCHAR" javaType="java.lang.String" /> <arg column="park_code" jdbcType="CHAR" javaType="java.lang.String" /> <arg column="park_name" jdbcType="VARCHAR" javaType="java.lang.String" /> <arg column="pwd" jdbcType="VARCHAR" javaType="java.lang.String" /> <arg column="state" jdbcType="TINYINT" javaType="java.lang.Byte" /> <arg column="role" jdbcType="TINYINT" javaType="java.lang.Byte" /> <arg column="last_date" jdbcType="TIMESTAMP" javaType="java.util.Date" /> <arg column="last_ip" jdbcType="INTEGER" javaType="java.lang.String" /> <arg column="login_count" jdbcType="INTEGER" javaType="java.lang.Integer" /> <arg column="date_add" jdbcType="TIMESTAMP" javaType="java.util.Date" /> <arg column="date_upd" jdbcType="TIMESTAMP" javaType="java.util.Date" /> </constructor> </resultMap> <sql id="Base_Column_List" > id, user_name, real_name, park_code, park_name, pwd, state, role, last_date, INET_NTOA(last_ip) last_ip, login_count, date_add, date_upd </sql> <!-- 根据条件分页查询数据 开始 --> <select id="selectListByQuery" resultMap="BaseResultMap" parameterType="com.example.demo.vo.queryVo.UserQuery"> select <include refid="Base_Column_List"/> from `user` <where> <if test="name != null and name != ''"> and (user_name = #{name} or real_name = #{name}) </if> <if test="parkCode != null and parkCode != ''"> and park_code = #{parkCode} </if> <if test="nameLike != null and nameLike != ''"> and (user_name like CONCAT('%', #{nameLike}, '%') or real_name like CONCAT('%', #{nameLike}, '%')) </if> <if test="notId != -1"> and id != #{notId} </if> </where> order by id desc <if test="pageSize > 0"> limit #{skip}, #{pageSize} </if> </select> <!-- 根据条件分页查询数据 结束 --> <!-- 根据条件查询记录数 开始 --> <select id="selectCountByQuery" parameterType="com.example.demo.vo.queryVo.UserQuery" resultType="java.lang.Integer"> SELECT count(*) FROM `user` <where> <if test="name != null and name != ''"> and (user_name = #{nameLike} or real_name = #{nameLike}) </if> <if test="parkCode != null and parkCode != ''"> and park_code = #{parkCode} </if> <if test="nameLike != null and nameLike != ''"> and (user_name like CONCAT('%', #{nameLike}, '%') or real_name like CONCAT('%', #{nameLike}, '%')) </if> <if test="notId != -1"> and id != #{notId} </if> </where> </select> <!-- 根据条件查询记录数 结束 --> <insert id="insertSelective" parameterType="com.example.demo.model.User" > <!--<selectKey resultType="java.lang.Integer" keyProperty="id" order="AFTER" > VALUES IDENTITY_VAL_LOCAL() </selectKey>--> insert into user <trim prefix="(" suffix=")" suffixOverrides="," > <if test="userName != null" > user_name, </if> <if test="realName != null" > real_name, </if> <if test="parkCode != null" > park_code, </if> <if test="parkName != null" > park_name, </if> <if test="pwd != null" > pwd, </if> <if test="state != null" > state, </if> <if test="role != null" > role, </if> <if test="lastDate != null" > last_date, </if> <if test="lastIp != null" > last_ip, </if> <if test="loginCount != null" > login_count, </if> <if test="dateAdd != null" > date_add, </if> <if test="dateUpd != null" > date_upd, </if> </trim> <trim prefix="values (" suffix=")" suffixOverrides="," > <if test="userName != null" > #{userName,jdbcType=VARCHAR}, </if> <if test="realName != null" > #{realName,jdbcType=VARCHAR}, </if> <if test="parkCode != null" > #{parkCode,jdbcType=CHAR}, </if> <if test="parkName != null" > #{parkName,jdbcType=VARCHAR}, </if> <if test="pwd != null" > #{pwd,jdbcType=VARCHAR}, </if> <if test="state != null" > #{state,jdbcType=TINYINT}, </if> <if test="role != null" > #{role,jdbcType=TINYINT}, </if> <if test="lastDate != null" > #{lastDate,jdbcType=TIMESTAMP}, </if> <if test="lastIp != null" > INET_ATON(#{lastIp,jdbcType=INTEGER}), </if> <if test="loginCount != null" > #{loginCount,jdbcType=INTEGER}, </if> <if test="dateAdd != null" > #{dateAdd,jdbcType=TIMESTAMP}, </if> <if test="dateUpd != null" > #{dateUpd,jdbcType=TIMESTAMP}, </if> </trim> </insert> <update id="updateByPrimaryKeySelective" parameterType="com.example.demo.model.User" > update user <set > <if test="userName != null" > user_name = #{userName,jdbcType=VARCHAR}, </if> <if test="realName != null" > real_name = #{realName,jdbcType=VARCHAR}, </if> <if test="parkCode != null" > park_code = #{parkCode,jdbcType=CHAR}, </if> <if test="parkName != null" > park_name = #{parkName,jdbcType=VARCHAR}, </if> <if test="pwd != null" > pwd = #{pwd,jdbcType=VARCHAR}, </if> <if test="state != null" > state = #{state,jdbcType=TINYINT}, </if> <if test="role != null" > role = #{role,jdbcType=TINYINT}, </if> <if test="lastDate != null" > last_date = #{lastDate,jdbcType=TIMESTAMP}, </if> <if test="lastIp != null" > last_ip = INET_ATON(#{lastIp,jdbcType=INTEGER}), </if> <if test="loginCount != null" > login_count = #{loginCount,jdbcType=INTEGER}, </if> <if test="dateAdd != null" > date_add = #{dateAdd,jdbcType=TIMESTAMP}, </if> <if test="dateUpd != null" > date_upd = #{dateUpd,jdbcType=TIMESTAMP}, </if> </set> where id = #{id,jdbcType=INTEGER} </update> </mapper>
2.2.5 集成mybatis - UserServiceImpl.java
package com.example.demo.api.impl; import com.alibaba.dubbo.config.annotation.Service; import com.example.demo.api.UserService; import com.example.demo.dao.UserMapper; import com.example.demo.model.User; import com.example.demo.vo.queryVo.UserQuery; import com.example.demo.vo.resultVo.PageModel; import org.springframework.beans.factory.annotation.Autowired; import java.util.List; /** * @author liyanlei * @Description: userService 实现 * @date 2018-01-15 16:15 */ //该Service注解是dubbo的注解,不是spring的。若使用xml配置方式暴露接口,则不需要该注解。 @Service public class UserServiceImpl implements UserService { @Autowired private UserMapper userMapper; @Override public User findOneById(Integer id) { return this.userMapper.selectByPrimaryKey(id); } @Override public User findOneByNameAndPwd(String userName, String pwd) { return this.userMapper.selectOneByNameAndPwd(userName, pwd); } @Override public User findOneByUserName(String userName) { return this.userMapper.selectOneByUserName(userName); } @Override public PageModel<User> findPageByQuery(UserQuery query) { PageModel<User> pageModel = new PageModel<User>(); pageModel.setDatas(this.userMapper.selectListByQuery(query));//列表数据 pageModel.setTotalCount(this.userMapper.selectCountByQuery(query));//总条数 return pageModel; } @Override public int findCountByQuery(UserQuery query) { return this.userMapper.selectCountByQuery(query); } @Override public List<User> findListByGroupId(int groupId) { return null; } @Override public List<User> findListByRoles(String roleTypes) { return null; } @Override public int findCountByUserName(String userName, Integer notId) { if(notId == null){ notId = 0; } return this.userMapper.selectCountByUserName(userName, notId); } @Override public int insertOne(User user) { return this.userMapper.insert(user); } @Override public int insertSelective(User user) { return this.userMapper.insertSelective(user); } @Override public int updateById(User user) { return this.userMapper.updateByPrimaryKey(user); } @Override public int updateByIdSelective(User user) { return this.userMapper.updateByPrimaryKeySelective(user); } @Override public int delById(Integer id) { return this.userMapper.deleteByPrimaryKey(id); } }
2.3 dubbo 配置 provider.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd"> <!-- 提供方应用信息,用于计算依赖关系 --> <dubbo:application name="demo-provider" /> <!-- 使用zookeeper注册中心暴露服务地址 --> <dubbo:registry protocol="zookeeper" address="localhost:2181" timeout="60000"/> <!-- 用dubbo协议在20880端口暴露服务 --> <dubbo:protocol name="dubbo" port="20880" /> <!-- 暴露dubbo服务的方式一--> <!-- 使用注解方式暴露接口,会自动扫描package下所有包中dubbo相关的注解,这样就不用在xml中再针对每个服务接口配置dubbo:service interface--> <dubbo:annotation package="com.example.demo.api.impl"/> <!-- 暴露dubbo服务的方式二 --> <!-- 使用xml配置方式申明暴露一个接口服务,在程序启动的时候会自动注册到zookeeper。 等同于在类上打@service注解,打了注解就必须要用annotation指定启动扫描路径,使用这种方式,就不需要指定annotation了--> <!--<dubbo:service interface="com.example.demo.api.UserService" ref="userService"/>--> <!-- 具体的实现bean,id与上面的ref要一致--> <!--<bean id="userService" class="com.example.demo.api.impl.UserServiceImpl" />--> </beans>
2.4 启动类SpringbootDubboServerApplication.java
package com.example.demo; import org.apache.ibatis.session.SqlSessionFactory; import org.apache.tomcat.jdbc.pool.DataSource; import org.mybatis.spring.SqlSessionFactoryBean; 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 org.springframework.context.annotation.ImportResource; import org.springframework.core.io.support.PathMatchingResourcePatternResolver; import org.mybatis.spring.annotation.MapperScan; import org.springframework.jdbc.datasource.DataSourceTransactionManager; import org.springframework.transaction.PlatformTransactionManager; @SpringBootApplication @MapperScan("com.example.demo.dao") @ImportResource("classpath:provider.xml") //加载xml文件 public class SpringbootDubboServerApplication { @Bean @ConfigurationProperties(prefix="spring.datasource") public DataSource dataSource() { return new org.apache.tomcat.jdbc.pool.DataSource(); } @Bean public SqlSessionFactory sqlSessionFactoryBean() throws Exception { SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean(); sqlSessionFactoryBean.setDataSource(dataSource()); PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(); sqlSessionFactoryBean.setMapperLocations(resolver.getResources("classpath:/mappers/*.xml")); return sqlSessionFactoryBean.getObject(); } @Bean public PlatformTransactionManager transactionManager() { return new DataSourceTransactionManager(dataSource()); } public static void main(String[] args) throws InterruptedException { SpringApplication.run(SpringbootDubboServerApplication.class, args); Thread.sleep(Long.MAX_VALUE); //pom中没有加spring-boot-starter-web依赖,启动时没有tomcat容器,会自动退出,所以加了一个sleep防止自动退出 } }运行springboot-dubbo-server项目
3 dubbo服务消费方配置
项目结构:
3.1 创建xml配置文件
创建远程服务代理和暴露dubbo服务一样,也有两种方式,一是使用注解方式,二是使用xml配置方式。下面的consumer.xml中使用的是第一种方式。如果使用xml配置方式创建远程服务代理,将dubbo:annotation一行替换成如下配置即可。
consumer.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd"> <!--消费方应用名,用于计算依赖关系,不是匹配条件,不要与提供方一样 --> <dubbo:application name="demo-consumer"/> <!--zookeeper注册中心 --> <dubbo:registry protocol="zookeeper" address="localhost:2181" timeout="60000"/> <!--关闭服务消费方所有服务的启动检查。dubbo缺省会在启动时检查依赖的服务是否可用,不可用时会抛出异常,阻止Spring初始化完成。--> <dubbo:consumer check="false" /> <!-- 使用注解方式创建远程服务代理--> <dubbo:annotation package="com.example.demo.controller"/> <!-- 使用xml配置方式创建远程服务代理,id即为provider.xml中暴露的服务的id--> <!-- 等同于dubbo:annotation 加上代码里的@Reference注解--> <!--<dubbo:reference id="userService" interface="com.example.demo.api.UserService"/>--> </beans>
3.2 创建Controller
UserController.java
package com.example.demo.controller; import com.alibaba.dubbo.config.annotation.Reference; import com.example.demo.api.UserService; import com.example.demo.model.User; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.RestController; import java.math.BigDecimal; import java.util.Date; @RestController @RequestMapping("/user") public class UserController { //注入服务提供方暴露的接口,通过@Reference注解,dubbo会在扫描的时候自动代理接口,然后通过rpc调用远程服务。 //如果用xml配置方式,需要将@Reference换成@Autowired。 // @Autowired @Reference UserService userService; @RequestMapping("/findOne") @ResponseBody public User findOneById(Integer id){ if(id == null){ id = 18; } System.out.println(id); User user = userService.findOneById(id); if(user == null){ user = new User(); } return user; } @RequestMapping("/saveOne") @ResponseBody public int saveOne(){ User user = new User(1, "lisi", "李四", "010101", "北海公园", "pwd123456", (byte) 1, (byte)1, new Date(), "127.0.0.1", 12, new Date(), new Date()); return userService.insertOne(user); } @RequestMapping("/delOne") @ResponseBody public int delOne(Integer id){ return userService.delById(id); } }
3.3 编写启动类
SpringbootDubboClientApplication.java
package com.example.demo; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.ImportResource; //必须在controller包中,在这里报错(这个启动类无法启动) @SpringBootApplication @ImportResource("classpath:consumer.xml") //加载xml配置文件 //@RestController public class SpringbootDubboClientApplication { public static void main(String[] args) throws Exception{ SpringApplication.run(SpringbootDubboClientApplication.class, args); } }右键-->debug(run)运行启动类:
4 测试
在浏览器中调用canbuy接口,正常返回结果,说明我们的配置都生效啦~~~http://localhost:8080/user/saveOne
http://localhost:8080/user/findOne?id=12
http://localhost:8080/user/delOne?id=16
到这里,Spring Boot集成Dubbo,整合mybatis的内容都讲完啦
参考
https://testerhome.com/topics/11360