SSM綜合專案實戰(TTSC) -- day02 Dubbo註冊中心,通用Mapper,分頁外掛
一、Dubbo的連線方式
1、連線方式介紹
使用Dubbo進行遠端呼叫實現服務互動,它支援多種協議,如Hessian、HTTP、RMI、Memcached、Redis等等。由於Dubbo將這些協議的實現進行了封裝了,無論是服務端(開發服務)還是客戶端(呼叫服務),都不需要關心協議的細節,只需要在配置中指定使用的協議即可,從而保證了服務提供方與服務消費方之間的透明。
Dubbo的客戶端和服務端有三種連線方式,分別是:廣播,直連和使用zookeeper註冊中心
2、dubbo廣播方式
(1)、提供者
(2)、消費者
3、dubbo直連方式
Dubbo直連,首先要取消廣播,然後客戶端直接到指定需要的服務的url獲取服務即可。這種方式在企業中一般在開發中環境中使用,但是生產環境很少使用,因為服務是直接呼叫,沒有使用註冊中心,很難對服務進行管理。
(1)、提供者
(2)、消費者
4、dubbo使用zookeeper註冊中心方式
Dubbo註冊中心和廣播註冊中心配置類似,不過需要指定註冊中心型別和註冊中心地址,這個時候就不是把服務資訊進行廣播了,而是告訴給註冊中心進行管理,這個時候我們就需要有一個註冊中心。
官方推薦使用zookeeper作為註冊中心。
二、使用dubbo註冊中心的方式進行連線
1、zookeeper介紹
註冊中心負責服務地址的註冊與查詢,相當於目錄服務,服務提供者在啟動時與註冊中心互動,消費者不斷的發起請求獲取服務資訊,註冊中心不轉發請求,壓力較小。使用dubbo-2.3.3以上版本,建議使用zookeeper註冊中心。
Zookeeper是Apacahe Hadoop的子專案,是一個樹型的目錄服務,支援變更推送,適合作為Dubbo服務的註冊中心,工業強度較高,可用於生產環境,並推薦使用
2、搭建linux中的zookeeper環境
(1)、匯入Linux虛擬機器,帳號密碼為:root/root
(2)、匯入zookeeper安裝包
將zookeeper.tar.gz上傳值/usr/local目錄中
解壓壓縮包並進入解壓後的資料夾,建立data資料夾
進入conf下,複製配置檔案並改名
編輯zoo.cfg,修改資料存放目錄
進入bin目錄,啟動zookeeper
3、zookeeper註冊中心在專案中應用
(1)、服務提供者:
(2)、服務消費者:
三、配置zookeeper的監控中心Monitor
1、Linux中上傳tomcat並解壓
2、將監控中心的war包上傳至tomcat的webapps下
3、解壓war包,並刪除之前的war包
4、啟動tomcat,訪問監控中心,密碼為root/root
四、建立資料庫,匯入資料資料,建立mybatis測試的maven工程
1、建立資料庫
2、匯入資料
注意:sql資源在本部落格中下載,目前用於測試,因此時候只需要匯入user.sql即可
3、建立測試用的mybatis的maven工程
4、編寫配置檔案
sqlMapConfig.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>
<!-- 引入外部資源配置檔案 -->
<properties resource="jdbc.properties"></properties>
<settings>
<!-- 開啟駝峰自動對映 -->
<setting name="mapUnderscoreToCamelCase" value="true" />
</settings>
<!-- 配置別名 -->
<typeAliases>
<package name="cn.itcast.mybatis.pojo" />
</typeAliases>
<!-- 配置資料庫連線資訊 -->
<environments default="development">
<environment id="development">
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driver}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</dataSource>
</environment>
</environments>
<!-- 掃描對映檔案包 -->
<mappers>
<package name="cn.itcast.mybatis.mapper" />
</mappers>
</configuration>
User.java
package cn.itcast.mybatis.pojo;
import java.util.Date;
public class User {
// 主鍵
private Long id;
// 使用者名稱
private String userName;
// 密碼
private String password;
// 姓名
private String name;
// 年齡
private Integer age;
// 性別,1男性,2女性
private Integer sex;
// 出生日期
private Date birthday;
// 建立時間
private Date created;
// 更新時間
private Date updated;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public Integer getSex() {
return sex;
}
public void setSex(Integer sex) {
this.sex = sex;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public Date getCreated() {
return created;
}
public void setCreated(Date created) {
this.created = created;
}
public Date getUpdated() {
return updated;
}
public void setUpdated(Date updated) {
this.updated = updated;
}
}
UserMapper.java
package cn.itcast.mybatis.mapper;
import cn.itcast.mybatis.pojo.User;
public interface UserMapper {
/**
* 根據id查詢使用者
*
* @param id
* @return
*/
User queryUserById(Long id);
/**
* 新增
*
* @param user
*/
void saveUser(User user);
/**
* 更新
*
* @param user
*/
void updateUserById(User user);
/**
* 根據id刪除
*
* @param id
*/
void deleteUserById(Long id);
}
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="cn.itcast.mybatis.mapper.UserMapper">
<!-- 根據id查詢使用者 -->
<select id="queryUserById" parameterType="LonG" resultType="user">
SELECT * FROM `user` WHERE id = #{id}
</select>
<!-- 新增使用者 -->
<insert id="saveUser" useGeneratedKeys="true" keyColumn="id"
keyProperty="id">
INSERT INTO `user` (
`user_name`,
`password`,
`name`,
`age`,
`sex`,
`birthday`,
`created`,
`updated`
)
VALUES
(
#{userName},
#{password},
#{name},
#{age},
#{sex},
NOW(),
NOW(),
NOW()
)
</insert>
<!-- 修改使用者 -->
<update id="updateUserById">
UPDATE `user`
SET
`user_name` = #{userName},
`name` =
#{name}
WHERE
(`id` = #{id});
</update>
<!-- 刪除使用者 -->
<delete id="deleteUserById">
DELETE FROM `user` WHERE id=#{id}
</delete>
</mapper>
5、編寫測試類
package cn.itcast.mybatis.mapper;
import java.io.InputStream;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Before;
import org.junit.Test;
import cn.itcast.mybatis.pojo.User;
public class UserMapperTest {
private UserMapper userMapper;
@Before
public void setUp() throws Exception {
//建立SqlSessionFactoryBuilder
SqlSessionFactoryBuilder builer = new SqlSessionFactoryBuilder();
//讀取配置檔案
InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
//獲取SqlSessionFactroy
SqlSessionFactory sqlSessionFactory = builer.build(inputStream);
//開啟session,引數是自動提交事務
SqlSession sqlSession = sqlSessionFactory.openSession(true);
//使用sqlSession獲取mapper
this.userMapper = sqlSession.getMapper(UserMapper.class);
}
@Test
public void testQueryUserById() {
User user = this.userMapper.queryUserById(6l);
System.out.println(user);
}
@Test
public void testSaveUser() {
User user = new User();
user.setUserName("delaiwen");
user.setName("榮耀行刑官");
this.userMapper.saveUser(user);
System.out.println(user);
}
@Test
public void testUpdateUserById() {
User user = new User();
user.setId(7l);
user.setUserName("delaiwen123");
user.setName("榮耀行刑官123");
this.userMapper.updateUserById(user);
}
@Test
public void testDeleteUserById() {
this.userMapper.deleteUserById(7l);
}
}
五、通用Mapper的使用
1、通用mapper的整合和使用文件
注意:mapper文件在本部落格資原始檔中有
2、在測試專案的SqlMapConfig.xml中加入通用mapper的配置
<!-- 通用Mapper的攔截器配置方式 -->
<plugins>
<plugin interceptor="com.github.abel533.mapperhelper.MapperInterceptor">
<!--主鍵自增回寫方法,預設值MYSQL,詳細說明請看文件 -->
<property name="IDENTITY" value="MYSQL" />
<!--通用Mapper介面,多個通用介面用逗號隔開 -->
<property name="mappers" value="com.github.abel533.mapper.Mapper" />
</plugin>
</plugins>
3、通用Mapper的使用
(1)、建立通用Mapper的介面
package cn.itcast.mybatis.mapper;
import com.github.abel533.mapper.Mapper;
import cn.itcast.mybatis.pojo.User;
public interface NewUserMapper extends Mapper<User> {
}
(2)、改造POJO類
4、建立測試類
package cn.itcast.mybatis.mapper;
import static org.junit.Assert.*;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Before;
import org.junit.Test;
import com.github.abel533.entity.Example;
import com.github.abel533.entity.Example.Criteria;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import cn.itcast.mybatis.pojo.User;
public class NewUserMapperTest {
private NewUserMapper newUserMapper;
@Before
public void setUp() throws Exception {
// 建立SqlSessionFactoryBuilder
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
// 讀取配置檔案
InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
// 使用Builder獲取SqlSessionFactory
SqlSessionFactory sqlSessionFactory = builder.build(inputStream);
// 開啟sqlSession
// 引數就是設定是否自動提交事務,如果為true,就是自動提交
SqlSession sqlSession = sqlSessionFactory.openSession(true);
// 使用SqlSession獲取Mapper
this.newUserMapper = sqlSession.getMapper(NewUserMapper.class);
}
@Test
public void testSelectOne() {
User param = new User();
param.setUserName("liqing");
param.setSex(1);
User user = this.newUserMapper.selectOne(param);
System.out.println(user);
}
@Test
public void testSelect() {
User param = new User();
param.setSex(1);
List<User> list = this.newUserMapper.select(param);
for (User user : list) {
System.out.println(user);
}
}
@Test
public void testSelectCount() {
User param = new User();
// param.setUserName("liqing");
param.setSex(1);
int count = this.newUserMapper.selectCount(param);
System.out.println(count);
}
@Test
public void testSelectByPrimaryKey() {
User user = this.newUserMapper.selectByPrimaryKey(9l);
System.out.println(user);
}
// 新增,不忽略空欄位
@Test
public void testInsert() {
User param = new User();
param.setSex(1);
param.setUserName("liubei");
param.setName("劉備");
this.newUserMapper.insert(param);
System.out.println(param);
}
// 新增,忽略空欄位
@Test
public void testInsertSelective() {
User param = new User();
param.setSex(1);
param.setUserName("guanyu");
param.setName("關羽");
this.newUserMapper.insertSelective(param);
System.out.println(param);
}
@Test
public void testDelete() {
fail("Not yet implemented");
}
@Test
public void testDeleteByPrimaryKey() {
fail("Not yet implemented");
}
// 更新,不忽略空欄位,即:如果其餘欄位沒有設定資料,則置為null(無論之前資料庫中有沒有資料,都置為null)
@Test
public void testUpdateByPrimaryKey() {
User param = new User();
param.setId(1l);
param.setName("張三123");
this.newUserMapper.updateByPrimaryKey(param);
}
// 更新,忽略空欄位
@Test
public void testUpdateByPrimaryKeySelective() {
User param = new User();
param.setId(2l);
param.setName("李四123");
this.newUserMapper.updateByPrimaryKeySelective(param);
}
// -----------------------------------多條件查詢-------------------------
@Test
public void testSelectCountByExample() {
// 宣告查詢物件
Example example = new Example(User.class);
// 使用查詢物件建立查詢條件物件
Criteria criteria = example.createCriteria();
// 查詢條件是,id為3,4,5的使用者
// 設定條件,第一個引數就是條件的屬性名,第二個引數是查詢的條件按資料
List<Object> ids = new ArrayList<>();
ids.add(3);
ids.add(4);
ids.add(5);
criteria.andIn("id", ids);
int count = this.newUserMapper.selectCountByExample(example);
System.out.println(count);
}
@Test
public void testDeleteByExample() {
fail("Not yet implemented");
}
@Test
public void testSelectByExample() {
// 宣告查詢物件
Example example = new Example(User.class);
// 使用查詢物件建立查詢條件物件
Criteria criteria = example.createCriteria();
// 查詢條件是,id為3,4,5的使用者
// 設定條件,第一個引數就是條件的屬性名,第二個引數是查詢的條件按資料
List<Object> ids = new ArrayList<>();
ids.add(3);
ids.add(4);
ids.add(5);
criteria.andIn("id", ids);
List<User> list = this.newUserMapper.selectByExample(example);
for (User u : list) {
System.out.println(u);
}
}
// 根據條件更新,忽略空欄位
@Test
public void testUpdateByExampleSelective() {
// 宣告查詢物件
Example example = new Example(User.class);
// 使用查詢物件建立查詢條件物件
Criteria criteria = example.createCriteria();
// 查詢條件是,id為3,4,5的使用者
// 設定條件,第一個引數就是條件的屬性名,第二個引數是查詢的條件按資料
List<Object> ids = new ArrayList<>();
ids.add(3);
ids.add(4);
ids.add(5);
// 把條件設定進去
criteria.andIn("id", ids);
// 宣告需要把資料修改成什麼樣
User user = new User();
user.setPassword("123456");
// 第一個引數是,要把資料修改成神馬樣,第二個引數是要把神馬樣的資料進行修改,修改的條件
this.newUserMapper.updateByExampleSelective(user, example);
}
// 根據條件更新,不忽略空欄位
@Test
public void testUpdateByExample() {
// 宣告查詢物件
Example example = new Example(User.class);
// 使用查詢物件建立查詢條件物件
Criteria criteria = example.createCriteria();
// 查詢條件是,id為3,4,5的使用者
// 設定條件,第一個引數就是條件的屬性名,第二個引數是查詢的條件按資料
List<Object> ids = new ArrayList<>();
ids.add(3);
ids.add(4);
ids.add(5);
// 把條件設定進去
criteria.andIn("id", ids);
// 宣告需要把資料修改成什麼樣
User user = new User();
user.setPassword("222");
// 第一個引數是,要把資料修改成神馬樣,第二個引數是要把神馬樣的資料進行修改,修改的條件
this.newUserMapper.updateByExample(user, example);
}
}
六、分頁外掛的使用
1、之前分頁的實現方法
(1)、在通用mapper介面中新增分頁方法
package cn.itcast.mybatis.mapper;
import java.util.List;
import java.util.Map;
import com.github.abel533.mapper.Mapper;
import cn.itcast.mybatis.pojo.User;
public interface NewUserMapper extends Mapper<User> {
/**
* @param map
* 一個key是start,表示從哪一條開始查,另一個key是rows,表示每頁顯示的資料條數
* @return
*/
public List<User> queryUserByPage(Map<String, Integer> map);
}
(2)、建立NewUserMapper.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="cn.itcast.mybatis.mapper.NewUserMapper">
<!-- 根據id查詢使用者 -->
<select id="queryUserByPage" parameterType="map" resultType="user">
SELECT * FROM `user` LIMIT #{start},#{rows}
</select>
</mapper>
(3)、測試類中的程式碼
@Test
public void testQueryUserByPage() {
Map<String, Integer> map = new HashMap<>();
map.put("start", 2);
map.put("rows", 3);
List<User> list = this.newUserMapper.queryUserByPage(map);
for (User user : list) {
System.out.println(user);
}
}
2、使用分頁外掛後分頁的實現方法
注意:分頁外掛的使用文件在本部落格資原始檔的通用mapper壓縮包中
(1)、在sqlMapConfig.xml中配置分頁助手的配置
<!-- 配置分頁助手 -->
<plugin interceptor="com.github.pagehelper.PageHelper">
<property name="dialect" value="mysql" />
<!-- 該引數預設為false -->
<!-- 設定為true時,使用RowBounds分頁會進行count查詢 -->
<property name="rowBoundsWithCount" value="true" />
</plugin>
(2)、編寫測試類,測試分頁方法
/**
* 使用分頁助手進行分頁測試
*/
@Test
public void testQueryUserByPage2() {
// 設定分頁資料
// 第一個引數是從哪一頁開始查,第二引數是每頁顯示的資料條數
PageHelper.startPage(2, 4);
List<User> list = this.newUserMapper.select(null);
for (User user : list) {
System.out.println(user);
}
PageInfo<User> pageInfo = new PageInfo<>(list);
System.out.println("資料總條數:"+pageInfo.getTotal());
System.out.println("總頁數:"+pageInfo.getPages());
}
七、在淘淘商城專案中整合分頁外掛
1、匯入item表資料
2、在SqlMapConfig.xml中加入分頁助手和通用Mapper配置
<?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>
<!-- 注意:分頁助手的配置要在通用mapper之前 -->
<plugins>
<!-- 配置分頁助手 -->
<plugin interceptor="com.github.pagehelper.PageHelper">
<property name="dialect" value="mysql" />
<!-- 該引數預設為false -->
<!-- 設定為true時,使用RowBounds分頁會進行count查詢 -->
<property name="rowBoundsWithCount" value="true" />
</plugin>
<!-- 通用Mapper的攔截器配置方式 -->
<plugin interceptor="com.github.abel533.mapperhelper.MapperInterceptor">
<!--主鍵自增回寫方法,預設值MYSQL,詳細說明請看文件 -->
<property name="IDENTITY" value="MYSQL" />
<!--通用Mapper介面,多個通用介面用逗號隔開 -->
<property name="mappers" value="com.github.abel533.mapper.Mapper" />
</plugin>
</plugins>
</configuration>
3、匯入pojo
注意:所有的pojo在本部落格資原始檔中都有
4、編寫mapper介面和對映檔案
(1)、介面
package com.taotao.manager.mapper;
import com.github.abel533.mapper.Mapper;
import com.taotao.manager.pojo.ItemCat;
/**
* 商品類目的通用mapper
* @author Administrator
*
*/
public interface ItemCatMapper extends Mapper<ItemCat> {
}
(2)、對映檔案
5、編寫Service介面和實現類
(1)、介面
package com.taotao.manager.service;
import java.util.List;
import com.taotao.manager.pojo.ItemCat;
/**
* 商品類目業務層介面
* @author Administrator
*
*/
public interface ItemCatService {
/**
* 分頁查詢商品類目
* @param page
* @param rows
* @return
*/
public List<ItemCat> queryItemCatByPage(Integer page, Integer rows);
}
(2)、實現類
package com.taotao.manager.service.impl;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.github.pagehelper.PageHelper;
import com.taotao.manager.mapper.ItemCatMapper;
import com.taotao.manager.pojo.ItemCat;
import com.taotao.manager.service.ItemCatService;
/**
* 商品類目業務層實現類
* @author Administrator
*
*/
@Service
public class ItemCatServiceImpl implements ItemCatService {
@Autowired
private ItemCatMapper itemCatMapper;
/**
* 分頁查詢商品類目
*/
public List<ItemCat> queryItemCatByPage(Integer page, Integer rows) {
//設定分頁引數
PageHelper.startPage(page, rows);
//執行查詢
List<ItemCat> list = this.itemCatMapper.select(null);
return list;
}
}
6、編寫Web層程式碼
package com.taotao.manager.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import com.taotao.manager.pojo.ItemCat;
import com.taotao.manager.service.ItemCatService;
/**
* 商品類目的web層
* @author Administrator
*
*/
@Controller
@RequestMapping("/item/cat")
public class ItemCatController {
@Autowired
private ItemCatService itemCatService;
/**
* 分頁查詢商品類目
* @PathVariable:將url中的引數對映的方法引數中
* @RequestParam:將url中?號後面的引數對映到方法引數中
* @param page
* @param rows
* @return
*/
@RequestMapping(value="query/{page}")
@ResponseBody
public List<ItemCat> queryItemCatByPage(@PathVariable Integer page, @RequestParam(value="row") Integer rows){
//呼叫服務進行分頁查詢
List<ItemCat> list = this.itemCatService.queryItemCatByPage(page, rows);
return list;
}
}