Mybatis适合新手快速入门

                                                                  

 

                               

目录

 

1.在学习Mybatis之前一定先要了解以下几点(很重要):

1.1什么是MyBatis?

2.MyBatis架构图

3.为什么要使用MyBatis?

4.Mybatis快速入门:

4.1准备数据,创建库和表

4.2创建工程,导入所需jar包、创建测试类

4.3导入junit、mysql、mybaits等开发包在pom.xml文件中引入相关依​​​​​

4.4添加mybatis-config,xml文件

4.5添加并编写User实体类

4.6添加userMapper.xml文件

4.7创建测试类,并测试!

5.Mybatis快速入门细节分析:

5.1mybaits-config.xml配置文件

5.2UserMapper.xml配置文件

6.Mybatis对数据库中的数据增删改查操作

6.1User表新增员工

6.2User表修改员工

6.3User表删除员工

7.#{} 和 ${} 占位符

8.常见的面试题

9.Mybatis进阶链接:


1.在学习Mybatis之前一定先要了解以下几点(很重要):

 

1.1什么是MyBatis?

  • 由来: Mybatis是apache的一个开源项目iBatis,2010年这个项目由这个组织(apache software foundation) 迁移到google code,并且改名MyBatis,2013年11月迁移到Github(GitHub 是一个面向开源及私有软件项目的托管平台)。

 

  • 具体功能:Mybatis是一个优秀的持久层框架,它对jdbc操作数据库的过程进行封装,使开发者只需关注SQL本身,而不需要花精力去处理例如:注册驱动,创建connection,创建statement等jdbc繁琐的过程代码(我会在本文后附加jdbc访问数据库操作的过程与代码)。

 

  • Mybatis是怎样访问数据库的:Mybatis通过xml或注解的方式将要执行的各种statement(statement,preparedStatement)配置起来,并通过java对象和statement中的sql进行映射生成最终执行的sql语句,最后由mybatis框架执行sql并将结果映射成java对象并返回。

 

注: 我们用的更多的传输器对象是PreparedStatement,PreparedStatement是Statement的子接口,比Statement更加安全,并且能够提高程序执行的效率。

记住这句话: 总之,Mybatis是对JDBC访问数据库的过程进行了封装,简化了JDBC代码(实际还是用的JDBC这门技术),解决了JDBC将结果集封装为Java对象的麻烦。

 

2.MyBatis架构图

 

1).mybatis-config.xml是Mybatis的核心配置文件,通过其中的配置可以生成SqlSessionFactory,也就是SqlSession工厂;

2).基于SqlSessionFactory可以生成SqlSession对象;

3).SqlSession是一个即可以发送Sql去执行,并返回结果;

4).Exectuor是SqlSession底层的对象,用于执行Sql语句;

5).MappedStatment对象也是SqlSession底层的对象,用于接收输入映射(sql语句的参数),以及做输出映射(即将SQL查询的结果映射成相应的结果)

 

 

3.为什么要使用MyBatis?

1.使用传统方式JDBC访问数据库:

1).使用JDBC访问数据库有大量重复代码(比如注册驱动,获取连接,获取传输器,释放资源等);

2).JDBC自身没有连接池,会频繁的创建连接和关闭连接,效率低;

3).SQL是写死在程序中,一旦修改SQL,需要对类重新编译;

4).对查询SQL执行后返回的ResultSet对象,需要手动处理;

5.)每次使用完毕后,还要释放资源;

2.使用mybatis框架访问数据库:

1).Mybatis对JDBC进行了封装,可以简化JDBC代码;

2).Mybatis自身支持链接池(关键它还可以配置其它的链接池),从而提高程序的效率;

3).Mybatis是将SQL配置在mapper文件中,修改SQL只是修改配置文件,类不需要重新编译;

4).对查询SQL执行后返回的ResultSet对象,Mybatis会帮我们处理,转换成Java对象;

 

4.Mybatis快速入门:

4.1准备数据,创建库和表

 

1、创建db库 user表,并插入若干条记录

-- 1、创建数据库 db 数据库

create database if not exists db charset utf8;

use db; -- 选择db数据库

-- 2、删除user表(如果存在)

drop table if exists user;

-- 3、在 yonghedb 库中创建 user表

create table user(

id int primary key auto_increment,

name varchar(50),

job varchar(50),

salary double

);

-- 4、往 user表中, 插入若干条记录

insert into user values(null, '诸葛亮', '程序员', 3300);

insert into user values(null, '黄忠', '程序员', 2800);

insert into user values(null, '赵云', '程序员鼓励师', 2700);

insert into user values(null, '张飞', '部门总监', 4200);

insert into user values(null, '关羽', '程序员', 3000);

insert into user values(null, '马超', '程序员', 3500);

insert into user values(null, '孙尚香', '程序员', 3700);

insert into user values(null, '周瑜', 'CEO', 5000);

 

4.2创建工程,导入所需jar包创建测试类

 

 

4.3导入junit、mysql、mybaits等开发包在pom.xml文件中引入相关依​​​​​

 

<dependencies>
		<!-- junit单元测试 -->
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>4.9</version>
		</dependency>
		<!-- mysql驱动 -->
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<version>5.1.32</version>
		</dependency>
		<!-- mybatis -->
		<dependency>
			<groupId>org.mybatis</groupId>
			<artifactId>mybatis</artifactId>
			<version>3.2.8</version>
		</dependency>
		<!-- 整合log4j -->
		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>slf4j-log4j12</artifactId>
			<version>1.6.4</version>
		</dependency>
	</dependencies>

 

  • 4.4添加mybatis-config,xml文件

说明:  在src/main/resources目录下,创建mybatis-config.xml文件(重点:mybatis的核心配置文件)

 

mybatis-config文件头信息如下:

<?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">


<!-- MyBatis的全局配置文件 -->

<configuration >



</configuration>

详细配置如下:


<?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">
	    
	<!-- MyBatis的全局配置文件 -->
	<configuration >
		<!-- 1.配置开发环境(需设置一个默认的环境) -->
		<environments default="develop">
			<!-- 这里可以配置多个环境,比如develop,test等 -->
			<environment id="develop">
				<!-- 1.1.配置事务管理方式:JDBC/MANAGED
				JDBC:将事务交给JDBC管理(推荐)
				MANAGED:自己管理事务
				  -->
				<transactionManager type="JDBC"></transactionManager>
				
				<!-- 1.2.配置数据源,即连接池方式:JNDI/POOLED/UNPOOLED
					JNDI:已过时
					POOLED:使用连接池(推荐)
					UNPOOLED:不使用连接池
				 -->
				<dataSource type="POOLED">
					<property name="driver" value="com.mysql.jdbc.Driver"/>
					<property name="url" value="jdbc:mysql://localhost:3306/yonghedb?characterEncoding=utf-8"/>
					<property name="username" value="root"/>
					<property name="password" value="root"/>
				</dataSource>
			</environment>
		</environments>

		<!-- 2.加载Mapper配置文件(因mapper文件中配置了要执行的SQL语句) -->
		<mappers>
			<!-- 注意路径 -->
			<mapper resource="UserMapper.xml"/>
		</mappers>
	</configuration>

4.5添加并编写User实体类

注意:在当前实例中,User类中的属性和数据库表的字段名称必须一致,否则将会无法将结果集封装到Java对象中。

在src/main/java目录下创建com.tedu.pojo.User类;

提供私有属性以及对应的getter方法、setter方法,并重写toString方法

package com.tedu.pojo;

/**
 * 实体类,用于封装User表中的一条用户信息
 */
public class User {
	//1.声明实体类中的属性
	private Integer id;
	private String name;
	private String job;
	private Double salary;
	public Integer getId() {
		return id;
	}
	public void setId(Integer id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getJob() {
		return job;
	}
	public void setJob(String job) {
		this.job = job;
	}
	public Double getSalary() {
		return salary;
	}
	public void setSalary(Double salary) {
		this.salary = salary;
	}
	@Override
	public String toString() {
		return "User [id=" + id + ", name=" + name + ", job=" + job + ", salary=" + salary + "]";
	}
	
	
}

 

4.6添加userMapper.xml文件

1.在src/main/resources目录下,创建UserMapper.xml文件 (实体类的映射文件)

2.UserMapper.xml文件配置如下:

UserMapper文件头信息如下:

<?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">

 

详细配置如下:

<?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一般指定为当前文件的所在的文件名(将来是接口的全限定类名)
		在程序中通过[ namespace + id ]定位到执行哪一条SQL语句
	 -->
	<mapper namespace="UserMapper">
	  
	  <!-- 通过select、insert、update、delete标签声明要执行的SQL -->
		<!-- 练习1: 查询user表中的所有员工信息
			resultType指定查询的结果将会封装到什么类型中 -->
		<select id="findAll" resultType="com.tedu.pojo.User">
		  select * from user
		</select>
		
	  <!-- 
		resultType:返回值类型,简单类型(例如:Integer,String,User等)
			如果返回集合(List<User>),只需配置集合中的元素类型即可!
		-->
		
</mapper>

 

4.7创建测试类,并测试!

 

1.创建com.tedu.mybatis.TestMybatis测试类,并提供findAll方法(查询user表中所有的员工信息),开发步骤如下:

 

 

2.实现findAll方法,代码如下:

这里写代码的时候,可以想想mybatis它的架构图

public class TestMybatis {

	/** 练习1(快速入门):  查询User表中的所有员工, 返回一个List<User>集合
	 * @throws IOException */

	@Test
	public void findAll() throws IOException{

		/**
		 * 写代码首先思路清晰,知道自己要实现什么;
		 * 需求:查询出数据库的User表中的员工信息;
		 * 返回值:List<User>;
		 * 实现步骤:
		 * 第一步:读取Mybatis的全局配置文件,从中还要加载UserMapper.xml文件
		 * 第二步:通过Mybatis的全局配置文件,创建SqlSessionFactory工厂对象
		 * 第三步:通过SqlSessionFactory工厂对象,创建一个SqlSession会话对象
		 * 第四步:通过SqlSession会话对象执行数据库操作
		 * 第五步:提交事务
		 * 第六步:关闭连接
		 */

		//第一步:读配置文件需要io流
		InputStream in = Resources.getResourceAsStream("mybatis-config.xml");         

		//第二步:
		SqlSessionFactory fac = new SqlSessionFactoryBuilder().build(in);

		//第三步:
		SqlSession session = fac.openSession();

		//第四步:这里就写命名空间+id
		List<User> list = session.selectList("UserMapper.findAll");
		for (User user : list) {
			System.out.println(user);
		}

        //第五步:这里是查询,所以不用提交事务
		
		//第六步:
		session.close();

	}

}

 

3.执行findAll方法,输出结果为:

 


5.Mybatis快速入门细节分析:

5.1mybaits-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">
	    
	<!-- MyBatis的全局配置文件 -->
	<configuration >
		<!-- 1.配置开发环境(需设置一个默认的环境) -->
		<environments default="develop">
			<!-- 这里可以配置多个环境,比如develop,test等 -->
			<environment id="develop">
				<!-- 1.1.配置事务管理方式:JDBC/MANAGED
				JDBC:将事务交给JDBC管理(推荐)
				MANAGED:自己管理事务
				  -->
				<transactionManager type="JDBC"></transactionManager>
				
				<!-- 1.2.配置数据源,即连接池方式:JNDI/POOLED/UNPOOLED
					JNDI:已过时
					POOLED:使用连接池(推荐)
					UNPOOLED:不使用连接池
				 -->
				<dataSource type="POOLED">
					<property name="driver" value="com.mysql.jdbc.Driver"/>
					<property name="url" value="jdbc:mysql://localhost:3306/yonghedb?characterEncoding=utf-8"/>
					<property name="username" value="root"/>
					<property name="password" value="root"/>
				</dataSource>
			</environment>
		</environments>

		<!-- 2.加载Mapper配置文件(因mapper文件中配置了要执行的SQL语句) -->
		<mappers>
			<!-- 注意路径 -->
			<mapper resource="UserMapper.xml"/>
		</mappers>
	</configuration>
  • configuration 是根标签,当前文件中所有的配置都在该标签内,注意其中配置的关键点:

(1)environments标签:

该标签内部可以配置多个environment,即多种环境,每种环境可以做不同的配置或链接不同数据库,例如:开发,测试,生产环境可能需要不同的配置,链接的数据库可能也不相同,因此我们可以配置三个environment,分别对应上面三种不同的环境;

但是要记住,environment可以配置多个,但是最终要使用的只能是其中一个!

(2)environment标签: 

内部可以配置多种配置信息,下面介绍事务管理配置.和数据源配置:

(3)transactionManage标签:

事务管理配置,mybatis中有两种事务管理方式,也就是type="[ JDBC|MANAGED]"

JDBC:这个配置就是直接使用了JDBC的提交和回滚设置,它依赖于数据源得到的连接来管理事务范围,推荐使用

MANAGED:这个配置几乎没做什么。它从来不提交或回滚一个连接。需要自己手动添加并管理。不推荐使用。

(4)datasource标签:

数据源,也就是连接池配置,这里type指定数据类型,有三种类型:JNDI,POOLED,UNPOOLED

JNDI:已过时,不推荐使用!

POOLED:使用连接池,mybatis会创建连接池,并从连接池中获取连接访问数据库,在操作完成之后,将会把连接返回连接池!

UNPOOLED:不使用连接池,该方式适用于只有小规模数量并发用户的简单应用程序上。

(5)mappers标签: 

用于导入mapper文件的位置,其中可以配置多个mapper,即可以导入多个mapper文件;

 

5.2UserMapper.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一般指定为当前文件的所在的文件名(将来是接口的全限定类名)
		在程序中通过[ namespace + id ]定位到执行哪一条SQL语句
	 -->
	<mapper namespace="UserMapper">
	  
	  <!-- 通过select、insert、update、delete标签声明要执行的SQL -->
		<!-- 练习1: 查询user表中的所有员工信息
			resultType指定查询的结果将会封装到什么类型中 -->
		<select id="findAll" resultType="com.tedu.pojo.User">
		  select * from user
		</select>
		
	  <!-- 
		resultType:返回值类型,简单类型(例如:Integer,String,User等)
			如果返回集合(List<User>),只需配置集合中的元素类型即可!
		-->
		
</mapper>

(1)第1行是xml的文档声明,用于声明xml的版本和编码

(2)第2、3、4行,引入了xml约束文档,当前xml文档将会按照mybatis-3-mapper.dtd文件所要求的规则进行书写。

(3)Mapper标签: 根标签,其中namespace(名称空间,也叫命名空间),要求不能重复,其实就是一个名称,一般我们指定为("包名+文件名").

(4)select标签:用于指定将来要执行的各种SQL语句。标签上可以声明属性,下面介绍常用的属性:idresultTyperesultMap

id属性:要求值不能重复。将来在执行SQL时,可以通过namespace + id找到指定SQL并执行。

resultType属性:从这条SQL语句中返回所期望类型的类的完全限定名称(包名+类名)。注意如果是集合情形,那应该是集合可以包含的类型,而不能是集合本身。

简而言之,resultType控制查询SQL执行后返回值的类型或集合中的泛型,例如查询User表中的单条记录,返回值是一个User对象,因此,resultType="com.tedu.pojo.User";

如果查询User表中的多条记录,返回值是一个List<User>,此时resultType的值应该集合中的泛型,因此resultType="com.tedu.pojo.User";

resultMap属性:复杂对象结构(例如多表关联查询等)。 使用 resultType 或 resultMap,但不能同时使用。


6.Mybatis对数据库中的数据增删改查操作

6.1User表新增员工

1、编辑UserMapper.xml文件, 添加新增员工对应的sql.

<!-- 练习2: 新增员工信息: 刘德华 歌手 888

增删改的标签上不用指定resultType, 因为返回值都是int类型

 -->

<update id="insert" >

insert into user value(null, '刘德华', '歌手', 888)

</update>

2、编写TestMybatis类,添加testInsert方法,实现新增员工操作。

/** 练习2: 新增员工信息: 刘德华 歌手 888 */
@Test
public void testInsert() { 
	//执行sql语句, 返回执行结果
	int rows = session.update("UserMapper.insert");
	//提交事务
	session.commit();
	System.out.println("影响的行数: "+rows);
}

 

6.2User表修改员工

1、编辑UserMapper.xml文件, 添加新增员工对应的sql.

<!-- 练习3:修改员工信息 -->
<update id="update">
	update user set job='歌手&演员', salary=8888 where name='刘德华'
</update>

2、编写TestMybatis类,添加testUpdate方法,实现修改员工信息。

/** 练习3: 修改员工信息, 将刘德华的job改为'歌手&演员' 
 * 		salary改为88888 */
@Test
public void testUpdate() { }
	//执行sql语句, 返回执行结果
	int rows = session.update("UserMapper.update");
	//提交事务
	session.commit();
	System.out.println("影响行数:"+rows);
}

6.3User表删除员工

1、编辑UserMapper.xml文件, 添加新增员工对应的sql.

<update id="delete">

delete from user where name='刘德华'

</update>

2、编写TestMybatis类,添加testDelete方法,实现删除员工。

/** 练习4: 删除name为'刘德华'的记录 */
@Test
public void testDelete() {
	//执行sql语句, 返回执行结果
	int rows = session.update("UserMapper.delete");
	//提交事务
	session.commit();
	System.out.println("影响行数:"+rows);
}

7.#{} 和 ${} 占位符

我们先做几个练习,从实践中总结,这样不容易遗忘!

说明: 在上面的增删改查操作中,SQL语句中的值是写死在SQL中,而在实际开发中,此处的值往往是用户提交过来的值,因此这里我们需要将SQL中写死的值替换为占位符。

使用占位符完成上面的增删改查练习:

练习5、查询:查询指定id的员工信息

mapper文件配置:

<select id="findById"  resultType="com.tedu.pojo.User">
	select * from user where id=#{id}
</select>
java代码示例:
/** 练习5: 查询User表中指定id的员工信息 */
@Test
public void testFindById() {
	//执行sql语句, 返回执行结果
	User user = session.selectOne(
			"UserMapper.findById", 1 );
	System.out.println( user);
}

练习6、往User表中添加一个新员工 

mapper文件配置:
<!-- 练习6: 新增员工信息: 小乔 Java开发工程师 15000
    如果通过map集合传输参数, 需要保证占位符中的变量名
    和map集合中的key保持一致
    

如果通过pojo对象传输参数, 需要保证占位符中的变量名
    和对象中的属性名保持一致, 或者在pojo中有对应的
    getXxx方法

<insert id="insert2">
	insert into user values
	(null, #{name}, #{job}, #{salary})
</insert>
java代码示例:
/** 练习6: 新增员工信息: 小乔 Java开发工程师 15000 */
@Test
public void testInsert2() {
	//将要传输的参数封装到map集合中
	//Map map = new HashMap();
	//map.put("name", "小乔");
	//map.put("job", "Java开发工程师");
	//map.put("salary", 15000);
	
	//也可以将要传输的参数封装到User对象中
	User user = new User();
	user.setName("小乔");
	user.setJob("保安");
	iser.setSalary(8000.0);
	//执行sql语句
	int rows = session.update("UserMapper.insert2", user);
	//提交事务
	session.commit();
	System.out.println( "影响的行数: "+rows );
}

练习7:修改员工信息: 张飞 架构师 25000

mapper文件配置:
<!-- 练习7: 修改员工信息: 张飞 架构师 25000 -->
<update id="update2">
	update user set job=#{job}, salary=#{salary} 
	where name=#{name}
</update>

 

java代码示例:
/** 练习7: 修改员工信息: 张飞 架构师 25000 */
@Test
public void testUpdate2() { 
	//将参数封装到User对象中
	User user =nwe User();
	user.setName("张飞");
	user.setJob("架构师");
	user.setSalary(25000.0);
	//执行sql语句
	int rows = session.update("UserMapper.update2", user);
	//提交事务
	session.commit();
	System.out.println("影响的行数: "+rows);
}

练习8:删除指定id的员工信息

mapper文件配置:
<!-- 练习8:删除User表中指定id的员工信息 -->
<insert id="delete2" parameterType="String">
	delete from User where id=#{id}
</insert>

 

总结:# {} 和 ${} 占位符

在上面的增删改查练习中,当SQL语句中包含的参数值是传递过来的,在SQL语句中我们会通过 #{} 占位符进行占位,在SQL语句真正执行时,再将传递过来的值替换SQL语句中的占位符。

其实,#{} 就是JDBC中的问号(?)占位符,因此为了安全考虑,在执行时会对传递过来的值进行转译处理。

例如:查询指定name的员工信息,SQL语句为:

select * from user  name=#{name};

其实就等价于JDBC中: select * from user where name=?,如果传过来的参数值为小乔,那么最终执行的SQL语句为:

select * from user where name='小乔';


那么如果我们在传递的时候不是一个参数值,而是一个SQL片段呢?

例如在查询时,我们想动态的传递查询的列:

select 查询的列?? from user;

此时传递过来的应该是一个SQL片段,不同于上面的参数值,如果此时还用 #{},也会像上面一样被转译处理,这不是我们希望看到的。

如果不想让传过来的SQL片段被转译处理,而是拼接在SQL语句中,那么这里可以使用 ${},例如:

select ${columns} from user;

做几个练习,就明白了:

示例1:查询User表中所有员工的名称(name)、职位(job):

mapper文件配置:
<!-- 练习9: 动态显示要查询的列 -->
<select id="findAll2"  resultType="com.tedu.pojo.User">
	select  ${cols}  from user
</select>
java代码示例:
/** 练习9: 动态显示要查询的列 
 * 		select name, job from user*/
@Test
public void testFindAll2() {
	Map map = new HashMap();	
	map.put("cols", "name,job");
	//执行sql语句, 返回结果
	List<User> list = session.selectList(
					"UserMapper.findAll2", map);
	//输出结果
	for ( User user : list ) {
		System.out.println( user);
	}
}

示例2: 根据name模糊查询user表

mapper文件配置:
<!-- 练习10: 根据name模糊查询user表 -->
<select id="findAll3"  resultType="com.tedu.pojo.User">
     select  *  from  user
     where  name  like  '%${name}%'
</select>


java代码示例:
/** 
 * 练习10: 根据name模糊查询user表
 * '%黄%'  '%张%'
 */
@Test
public void testFindAll3() {
	//将参数封装到map集合中
	Map map = new HashMap();
	map.put("name", "黄");
	//执行sql, 返回结果
	List<User> list = session.selectList(
				"UserMapper.findAll3", map);
	//输出结果
	for (User user : list) {
		System.out.println( user);
	}
}

8.常见的面试题

做到这,想必你已经对mybatis的基本操作有了更深的认识,下面咱们趁热打铁,来看下面的面试题?

第一题 :

面试官: 说一说#{ } 与 $ { }的区别?

答:

1). #{}是占位符,预编译处理;${}是拼接符,字符串替换,没有预编译处理。

2). Mybatis在处理#{}时,#{}传入参数是以字符串传入,会将SQL中的#{}替换为?号,调用PreparedStatement的set方法来赋值。

3). 变量替换后,#{} 对应的变量自动加上单引号 ‘’;变量替换后,${} 对应的变量不会加上单引号 ‘’

4). #{} 可以有效的防止SQL注入,提高系统安全性;${} 不能防止SQL 注入

第二题:

面试官: 什么是 SQL 注入攻击?

答:

首先我们得知道什么是 SQL 注入攻击,官方一点的说法是这样的:

所谓SQL注入,就是通过把SQL命令插入到Web表单提交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令。

 

第三题:

面试官: 举一个sql注入攻击的例子?

答:

例如:

普通查询:

面试官问你 SQL 注入攻击了吗?

恶意查询:

面试官问你 SQL 注入攻击了吗?

 

综上述图片,我们发现:

普通查询中,我们传入的查询数据为 1,恶意查询中,我们传入的数据为:-1 OR 1=1

在这个语句中 id=-1 一般为 False,而 1=1 却恒为 true,所以这个查询语句能查询到所有结果,这是与我们编程的初衷相违背的。

第四题:

面试官:我们该如何防止SQL注入攻击呢?

答:

(1)使用正则表达式对用户提交的参数进行校验。

例如:通过正则表达式检查用户名和密码中是否包含(#、-- 、or、and等符号),如果包含,就直接结束程序,通知用户,用户名或密码输入不合法!

(2)使用PreparedStatement对象来替代Statement对象。

使用PreparedStatement对象是如何防止SQL注入攻击的:先将SQL骨架发送给服务器,预编译以后,随后传过来的参数只会当做普通文本,不会影响到sql语句本身;

 

第五题:

面试官:  mybatis中的#{} 为什么能防止sql注入,${}不能防止sql注入

答:

#{}在mybatis中的底层是运用了PreparedStatement 预编译,传入的参数会以 ? 形式显示,因为sql的输入只有在sql编译的时候起作用,当sql预编译完后,传入的参数就仅仅是参数,不会参与sql语句的生成

而${}则没有使用预编译,传入的参数直接和sql进行拼接,由此会产生sql注入的漏洞。

 



9.Mybatis快速进阶链接:

https://blog.csdn.net/weixin_46034322/article/details/106162486


感谢您的阅读,努力成为习惯,优秀自成常态!

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值