Java框架(一)--MyBatis入门

MyBatis入门

一、框架的作用

框架是可被应用开发者定制的应用骨架。
框架是一种规则,保证开发者遵循相同的方式开发程序。
框架提倡“不要重复造轮子”,对基础功能进行封装。

1、框架的优点

极大提升了开发效率。
统一的编码规则,利于团队管理。
灵活配置的应用,拥有更好的维护性。

二、什么是MyBatis

MyBatis是优秀的持久层框架。
MyBatis使用XML将SQL与程序解耦,便于维护。
MyBatis学习简单,执行高效,是JDBC的延伸。
官方中文文档:
https://mybatis.org/mybatis-3/zh/

1、MyBatis开发流程

引入MyBatis依赖
创建核心配置文件
创建实体(Entity)类
创建Mapper映射文件
初始化SessionFactory
利用SqlSession对象操作数据
在这里插入图片描述

三、Mybatis环境配置

1、引入MyBatis依赖

在pom.xml文件中

...
<dependency>
  <groupId>org.mybatis</groupId>
  <artifactId>mybatis</artifactId>
  <version>3.5.9</version>
</dependency>
<dependency>
  <groupId>mysql</groupId>
  <artifactId>mysql-connector-java</artifactId>
  <version>5.1.49</version>
</dependency>
...

2、mybatis-config.xml

MyBatis采用XML格式配置数据库环境信息。
MyBatis环境配置标签。
environment包含数据库驱动、URL、用户名与密码。
在这里插入图片描述

<?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="dev">
  	<!--配置环境,不同的环境不用的id名称-->
    <environment id="dev">
    	<!--采用JDBC方式对数据库事务进行commit/rollback-->
      <transactionManager type="JDBC"/>
      <!--采用连接池方式管理数据库连接-->
      <dataSource type="POOLED">
        <property name="driver" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost:3306/databaseName?useUnicode=true&amp;characterEncoding=UTF-8"/>
        <property name="username" value="root"/>
        <property name="password" value="root"/>
      </dataSource>
    </environment>
    <environment id="prd">
    	<!--采用JDBC方式对数据库事务进行commit/rollback-->
      <transactionManager type="JDBC"/>
      <!--采用连接池方式管理数据库连接-->
      <dataSource type="POOLED">
        <property name="driver" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://192.168.1.34:3306/databaseName?useUnicode=true&amp;characterEncoding=UTF-8"/>
        <property name="username" value="root"/>
        <property name="password" value="root"/>
      </dataSource>
    </environment>
  </environments>
  <mappers>
    <mapper resource="org/mybatis/example/BlogMapper.xml"/>
  </mappers>
</configuration>

四、SqlSessionFactory

SqlSessionFactory是MyBatis的核心对象
用于初始化MyBatis,创建SqlSession对象。
保证SqlSessionFactory在应用中全局唯一。

1、SqlSession

SqlSession是MyBatis操作数据库的核心对象。
SqlSession使用JDBC方式与数据库交互。
SqlSession对象提供了数据表CRUD对应方法。

...
//利用Reader加载classpath下的mybatis-config.xml核心配置文件
Reader reader = Resources.getResourceAsReader("mybatis-config.xml");
//初始化SqlSessionFactory对象,同时解析mybatis-config.xml文件
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
//创建SqlSession对象,SqlSession是JDBC的扩展类,用于与数据库交互
SqlSession sqlSession = null;
try{
	sqlSessionFactory.openSession();
	//创建数据库连接(测试用)
	Connection connection = sqlSession.getConnection();
}catch(Exception e){
	e.printStackTrace();
}finally{
	if(sqlSession!=null){
		//如果type="POOLED",代表使用连接池,close则是将连接回收到连接池中
		//如果type="UNPOOLED",代表直连,close则会调用Connection.close()方法关闭连接
		sqlSession.close();
	}
}
...

五、初始化工具类MyBatisUtils

为了保证SqlSessionFactory在应用中全局唯一,把初始化SqlSessionFactory对象的代码写在工具类中。

//NyBatisUtils工具类,创建全局唯一的SqlSessionFactory对象
public class NyBatisUtils{
	//利用static(静态)属于类不属于对象,且全局唯一
	public static SqlSessionFactory sqlSessionFactory = null;
	//利用静态快在初始化类时实例化sqlSessionFactory
	static {
		Reader reader = null;
		try{
			reader = Resources.getResourceAsReader("mybatis-config.xml");
			sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
		}catch(IOException e){
			e.printStackTrace();
			//初始化错误时,通过抛出异常ExceptionInInitializerError通知调用者
			throw new ExceptionInInitializerError(e);
		}
	}
	//openSession创建一个新的SqlSession对象
	public static SqlSession openSession(){
		return sqlSessionFactory.openSession();
	}
	//释放一个有效的SqlSession对象
	public static void closeSession(SqlSession session){
		if(sqlSession!=null){
		//如果type="POOLED",代表使用连接池,close则是将连接回收到连接池中
		//如果type="UNPOOLED",代表直连,close则会调用Connection.close()方法关闭连接
			sqlSession.close();
		}
	}
}

六、MyBatis数据查询

1、MyBatis数据查询步骤

创建实体类(Entity)
创建Mapper XML
编写SQL标签
开启驼峰命名映射
新增
SqlSession执行select语句

2、创建实体类(Entity)

public class Goods{
	private Integer goodsId;
	private String title;
	...
	public Integer getGoodsId(){
		return goodsId;
	}
	public void setGoodsId(Integer goodsId){
		this.goodsId = goodsId;
	}
	...
}

3、创建Mapper XML并编写SQL标签

在resources/mappers目录下创建goods.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命名空间,为了区分不同表的sql语句-->
<mapper namespace="goods">
	<!--id属性在同一个命名空间下值唯一-->
	<!--resultType返回类型,会把每一条记录包装成指定的类型-->
	<select id="selectAll" resultType="com.ql.mybatis.entity.Goods">
		select * from t_goods order by goods_id desc limit 10
	</select>
</mapper>

4、在mybatis-config.xml配置文件中添加并开启驼峰命名映射

<configuration>
	<settings>
		<!--goods_id ==> goodsId 驼峰命名转换-->
		<setting name="mapUnderscoreToCamelCase" value="true"/>
	</settings>
	...
	<!--在configuration标签里添加-->
	<mappers>
		<mapper resource="mappers/goods.xml">
	</mappers>
</configuration>

5、SqlSession执行select语句

SqlSession session = null;
try{
	session = MyBatisUtils.openSession();
	List<Goods> list = session.selectList("goods.selectAll");
}catch(Exception e){
	throw e;
}finally{
	MyBatisUtils.closeSession(session);
}

七、SQL传参

1、传递单参数:

在这里插入图片描述

Goods goods = session.selectOne("goods.selectById",1602);

2、传递多条参数时:

<select id="selectByPriceRange" parameterType="java.util.Map" resultType="com.ql.mybatis.entity.Goods">
	select * from t_goods
	where 
		current_price between #{min} and #{max}
	order by current_price
	limit 0,#{limt}
</select>
Map param = new HashMap();
param.put("min",100);
param.put("max",500);
param.put("limt",10);
//不加namespace前缀时保证id全局唯一
List<Goods> list = session.selectList("selectByPriceRange",param);

八、MyBatis获取多表关联查询结果

多表关联时resultType可以是Map(HashMap),但是结果没有顺序,建议使用LinkedHashMap,会按照数据库表字段顺序返回结果。

<!--利用LinkedHashMap保存多表关联结果
MyBatis会将每一条记录包装为LinkedHashMap对象
key是字段名 value是字段对应的值,字段类型根据表结构进行自动判断
优点:易于扩展,易于使用
缺点:太过灵活,无法进行编译时检查
-->
<select id="selectCoodsMap" resultType="java.util.LinkedHashMap">
	select g.* , c.category_name from t_goods g, t_category c 
	where g.category_id = c.category_id
</select> 

查询时返回Map的集合

List<Map> list = session.selectList("goods.selectGoodsMap");

九、ResultMap结果映射

ResultMap可以将查询结果映射为复杂类型的Java对象。
ResultMap适用于Java对象保存多表关联结果。
ResultMap支持对象关联查询等高级特性。
首先,创建结果映射对象:

//Data Transfer Object--数据传输对象
public class GoodsDTO{
	private Goods goods = new Goods();
	private String categoryName;
	public Goods getGoods(){
		return goods;
	}
	...
}
<!--结果映射-->
<resultMap id="rmGoods" type="com.ql.mybatis.dto.GoodsDTO">
	<!--设置主键字段与属性映射-->
	<id property="goods.goodsId" column="goods_id">
	<!--设置非主键字段与属性映射-->
	<result property="goods.title" column="title"></result>
	<result property="goods.categoryId" column="category_id"></result>
	<result property="categoryName" column="category_name"></result>
</resultMap>
<select id="selectCoodsDTO" resultMap="rmGoods">
	select g.* , c.category_name from t_goods g, t_category c 
	where g.category_id = c.category_id
</select>

十、MyBatis数据写入

1、数据库事务

数据库事务是保证数据操作完整性的基础。
在这里插入图片描述

2、MyBatis写操作包含三种

插入 - <insert>
更新 - <update>
删除 - <delete>

3、插入 - <insert>

在这里插入图片描述
last_insert_id() --MySQL函数,用于获取当前连接最后产生的id号,不会有并发问题。

//insert()方法返回值代表本次成功插入的记录总数
int num = session.insert("goods.insert", goods);
session.commit();//提交事务数据

4、selectKey与useGeneratedKeys的区别

selectKey标签用法:
在这里插入图片描述
useGeneratedKeys属性用法:
在这里插入图片描述
二者区别-显示与隐示
selectKey标签需要明确编写获取最新主键的SQL语句。
useGeneratedKeys属性会自动根据驱动生成对应的SQL语句。
二者区别-应用场景不同
selectKey适用与所有关系型数据库。
useGeneratedKeys只支持“自增主键”类型的数据库。
在Oracle中selectKey的用法
在这里插入图片描述

5、更新 - <update>

在这里插入图片描述

Goods goods = session.selectOne("goods.selectById", 739);
goods.setTile("更新标题");
int num = session.insert("goods.update", goods);
session.commit();//提交事务数据

6、删除 - <delete>

在这里插入图片描述

int num = session.delete("goods.delete", 739);
session.commit();//提交事务数据

十一、MyBatis预防SQL注入攻击

1、SQL注入攻击

SQL注入是指攻击者利用SQL漏洞,绕过系统约束,越权获取数据的攻击方式。
在这里插入图片描述

2、MyBatis两种传值方式

${}文本替换,未经过任何处理对SQL文本替换。
#{}预编译传值,使用预编译传值可以预防SQL注入。

/*
${}原文传值
select * from t_goods where title = '' or 1=1 
#{}预编译
select * from t_goods where title = "'' or 1=1"
*/

${}原文传值一般可以用到根据不同字段排序(order by)等代码传入的子句,而不能是外界输入的子句。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值