MyBatis(一) 概述与SQL定制、对象映射
个人博客网:https://wushaopei.github.io/ (你想要这里多有)
一、MyBatis概述
1、mybatis简介
MyBatis 是支持定制化 SQL、存储过程以及高级映射的优秀的持久层框架。
MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。
MyBatis可以使用简单的XML或注解用于配置和原始映射,将接口和Java的POJO(Plain Old Java Objects,普通的Java对象)映射成数据库中的记录.
2、mybatis历史
原是apache的一个开源项目iBatis, 2010年6月这个项目由apache software foundation 迁移到了google code,随着开发团队转投Google Code旗下,ibatis3.x正式更名为Mybatis ,代码于2013年11月迁移到Github(下载地址见后)。
iBATIS一词来源于“internet”和“abatis”的组合,是一个基于Java的持久层框架。iBATIS提供的持久层框架包括SQL Maps和Data Access Objects(DAO)
3、为什么要使用mybatis
MyBatis是一个半自动化的持久化层框架。
jdbc编程---当我们使用jdbc持久化的时候,sql语句被硬编码到java代码中。这样耦合度太高。代码不易于维护。在实际项目开发中会经常添加sql或者修改sql,这样我们就只能到java代码中去修改。
Hibernate和JPA
长难复杂SQL,对于Hibernate而言处理也不容易
内部自动生产的SQL,不容易做特殊优化。
基于全映射的全自动框架,javaBean存在大量字段时无法只映射部分字段。导致数据库性能下降。
对开发人员而言,核心sql还是需要自己优化
sql和java编码分开,功能边界清晰,一个专注业务、一个专注数据。
可以使用简单的XML或注解用于配置和原始映射,将接口和Java的POJO映射成数据库中的记录。成为业务代码+底层数据库的媒介
4、理解 SqlSession及其子父类的含义!
SqlSession的使用范围
- SqlSession中封装了对数据库的操作,如:查询、插入、更新、删除等。
- SqlSession通过SqlSessionFactory创建。
- SqlSessionFactory是通过SqlSessionFactoryBuilder进行创建。
SqlSessionFactoryBuilder
SqlSessionFactoryBuilder用于创建SqlSessionFacoty,SqlSessionFacoty一旦创建完成就不需要SqlSessionFactoryBuilder了,因为SqlSession是通过SqlSessionFactory创建的。所以可以将SqlSessionFactoryBuilder当成一个工具类使用,最佳使用范围是方法范围即方法体内局部变量。
SqlSessionFactory
SqlSessionFactory是一个接口,接口中定义了openSession的不同重载方法,SqlSessionFactory的最佳使用范围是整个应用运行期间,一旦创建后可以重复使用,通常以单例模式管理SqlSessionFactory。
SqlSession
SqlSession是一个面向用户的接口,sqlSession中定义了数据库操作方法。
每个线程都应该它自己的SqlSession实例。SqlSession的实例不能共享使用,它也是线程不安全的。因此最佳的范围是请求或方法范围。绝对不能将SqlSession实例的引用放在一个类的静态字段或实例字段中。
二、MyBatis的Hello示例程序
1、创建一个数据库和一个单表
drop database if exists mybatis;
create database mybatis;
use mybatis;
## 创建单表
####################################################################
create table t_user(
`id` int primary key auto_increment,
`last_name` varchar(50),
`sex` int
);
insert into t_user(`last_name`,`sex`) values('wsp168',1);
select * from t_user;
2、搭建mybatis开发环境
创建一个java工程
导 入 需 要 的 jar 包:
log4j-1.2.17.jar
mybatis-3.4.1.jar
mysql-connector-java-5.1.7-bin.jar
3、创建Pojo对象User
不调用接口方法,直接映射到xml文件中!
package com.webcode.pojo;
public class User {
private Integer id;
private String lastName;
private Integer sex;
。。。。。。。。。。
}
4、在src目录创建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="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/mybatis"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="com/webcode/pojo/UserMapper.xml"/>
</mappers>
</configuration>
配置文件代码获取方法
5、创建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">
<!--
namespace名称空间
取值一般有两种情况:
一种情况是:使用javaBean的全类名
二种情况是:使用Mapper接口的全类名
-->
<mapper namespace="com.webcode.pojo.User">
<!--
select标签用来配置一个select语句
id 用来配置一个唯一的标识
resultType 是查询完之后一条记录对应转换成为的javaBean对象
#{id}是占位符
-->
<select id="selectUserById" resultType="com.webcode.pojo.User">
select id,last_name lastName,sex from t_user where id = #{id}
</select>
</mapper>
6、传统mybatis的hello world 示例代码
package com.webcode.pojo.test;
import java.io.IOException;
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.Test;
import com.webcode.pojo.User;
public class UserTest {
@Test
public void testselectUserById() throws IOException {
//从配置文件读取指定的资源,以输入流的形式返回
InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
// 通过sqlSessionFactoryBuilder创建SqlSessionFactory(从输入流获取连接条件,创建连接工厂)
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
System.out.println(sqlSessionFactory);
//从工厂中获取一个连接(看成是数据库连接池即可),相当于 以前的Connection对象,每次用来都用关闭
SqlSession openSession = sqlSessionFactory.openSession();
try {
/*由相对路径映射到xml文件中的id,调动执行sql语句,
并以resultType定义的类型返回到请求端或者是客户端*/
User user = openSession.selectOne("com.webcode.pojo.User.selectUserById",1);
System.out.println(user);
} catch (Exception e) {
e.printStackTrace();
} finally {
openSession.close();//释放资源
}
}
}
打印结果: User [id=1, lastName=wsp168, sex=1]
代码流程:
关于Mybatis的配置文件提示功能:
关于log4j的提示:
如果不想看到,解决方案为:
只要在应用的classpath中创建一个名称为log4j.properties的文件, 文件的具体内容如下:
# Global logging configuration
log4j.rootLogger=ERROR, stdout
# MyBatis logging configuration...
log4j.logger.org.mybatis.example.BlogMapper=TRACE
# Console output...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n
注意:
7.加入log4j配置
导入‘log4j-1.2.17.jar’包
在工程下的config文件夹中创建 "log4j.properties"文件
\u4E0B\uFF1A
# Global logging configuration
log4j.rootLogger=DEBUG, stdout
# MyBatis logging configuration...
# Console output...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n
打印结果:
DEBUG [main] - Logging initialized using 'class org.apache.ibatis.logging.log4j.Log4jImpl' adapter.
DEBUG [main] - PooledDataSource forcefully closed/removed all connections.
DEBUG [main] - PooledDataSource forcefully closed/removed all connections.
DEBUG [main] - PooledDataSource forcefully closed/removed all connections.
DEBUG [main] - PooledDataSource forcefully closed/removed all connections.
org.apache.ibatis.session.defaults.DefaultSqlSessionFactory@61832929
DEBUG [main] - Opening JDBC Connection
DEBUG [main] - Created connection 1585787493.
DEBUG [main] - Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@5e853265]
DEBUG [main] - ==> Preparing: select id,last_name lastName,sex from t_user where id = ?
DEBUG [main] - ==> Parameters: 1(Integer)
DEBUG [main] - <== Total: 1
User [id=1, lastName=wsp168, sex=1]
DEBUG [main] - Resetting autocommit to true on JDBC Connection [com.mysql.jdbc.JDBC4Connection@5e853265]
DEBUG [main] - Closing JDBC Connection [com.mysql.jdbc.JDBC4Connection@5e853265]
DEBUG [main] - Returned connection 1585787493 to pool.
流程图解:
三、传统方式mybatis的增,删,改,查实现
1、UserDao:
package com.webcode.dao;
import java.util.List;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import com.webcode.pojo.User;
/**
* @author 鮀城小帅
* */
/**
*
* 注意:在创建连接时,底层自动对事务commit做了false定义,而没有提交的事务会自动回滚。
* 在执行CRUD时要手动提交事务,即,在执行语句后,session.commit();
* */
public class UserDao {
private SqlSessionFactory sqlSessionFactory;
/*
* 创建sql会话工厂方法
* */
public void setSqlSessionFactory(SqlSessionFactory sqlSessionFactory) {
this.sqlSessionFactory = sqlSessionFactory;
}
/*
* 根据id查询用户
* */
public User queryUserById(Integer id) {
SqlSession openSession = sqlSessionFactory.openSession();
try {
return openSession.selectOne("com.webcode.pojo.User.selectUserById",id);
} catch (Exception e) {
e.printStackTrace();
} finally {
openSession.close();//释放资源
}
return null;
}
/*
* 查询所有用户
* */
public List<User> queryUsers(){
SqlSession session = sqlSessionFactory.openSession();
try {
return session.selectList("com.webcode.pojo.User.queryUsers");
} catch (Exception e) {
e.printStackTrace();
} finally {
session.close();//释放资源
}
return null;
}
/*
* 添加用户
* */
public int saveUser(User user) {
SqlSession session = sqlSessionFactory.openSession();
try {
int result = session.insert("com.webcode.pojo.User.saveUser",user);
session.commit();//提交事务
return result;
} catch (Exception e) {
e.printStackTrace();
} finally {
session.close();//释放资源
}
return -1;
}
/*
* 根据id删除用户
* */
public int deleteUserById(Integer id) {
SqlSession openSession = sqlSessionFactory.openSession();
try {
int delete = openSession.delete("com.webcode.pojo.User.deleteUserById",id);
openSession.commit();//手动提交事务
return delete;
} catch (Exception e) {
e.printStackTrace();
} finally {
openSession.close();//释放资源
}
return -1;
}
/*
* 修改用户
* */
public int updateUser(User user) {
SqlSession openSession = sqlSessionFactory.openSession();
try {
int update = openSession.update("com.webcode.pojo.User.updateUsers",user);
openSession.commit();//手动提交事务
return update;
} catch (Exception e) {
// TODO: handle exception
}finally {
openSession.close();//释放资源
}
return -1;
}
}
2、编写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">
<!--
namespace名称空间
取值一般有两种情况:
一种情况是:使用javaBean的全类名
二种情况是:使用Mapper接口的全类名
-->
<mapper namespace="com.webcode.pojo.User">
<!--
select标签用来配置一个select语句
id 用来配置一个唯一的标识
resultType 是查询完之后一条记录对应转换成为的javaBean对象
#{id}是占位符
-->
<select id="selectUserById" resultType="com.webcode.pojo.User">
select id,last_name lastName,sex from t_user where id = #{id}
</select>
<!-- 查询全部的User对象 -->
<select id="queryUsers" resultType="com.webcode.pojo.User">
select id,last_name lastName,sex from t_user
</select>
<!-- parameterTypr参数类型(可选)
useGeneratedKeys="true" 使用(或返回)数据库生成的主键
keyProperty="id" 把数据库返回的主键值注入到bean对象的id属性中
-->
<insert id="saveUser" parameterType="com.webcode.pojo.User" >
<!--
selectKey标签可以定义一些查询语句,这些语句可以选择性地在大标签的sql语句之前或之后执行
我们希望,通过执行一个查询,把最后一次生成的id返回。
order属性配置执行的顺序
BEFORE 之前
AFTER 之后
keyProperty="id" 把数据库返回的主键值注入到bean对象的id属性中
resultType="int" 设置selectKey查询之后返回的类型是什么 int 表示Integer类型
-->
<selectKey order="AFTER" keyProperty="id" resultType="int">
select last_insert_id()
</selectKey>
insert into t_user (`last_name`,`sex`) values(#{lastName},#{sex})
</insert>
<!-- <insert id="saveUser" parameterType="com.webcode.pojo.User" -->
<!-- useGeneratedKeys="true" keyProperty="id"> -->
<!-- insert into t_user (`last_name`,`sex`) values(#{lastName},#{sex}) -->
<!-- </insert> -->
<!-- 根据id删除一个用户 -->
<delete id="deleteUserById" parameterType="int">
delete from t_user where id=#{id}
</delete>
<update id="updateUser" parameterType="com.webcode.pojo.User">
update t_user set last_name = #{lastName},sex=#{sex} where id=#{id}
</update>
</mapper>
映射关系图解:
3、编写UserDao测试
package com.webcode.dao.test;
import static org.junit.Assert.*;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.BeforeClass;
import org.junit.Test;
import com.webcode.dao.UserDao;
import com.webcode.pojo.User;
/**
* @author 鮀城小帅
* */
public class UserDaoTest {
private static UserDao userDao;
@BeforeClass
public static void setUpBeforeClass() throws Exception {
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder()
.build(Resources.getResourceAsStream("mybatis-config.xml"));
userDao = new UserDao();
userDao.setSqlSessionFactory(sqlSessionFactory);
}
@Test
public void testQueryUserById() {
System.out.println(userDao.queryUserById(1));
}
@Test
public void testQueryUsers() {
userDao.queryUsers().forEach(System.out::println);
}
@Test
public void testSaveUser() {
userDao.saveUser(new User(null, "xxx", 1));
}
@Test
public void testDeleteUserById() {
userDao.deleteUserById(3);
}
@Test
public void testUpdateUser() {
userDao.updateUser(new User(3,"aaa",0));
}
}
4、插入记录并返回主键
打印结果:
5、插入记录并返回主键
<!-- parameterType类型(可选) -->
<insert id="saveUser" parameterType="com.webcode.pojo.User" keyProperty="id" useGeneratedKeys="true" >
<!-- parameterType 参数类型(可选)
useGeneratedKeys="true" 使用(或返回)数据库生成的主键
keyProperty="id" 把数据库返回的主键值注入到bean对象的id属性中
-->
insert into t_user(`last_name`,`sex`) values(#{lastName},#{sex})
</insert>
6、标签的使用
<!-- parameterType类型(可选) -->
<insert id="saveUser" parameterType="com.webcode.pojo.User" >
<!--
selectKey标签可以定义一些查询语句,这些语句可以选择性地在大标签的sql语句之前或之后执行
我们希望,通过执行一个查询,把最后一次生成的id返回。
order属性配置执行的顺序
BEFORE 之前
AFTER 之后
keyProperty="id" 把数据库返回的主键值注入到bean对象的id属性中
resultType="int" 设置selectKey查询之后返回的类型是什么 int 表示Integer类型
-->
<selectKey order="AFTER" keyProperty="id" resultType="int">
select last_insert_id
</selectKey>
insert into t_user(`last_name`,`sex`) values(#{lastName},#{sex})
</insert>
四、Mapper 接口方式的 mybatis 的增,删,改,查实现
1、Mapper 接口编程的命名习惯
- JavaBean对象是 User
- Mapper接口的名称是: UserMapper
- sql语句的配置文件命名: UserMapper.xml
- JavaBean对象是 Book
- Mapper接口的名称是: BookMapper
- sql语句的配置文件命名: BookMapper.xml
2、Mapper接口开发有四个开发规范 必须遵守
1、名称空间必须是接口的全类名
2、方法名必须与id值一致
3、parameterType必须与方法参数类型一致
4、resultType必须与方法返回值一致(是指javaBean对象)
3、编写 Mapper 接口
public interface UserMapper {
public User queryUserById(Integer id);
public List<User> queryUsers();
public int saveUser(User user);
public int deleteUserById(Integer id);
public int updateUser(User user);
}
4、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名称空间值必须是Mapper接口的全类名
-->
<mapper namespace="com.webcode.mapper.UserMapper">
<!--
Mapper接口方案需要注意的第二点事项是:
方法名,必须要和id值一致
Mapper接口方案需要注意的第三点事项是:
返回值类型必须一致
Mapper接口方案需要注意的第四点事项是:
参数类型也必须一致(写就必须一致)
-->
<select id="queryUserById" resultType="com.webcode.pojo.User" parameterType="int">
select id,last_name lastName,sex from t_user where id = #{id}
</select>
<!-- public List<User> queryUsers(); -->
<select id="queryUsers" resultType="com.webcode.pojo.User">
select id,last_name lastName,sex from t_user
</select>
<!-- public int saveUser(User user);
普通类型可以忽略(主要是javaBean对象)
-->
<insert id="saveUser" parameterType="com.webcode.pojo.User" useGeneratedKeys="true" keyProperty="id">
insert into t_user(last_name,sex) values(#{lastName},#{sex})
</insert>
<!-- public int deleteUserById(Integer id); -->
<delete id="deleteUserById">
delete from t_user where id = #{id}
</delete>
<!-- public int updateUser(User user); -->
<update id="updateUser" parameterType="com.webcode.pojo.User">
update t_user set last_name = #{lastName},sex = #{sex} where id = #{id}
</update>
</mapper>
5、编写UserMapper测试
package com.webcode.mapper.test;
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 com.webcode.mapper.UserMapper;
import com.webcode.pojo.User;
import org.junit.BeforeClass;
import org.junit.Test;
public class UserMapperTest {
static SqlSessionFactory sqlSessionFactory;
@BeforeClass
public static void setUpBeforeClass() throws Exception {
sqlSessionFactory = new SqlSessionFactoryBuilder().build(Resources.getResourceAsStream("mybatis-config.xml"));
}
@Test
public void testQueryUserById() {
SqlSession session = sqlSessionFactory.openSession();
try {
UserMapper mapper = session.getMapper(UserMapper.class);
System.out.println(mapper.queryUserById(1));
} catch (Exception e) {
e.printStackTrace();
}finally {
session.close();
}
}
@Test
public void testQueryUsers() {
SqlSession session = sqlSessionFactory.openSession();
try {
UserMapper mapper = session.getMapper(UserMapper.class);
mapper.queryUsers().forEach(System.out::println);
} catch (Exception e) {
e.printStackTrace();
}finally {
session.close();
}
}
@Test
public void testSaveUser() {
SqlSession session = sqlSessionFactory.openSession();
try {
UserMapper mapper = session.getMapper(UserMapper.class);
int saveUser = mapper.saveUser(new User(null,"吴",11));
session.commit();
System.out.println(saveUser);
} catch (Exception e) {
e.printStackTrace();
}finally {
session.close();
}
}
@Test
public void testDeleteUserById() {
SqlSession openSession = sqlSessionFactory.openSession();
try {
UserMapper mapper = openSession.getMapper(UserMapper.class);
int deleteUserById = mapper.deleteUserById(2);
openSession.commit();
System.out.println(deleteUserById);
} catch (Exception e) {
e.printStackTrace();
}finally {
openSession.close();
}
}
@Test
public void testUpdateUser() {
SqlSession session = sqlSessionFactory.openSession();
try {
UserMapper mapper = session.getMapper(UserMapper.class);
int updateUser = mapper.updateUser(new User(1,"少",33));
session.commit();
System.out.println(updateUser);
}catch (Exception e) {
e.printStackTrace();
}finally {
session.close();
}
}
}
五、mybatis的核心配置之properties
<!--
properties标签可以用来定义多组键值对
每个property标签是一组键值对
properties标签还可以引入单独的属性配置文件
resource="jdbc.properties" 引入classpath路径下的jdbc.properties配置文件
源码目录,就是classPath路径
properties标签在引入外部属性配置文件和内部定义属性的时候。外部会替换掉内部定义的值。
-->
<properties resource="jdbc.properties">
<property name="url" value="jdbc:mysql://localhost:3306/mybatis"/>
<property name="username" value="root"/>
</properties>
MyBatis(一) 概述与SQL定制、对象映射的更多相关文章
- JAVAEE——Mybatis第二天:输入和输出映射、动态sql、关联查询、Mybatis整合spring、Mybatis逆向工程
1. 学习计划 1.输入映射和输出映射 a) 输入参数映射 b) 返回值映射 2.动态sql a) If标签 b) Where标签 c) Sql片段 d) Foreach标签 3.关联查询 a) 一对 ...
- java web(七): mybatis的动态sql和mybatis generator自动生成pojo类和映射文件
前言: MyBatis 的强大特性之一便是它的动态 SQL.如果你有使用 JDBC 或其它类似框架的经验,你就能体会到根据 不同条件拼接 SQL 语句的痛苦.例如拼接时要确保不能忘记添加必要的空格,还 ...
- MyBatis的核心配置、动态sql、关联映射(快速总结)
MyBatis的核心对象和配置 #1. SqlSessionFactory对象: 单个数据库映射关系经过编译的内存镜像: 作用:创建SQLSession对象. //读取配置文件 InputSteam ...
- MyBatis源码分析-SQL语句执行的完整流程
MyBatis 是支持定制化 SQL.存储过程以及高级映射的优秀的持久层框架.MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集.MyBatis 可以对配置和原生Map使用简 ...
- 深入理解MyBatis的原理(四):映射器的用法
前言:继续深入学习 mybatis 的用法及原理,还是先会用再学习原理. 映射器的主要元素有:select.insert.update.delete.parameterMap(即将被删除,不建议使用) ...
- MyBatis官方教程及源代码解析——mapper映射文件
缓存 1.官方文档 MyBatis 包括一个非常强大的查询缓存特性,它能够非常方便地配置和定制. MyBatis 3 中的缓存实现的非常多改进都已经实现了,使得它更加强大并且易于配置. 默认情况下是没 ...
- MyBatis注解配置动态SQL
MySQL创建表 DROP TABLE IF EXISTS `tb_employee`; CREATE TABLE `tb_employee` ( `id` int(11) NOT NULL AUTO ...
- Mybatis第六篇【配置文件和映射文件再解读、占位符、主键生成与获取、Mapper代理】
配置文件和映射文件再解读 映射文件 在mapper.xml文件中配置很多的sql语句,执行每个sql语句时,封装为MappedStatement对象,mapper.xml以statement为单位管理 ...
- 【mybatis深度历险系列】mybatis中的动态sql
最近一直做项目,博文很长时间没有更新了,今天抽空,学习了一下mybatis,并且总结一下.在前面的博文中,小编主要简单的介绍了mybatis中的输入和输出映射,并且通过demo简单的介绍了输入映射和输 ...
随机推荐
- leetCode刷题 | 两数之和
两数之和: 给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标. 你可以假设每种输入只会对应一个答案.但是,你不能重复利用这个数 ...
- 性能测试之数据库监控分析工具PMM
PMM(Percona Monitoring and Management) 是一个用于管理和监控数据库性能的开源平台. . 它能提供全面的基于时间和各类监控指标.计数器的分析. 性能测试中,是做数据 ...
- Vulnhb 靶场系列:Jarbas1.0
靶场镜像 官网 信息收集 攻击机kali IP地址 通过nmap 进行主机发现,发现目标机IP地址 nmap -sP 192.168.227.1/24 参数说明: -sP (Ping扫描) 该选项告诉 ...
- 单片机P0口
http://www.21ic.com/app/mcu/201307/186301.htm http://blog.csdn.net/zmq5411/article/details/6005977 h ...
- xml(3)
xml的解析方式:dom解析和sax解析 DOM解析 使用jaxp进行增删改查 1.创建DocumentBuilderFactory工厂 2.通过DocumentBuilderFactory工厂创建D ...
- flink基础篇
Flink面试--核心概念和基础考察 1.简单介绍一下 Flink 2.Flink 相比传统的 Spark Streaming 有什么区别? 3.Flink 的组件栈有哪些? 面试知识 ...
- neo4j企业版集群搭建
一.HA高可用集群搭建 版本采用的是neo4j-enterprise-3.5.3-unix.tar.gz 1.1.集群ip规划 192.168.56.10 neo4j-node1 192.168.56 ...
- vue打包 报错问题记录
1. assetsPublicPath: '/' 修改为 assetsPublicPath: './' 2. untils.js里面增加 publicPath: '../../' 重新运行 ...
- c# 贪吃蛇小游戏
------------恢复内容开始------------ 新手学习c# 在博客园上看到后自己模仿打出来的第一个程序 开心,纪念一下 bean :食物类 block :蛇块类 snake :蛇类 ...
- 2.6 Golang命令
在命令行执行go命令查看相关的Go语言命令: Go is a tool for managing Go source code. Usage: go command [arguments] The c ...