创建一个简单MyBatis程序
文章目录
MyBatis基础
MyBatis 简介
(1)MyBatis是一个半自动映射框架,它需要用户手工匹配提供POJO、SQL和映射关系,并熟练地掌握SQL语言的编写,而不像Hibernate那种全表映射能自动地生成对应的SQL语句。
(2)MyBatis可以通过配置动态SQL并优化SQL语句来优化数据库操作性能,它还支持存储过程,而Hibernate无法做到这些。
(3)MyBatis以第三方包的形式提供,不像Hibernate本身是集成在Java EE开发的MyEclipse环境中的,故只能以.jar包的形式引入项目来使用。
创建一个MyBatis程序
1. 创建Java项目
在MyEclipse 2019中,创建Java项目,项目名为MybatisDemo。
SQL Server创建数据库TEST
建立userTable表
2. 加载MyBatis包
(1)访问MyBatis官网,网址为:https://github.com/mybatis/mybatis-3/releases ,
(2)下载得到文件mybatis-3.5.3.zip,解压,得到目录如图所示。
在该目录下首先看到的是MyBatis的核心包:
mybatis-3.5.3.jar
进一步点击进入lib子目录,可看到MyBatis框架的一些依赖包:
ant-1.9.6.jar
ant-launcher-1.9.6.jar
asm-5.2.jar
cglib-3.2.5.jar
commons-logging-1.2.jar
javassist-3.22.0-CR2.jar
log4j-1.2.17.jar
log4j-api-2.3.jar
log4j-core-2.3.jar
ognl-3.1.15.jar
slf4j-api-1.7.25.jar
slf4j-log4j12-1.7.25.jar
作为一个持久层框架,MyBatis最终还是要操作底层数据库的,故使用MyBatis的项目必然离不开数据库驱动包,操作SQL Server 2014的驱动包:
sqljdbc4.jar
(3)发布到类路径
右击项目名,选择【Build Path】→【Configure Build Path…】,进入【Properties for MybatisDemo】窗口,点击【Add JARs…】按钮,从弹出【JAR Selection】对话框中展开项目的目录树,选中lib目录下的全部.jar包,单击【OK】按钮,返回【Properties for MybatisDemo】窗口,再次单击【OK】按钮回到集成开发环境,操作如图所示。
完成以上步骤后,项目中增加了一个“Referenced Libraries”目录,展开可看到所有MyBatis的包都已被载入进来,此时项目的目录树呈现如图所示的状态,表明该项目已成功添加了MyBatis框架。
3. 编写POJO类和映射文件
(1)编写POJO类
项目src下创建包org.vo,添加编写UserTable类
UserTable.java代码为。
package org.vo;
public class UserTable { // 无须序列化POJO类
// Fields // 属性
private Integer id; // 对应表中 id 字段
private String username; // 对应表中 username 字段
private String password; // 对应表中 password 字段
// Constructors
/** default constructor */
public UserTable() {
}
/** full constructor */
public UserTable(String username, String password) {
this.username = username;
this.password = password;
}
// Property accessors // 上述各属性的get和set方法
public Integer getId() {
return this.id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUsername() {
return this.username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return this.password;
}
public void setPassword(String password) {
this.password = password;
}
}
(2)org.ov包下创建映射文件
映射文件UserTableMapper.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="org.vo.UserTableMapper">
<select id="fromUserTable" parameterType="Integer" resultType="org.vo.UserTable">
select * from userTable
</select>
<insert id="intoUserTable" parameterType="org.vo.UserTable">
insert into userTable(username, password) values(#{username}, #{password})
</insert>
<update id="updtUserTable" parameterType="org.vo.UserTable">
update userTable set username=#{username}, password=#{password} where id = #{id}
</update>
<delete id="deltUserTable" parameterType="Integer">
delete from userTable where id = #{id}
</delete>
</mapper>
4.创建mybatis-config.xml核心配置文件
在项目src下创建MyBatis框架的核心配置文件mybatis-config.xml,内容为:
mybatis-config.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>
<environments default="sqlsrv">
<environment id="sqlsrv">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.microsoft.sqlserver.jdbc.SQLServerDriver"/>
<property name="password" value="123456"/> <property name="username" value="sa"/>
<property name="url" value="jdbc:sqlserver://localhost:1433;databaseName=TEST"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="org/vo/UserTableMapper.xml"/>
</mappers>
</configuration>
5. 编写测试类
在src下创建包org.test,在该包下建立测试类,命名为MybatisTest.java,其代码如下:
package org.test;
import java.util.List;
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.vo.UserTable;
public class MybatisTest {
public SqlSession session;
public static void main(String[] args) {
MybatisTest mt = new MybatisTest(); //创建类对象
mt.getCurrentSession(); //获得session对象
mt.saveUser(); //插入一条记录
System.out.println("增加一条记录后结果======");
mt.queryUser(); //查看数据库结果
mt.updateUser(); //修改该条记录
System.out.println("修改该条记录后结果======");
mt.queryUser(); //查看数据库结果
mt.deleteUser(); //删除该条记录
System.out.println("删除该条记录后结果======");
mt.queryUser(); //查看数据库结果
mt.closeSession(); //关闭session
}
//获得session方法
public void getCurrentSession() {
try {
String resource = "mybatis-config.xml";
InputStream stream = Resources.getResourceAsStream(resource);
SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(stream);
session = sessionFactory.openSession();
} catch(Exception e) {
e.printStackTrace();
}
}
//关闭session方法
public void closeSession(){
if(session != null) {
session.close(); //关闭SqlSession
}
}
//插入一条记录方法
public void saveUser() {
UserTable user = new UserTable();
user.setUsername("Hello");
user.setPassword("123");
session.insert("org.vo.UserTableMapper.intoUserTable", user);
session.commit(); //提交事务
}
//修改这条记录方法
public void updateUser() {
UserTable user = new UserTable();
user.setId(1);
user.setUsername("Hi");
user.setPassword("321");
session.update("org.vo.UserTableMapper.updtUserTable", user);
session.commit();
}
//查询数据库结果方法
public void queryUser() {
try {
List list = session.selectList("org.vo.UserTableMapper.fromUserTable");
for(int i=0; i<list.size(); i++) {
UserTable user = (UserTable)list.get(i);
System.out.println(user.getUsername());
System.out.println(user.getPassword());
}
} catch(Exception e) {
e.printStackTrace();
}
}
//删除该条记录方法
public void deleteUser(){
session.delete("org.vo.UserTableMapper.deltUserTable", 1);
session.commit();
}
}
package org.test;
import java.util.List;
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.vo.UserTable;
public class MybatisTest {
public SqlSession session;
public static void main(String[] args) {
MybatisTest mt = new MybatisTest(); //创建类对象
mt.getCurrentSession(); //获得session对象
mt.saveUser(); //插入一条记录
System.out.println("增加一条记录后结果======");
mt.queryUser(); //查看数据库结果
mt.updateUser(); //修改该条记录
System.out.println("修改该条记录后结果======");
mt.queryUser(); //查看数据库结果
mt.deleteUser(); //删除该条记录
System.out.println("删除该条记录后结果======");
mt.queryUser(); //查看数据库结果
mt.closeSession(); //关闭session
}
//获得session方法
public void getCurrentSession() {
try {
String resource = "mybatis-config.xml";
InputStream stream = Resources.getResourceAsStream(resource);
SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(stream);
session = sessionFactory.openSession();
} catch(Exception e) {
e.printStackTrace();
}
}
//关闭session方法
public void closeSession(){
if(session != null) {
session.close(); //关闭SqlSession
}
}
//插入一条记录方法
public void saveUser() {
UserTable user = new UserTable();
user.setUsername("Jack");
user.setPassword("123456");
session.insert("org.vo.UserTableMapper.intoUserTable", user);
session.commit(); //提交事务
}
//修改这条记录方法
public void updateUser() {
UserTable user = new UserTable();
user.setId(1);
user.setUsername("Jacy");
user.setPassword("123456");
session.update("org.vo.UserTableMapper.updtUserTable", user);
session.commit();
}
//查询数据库结果方法
public void queryUser() {
try {
List list = session.selectList("org.vo.UserTableMapper.fromUserTable");
for(int i=0; i<list.size(); i++) {
UserTable user = (UserTable)list.get(i);
System.out.println(user.getUsername());
System.out.println(user.getPassword());
}
} catch(Exception e) {
e.printStackTrace();
}
}
//删除该条记录方法
public void deleteUser(){
session.delete("org.vo.UserTableMapper.deltUserTable", 1);
session.commit();
}
}
以上代码中首先通过getCurrentSession()方法获取session对象,MyBatis的session对象为SqlSession(位于框架的org.apache.ibatis.session包中),它是程序与持久层之间执行交互操作的一个单线程对象,该对象包含了数据库中所有执行SQL操作的方法,其底层已经封装了JDBC,可以直接使用其实例来执行映射文件中的SQL语句,代码中执行数据库操作的各条语句列出如下:
session.insert("org.vo.UserTableMapper.intoUserTable", user); //插入
session.update("org.vo.UserTableMapper.updtUserTable", user); //更新
List list = session.selectList("org.vo.UserTableMapper.fromUserTable"); //查询
session.delete("org.vo.UserTableMapper.deltUserTable", 1); //删除
6. 运行
项目结构:
MybatisTest.java 测试类也是包含主函数的类,可以直接按“Java Application”程序运行,运行后,控制台输出结果如图所示。
增加一条记录后结果======
Hello
123
修改该条记录后结果======
Hello
123
删除该条记录后结果======
Hello
123
MyBatis原理及工作流程
为了能够更加清晰地理解上面这个MyBatis程序,有必要再深入了解一下MyBatis的原理和工作流程,如图所示。
MyBatis配置入门
MyBatis的映射文件
MyBatis的映射文件名形如“*
Mapper.xml”,其中“*
”定义为要映射的POJO类名,例如MyBatisDemo的POJO类名为UserTable,故映射文件名就是UserTableMapper.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="org.vo.UserTableMapper">
<select id="fromUserTable" parameterType="Integer" resultType="org.vo.UserTable">
select * from userTable
</select>
<insert id="intoUserTable" parameterType="org.vo.UserTable">
insert into userTable(username, password) values(#{username}, #{password})
</insert>
<update id="updtUserTable" parameterType="org.vo.UserTable">
update userTable set username=#{username}, password=#{password} where id = #{id}
</update>
<delete id="deltUserTable" parameterType="Integer">
delete from userTable where id = #{id}
</delete>
</mapper>
在文件开头3行声明了“dtd”文件等约束配置信息,其余是需要用户编写的映射信息。
其中,<mapper>
是根元素,它包含一个namespace属性,该属性指定了命名空间,也就是此映射文件所在的完整包路径,MyBatisDemo的映射文件置于项目org.vo包下,故namespace属性值为“org.vo.UserTableMapper”。
根元素中配置了4个子元素,子元素中的信息就是用于执行SQL语句的配置,其id属性是每个子元素的唯一标识,也就是在主程序中传递给会话对象执行操作的字符串参数中的方法名;parameterType属性用来指定该子元素执行SQL时需要传入参数的类型,比如删除用户记录需要指定要删用户的id,该id以一个整型参数传入,故<delete>
元素的parameterType属性值为Integer;resultType属性用于指定返回结果的类型,比如查询用户得到的结果是以POJO对象的形式返回的,故<select>
元素的resultType属性为org.vo.UserTable(即用户POJO类)类型。
MyBatis核心配置文件
使用MyBatis必须配置它,需要用户手动创建MyBatis核心配置文件mybatis-config.xml。MyBatisDemo中该文件的内容为。mybatis-config.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> <environments default="sqlsrv"> <environment id="sqlsrv"> <transactionManager type="JDBC"/> <dataSource type="POOLED"> <property name="driver" value="com.microsoft.sqlserver.jdbc.SQLServerDriver"/> <property name="password" value="123456"/> <property name="username" value="sa"/> <property name="url" value="jdbc:sqlserver://localhost:1433;databaseName=TEST"/> </dataSource> </environment> </environments> <mappers> <mapper resource="org/vo/UserTableMapper.xml"/> </mappers></configuration>
与Hibernate类比
将MyBatis与Hibernate这两种持久层框架放在一起来看一看,会发现它们二者在使用和配置上存在着很大的相似性,如图所示。
MyBatis与Struts 2整合应用
整合原理
只须将原来系统中的Hibernate替换为MyBatis框架即可,前端Struts 2系统的结构无须改变,整合的原理如图所示。
应 用 案 例
1.清除Hibernate框架
(1)启动MyEclipse 2019,导入项目11bookManage。
(2)删除org.vo下的所有映射文件、org.util下的HibernateSessionFactory.java以及原Hibernate的核心配置文件hibernate.cfg.xml。
(3)右击项目名,选择【Build Path】→【Configure Build Path…】,进入【Properties for 11bookManage】窗口,选中“Hibernate 5.1 Libraries”条目,单击【Remove】按钮删除Hibernate的库目录,如图所示。
2.添加MyBatis框架
将MyBatis框架的类库复制到项目的\WebRoot\WEB-INF\lib路径下。在工作区视图中,右击项目名,从弹出菜单中选择【Refresh】刷新。打开项目树,展开“Web App Libraries”目录可看到原Struts 2与MyBatis的所有.jar包(一共是20个),如图所示,
表明MyBatis框架加载成功。
3.改写POJO类、创建映射文件
(1)接下来,对org.vo下的所有POJO类进行修改,非常简单,只须去掉每个POJO类名后的序列化语句“implements java.io.Serializable”即可。
(2)MyBatis的映射文件必须由用户手工创建和编写,如下。
11bookManage我们仅用MyBatis实现系统的“图书管理”功能,与之相关的两个POJO类为Login.java和Book.java,故这里只创建两个映射文件。
Login.java对应的映射文件LoginMapper.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="org.vo.LoginMapper">
<select id="fromLoginbyName" parameterType="String" resultType="org.vo.Login">
select * from login where name = #{name}
</select>
</mapper>
Book.java对应的映射文件BookMapper.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="org.vo.BookMapper">
<select id="fromBookbyIsbn" parameterType="String" resultType="org.vo.Book">
select * from book where ISBN = #{ISBN}
</select>
<insert id="intoBook" parameterType="org.vo.Book">
insert into book(ISBN, bookName, author, publisher, price, cnum, snum, summary, photo) values(#{ISBN}, #{bookName}, #{author}, #{publisher}, #{price}, #{cnum}, #{snum}, #{summary}, #{photo})
</insert>
<update id="updtBook" parameterType="org.vo.Book">
update book set bookName=#{bookName}, author=#{author}, publisher=#{publisher}, price=#{price}, cnum=#{cnum}, snum=#{snum}, summary=#{summary} where ISBN = #{ISBN}
</update>
<delete id="deltBook" parameterType="String">
delete from book where ISBN = #{ISBN}
</delete>
<update id="updtBookSnum" parameterType="org.vo.Book">
update book set snum=#{snum}-1 where ISBN = #{ISBN}
</update>
</mapper>
4.创建mybatis-config.xml核心配置文件
在项目src下创建MyBatis框架的核心配置文件mybatis-config.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>
<environments default="sqlsrv">
<environment id="sqlsrv">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.microsoft.sqlserver.jdbc.SQLServerDriver"/>
<property name="password" value="njnu123456"/>
<property name="username" value="sa"/>
<property name="url" value="jdbc:sqlserver://localhost:1433;databaseName=MBOOK"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="org/vo/BookMapper.xml"/>
<mapper resource="org/vo/LoginMapper.xml"/>
</mappers>
</configuration>
5.创建会话管理工具类
在项目org.util下编写MyBatisSessionFactory.java,代码如下:
package org.util;
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;
public class MyBatisSessionFactory {
private static SqlSessionFactory sessionFactory = null;
static{
try {
//根据配置文件生成SqlSessionFactory工厂
String resource = "mybatis-config.xml";
InputStream stream = Resources.getResourceAsStream(resource);
sessionFactory = new SqlSessionFactoryBuilder().build(stream);
} catch(Exception e) {
e.printStackTrace();
}
}
public static SqlSession getSession() {
return sessionFactory.openSession(); //返回获取的会话对象
}
}
6.修改持久层实现
(1)LoginDaoImpl.java代码修改如下:
package org.dao.impl;
import org.dao.LoginDao;
import org.apache.ibatis.session.SqlSession;
import org.util.MyBatisSessionFactory;
import org.vo.Login;
public class LoginDaoImpl implements LoginDao {
public Login checkLogin(String name, String password) {
Login login = null;
try {
//通过工具类MyBatisSessionFactory获取会话对象
SqlSession session = MyBatisSessionFactory.getSession();
//通过会话对象执行查询
login = session.selectOne("org.vo.LoginMapper.fromLoginbyName", name);
session.commit();
session.close();
if(!login.getPassword().equals(password)) login = null;
} catch(Exception e) {
e.printStackTrace();
}
return login;
}
}
(2)BookDaoImpl.java代码修改。
可以看到,以上代码的结构十分清晰、简洁,在进行数据库操作前,都是先通过工具类获取会话对象:
SqlSession session = MyBatisSessionFactory.getSession();
完成后,部署运行程序,就可实现对图书的增删改查操作。
12章 MyBatis基础
-《Java EE实用教程 (第3版)》是2018年电子工业出版社出版的图书,作者是郑阿奇。
创建一个简单MyBatis程序的更多相关文章
- 如何创建一个简单的struts2程序
如何创建一个简单的Struts2程序 “计应134(实验班) 凌豪” 1.创建一个新的Web项目test(File->new->Web Project) 2.Struts2框架的核心配置文 ...
- 使用ssm(spring+springMVC+mybatis)创建一个简单的查询实例(三)(错误整理篇)
使用ssm(spring+springMVC+mybatis)创建一个简单的查询实例(一) 使用ssm(spring+springMVC+mybatis)创建一个简单的查询实例(二) 以上两篇已经把流 ...
- 使用ssm(spring+springMVC+mybatis)创建一个简单的查询实例(二)(代码篇)
这篇是上一篇的延续: 用ssm(spring+springMVC+mybatis)创建一个简单的查询实例(一) 源代码在github上可以下载,地址:https://github.com/guoxia ...
- 使用ssm(spring+springMVC+mybatis)创建一个简单的查询实例(一)
梳理下使用spring+springMVC+mybatis 整合后的一个简单实例:输入用户的 ID,之后显示用户的信息(此次由于篇幅问题,会分几次进行说明,此次是工程的创建,逆向生成文件以及这个简单查 ...
- [WCF学习笔记] 我的WCF之旅(1):创建一个简单的WCF程序
近日学习WCF,找了很多资料,终于找到了Artech这个不错的系列.希望能从中有所收获. 本文用于记录在学习和实践WCF过程中遇到的各种基础问题以及解决方法,以供日后回顾翻阅.可能这些问题都很基础,可 ...
- 在 Visual Studio 中创建一个简单的 C# 控制台应用程序
转载:https://blog.csdn.net/qq_43994242/article/details/87260824 快速入门:使用 Visual Studio 创建第一个 C# 控制台应用 h ...
- 《Entity Framework 6 Recipes》翻译系列 (3) -----第二章 实体数据建模基础之创建一个简单的模型
第二章 实体数据建模基础 很有可能,你才开始探索实体框架,你可能会问“我们怎么开始?”,如果你真是这样的话,那么本章就是一个很好的开始.如果不是,你已经建模,并在实体分裂和继承方面感觉良好,那么你可以 ...
- 如何创建一个简单的C++同步锁框架(译)
翻译自codeproject上面的一篇文章,题目是:如何创建一个简单的c++同步锁框架 目录 介绍 背景 临界区 & 互斥 & 信号 临界区 互斥 信号 更多信息 建立锁框架的目的 B ...
- Windows 8.1 应用再出发 (WinJS) - 创建一个简单项目
前面几篇我们介绍了如何利用 C# + XAML 完成Windows Store App 功能的实现,接下来的几篇我们来看看如何利用 Html + WinJS 来完成这些功能. 本篇我们使用WinJS ...
随机推荐
- 哔哩哔哩批量采集器(支持windows和mac)
链接:https://pan.baidu.com/s/1jW2ea0Cl1xL5xN9DuB8Fcw 密码:klyw
- Android 11 源码下载+编译教程
下载AOSP源码 这里我使用的是外国语大学的镜像执行的下载,Mac系统的话,一定要在区分大小姐的磁盘下执行 repo init -u https://mirrors.bfsu.edu.cn/git/A ...
- B树——插入和删除
B树--插入和删除 B树的插入 5阶B数--结点关键字个数向上取整m/2-1≤n≤m-1 即2≤n≤4 连续插入5个元素后,超出来了. 在插入key后,若导致原结点关键字数超过上限,则从中间位置(m/ ...
- 浏览器开发者工具network详解
General概诉 请求链接 Request URL: 请求方式 Request Method: 代码状态 Status Code: 远程地址 Remote Address: 引用协议 用于过滤 Re ...
- Flutter InkWell - Flutter每周一组件
Flutter Inkwell使用详解 该文章属于[Flutter每周一组件]系列,其它组件可以查看该系列下的文章,该系列会不间断更新:所有组件的demo已经上传值Github: https://gi ...
- Yii 文件上传类的使用
https://segmentfault.com/a/1190000009674814 以上链接的文章已经写的很好了,一目了然,这里不再多做说明. 补充:当执行 UploadedFile->sa ...
- MySQL高可用方案-MySQL InnoDB Cluster
MySQL InnoDB Cluster简介 MySQL InnoDB Cluster 是最新GA的MySQL高可用方案,利用MySQL Group Replication和MySQL Shell.M ...
- Python朗读excel中的英文单词
安装win32com的时候出现了诸多问题,直接贴代码: 1 ''' 2 #利用python朗读excel里面的单词 3 ''' 4 5 #开始导入所需库 6 import xlrd 7 from bs ...
- 微信小说分销系统设计之使用百度Echarts地图统计功能统计微信粉丝地域分布情况
/** 转载请保留博客园原地址以及版权声明,请勿恶意修改,本博客中的内容均属于技术交流,请勿用于商业用途,谢谢配合 * 作者:杨浩瑞 QQ:1420213383 独立博客:http://www. ...
- Hive Hooks介绍
Hive作为SQL on Hadoop最稳定.应用最广泛的查询引擎被大家所熟知.但是由于基于MapReduce,查询执行速度太慢而逐步引入其他的近实时查询引擎如Presto等.值得关注的是Hive目前 ...