JDBC
JDBC 就是使用Java语言操作关系型数据库的一套API
全称:( Java DataBase Connectivity ) Java 数据库连接
JDBC中定义了所有操作关系型数据库的规则。众所周知,接口是无法直接使用的,我们需要使用接口的实现类,而这套实现类(称之为:驱动)就由各自的数据库厂商给出。
- 我们可以使用这套接口(JDBC)编程,真正执行的代码是驱动 jar包中的实现类
- 以后编写操作数据库的代码只需要面向JDBC(接口),操作哪儿个 关系型数据库就需要导入该数据库的驱动包,如需要操作MySQL数 据库,就需要再项目中导入MySQL数据库的驱动包。如下图就是 MySQL驱动包
SQL注入
SQL注入是通过操作输入来修改事先定义好的SQL语句,用以达到执行代码对服务器进行攻击的方法。
PreparedStatement
PreparedStatement 好处:
- 预编译SQL,性能更高
- 性能高: 检查SQL和编译SQL花费的时间比执行SQL的时间还要长。如果我们只是重新设置参数,那么检查SQL语句和编译SQL语句将不需要重复执行。这样就提高了性能。
- 开启预编译功能: 在代码中编写url时需要加上useServerPrepStmts=true (因为预编译功能默认是关闭的)
- 防止SQL注入:==将敏感字符进行转义==
// SQL语句中的参数值,使用?占位符替代
String sql = "select * from user where username = ? and password = ?";
// 通过Connection对象获取,并传入对应的sql语句
PreparedStatement pstmt = conn.prepareStatement(sql);
- 设置参数值
setXxx(参数1,参数2); Xxx:数据类型 ;
如 setInt (参数1,参数2)
// 设置?的值
pstmt.setString(1,name);
pstmt.setString(2,pwd);
// 执行sql
连接池DataSource
数据库连接池是个容器,负责分配、管理数据库连接(Connection)
它允许应用程序重复使用一个现有的数据库连接,而不是再重新建立一个;
释放空闲时间超过最大空闲时间的数据库连接来避免因为没有释放数据库连接而引起的数据库连接遗漏
连接池的实现
接口:==DataSource==
通过连接池(DataSource)获取 Connection 对象。
Druid连接池的使用
- 导入jar包 druid-1.1.12.jar
- 定义配置文件 druid.properties
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql:///db1?useSSL=false&useServerPrepStmts=true
username=root
password=1234
# 初始化连接数量
initialSize=5
# 最大连接数
maxActive=10
# 最大等待时间
maxWait=3000
- 加载配置文件
- 获取数据库连接池对象
- 获取连接
//3. 加载配置文件
Properties prop = new Properties();
prop.load(new FileInputStream("jdbc-demo/src/druid.properties"));
//4. 获取连接池对象
DataSource dataSource = DruidDataSourceFactory.createDataSource(prop);
//5. 获取数据库连接 Connection
Connection connection = dataSource.getConnection();
System.out.println(connection); //获取到了连接后就可以继续做其他操作了
仓库
jar包的查找顺序: 本地仓库 --> 远程仓库--> 中央仓库
Maven的项目结构
IDEA使用Maven
IDEA配置Maven环境
我们需要先在IDEA中配置Maven环境:
- 选择 IDEA中 File --> Settings
- 搜索 maven
- 设置 IDEA 使用本地安装的 Maven,并修改配置文件路径
IDEA 创建 Maven项目
- 创建模块,选择Maven,点击Next
- 填写模块名称,坐标信息,点击finish,创建完成
创建好的项目目录结构如下:
- 编写 HelloWorld,并运行
配置 Maven-Helper 插件
- 选择 IDEA中 File --> Settings
- 选择 Plugins
- 搜索 Maven,选择第一个 Maven Helper,点击Install安装,弹出面板中点击Accept
- 重启 IDEA
安装完该插件后可以通过 选中项目右键进行相关命令操作,如下图所示:
快捷方式导入jar包的坐标:
每次需要引入jar包,都去对应的网站进行搜索是比较麻烦的,接下来给大家介绍一种快捷引入坐标的方式
- 在 pom.xml 中 按 alt + insert,选择 Dependency
- 在弹出的面板中搜索对应坐标,然后双击选中对应坐标
- 点击刷新按钮,使坐标生效
MyBatis
- MyBatis 是一款优秀的==持久层框架==,用于简化 JDBC 开发
持久层:
- 负责将数据到保存到数据库的那一层代码。
框架:
- 框架就是一个半成品软件,是一套可重用的、通用的、软件基础代码模型
- 在框架的基础之上构建软件编写更加高效、规范、通用、可扩展
MyBatis优化
- 硬编码可以配置到==配置文件==
- 操作繁琐的地方mybatis都==自动完成==
如图所示
下图是持久层框架的使用占比。
MyBatis操作步骤
- 添加mybatis依赖
- 创建logback的配置文件(under resources folder)
- 编写 MyBatis 核心配置文件(mybatis-config.xml under resources folder)
- 编写 SQL 映射文件 (UserMapper.xml under resources folder)
- 编码
- 在
com.itheima.pojo包下创建 User类 - 在
com.itheima包下编写 MybatisDemo 测试类
- 在
编写mybatis-config.xml
- 添加mybatis依赖
- 创建logback的配置文件(under resources folder)
- 编写 MyBatis 核心配置文件(mybatis-config.xml under resources folder)
- 编写 SQL 映射文件 (UserMapper.xml under resources folder)
- 编码
- 在
com.itheima.pojo包下创建 User类 - 在
com.itheima包下编写 MybatisDemo 测试类
- 在
<?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>
<typeAliases>
<package name="com.itheima.pojo"/>
</typeAliases>
<!--
environments:配置数据库连接环境信息。可以配置多个environment,通过default属性切换不同的environment
-->
<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:///mybatis?useSSL=false"/>
<property name="username" value="root"/>
<property name="password" value="1234"/>
</dataSource>
</environment>
<environment id="test">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<!--数据库连接信息-->
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql:///mybatis?useSSL=false"/>
<property name="username" value="root"/>
<property name="password" value="1234"/>
</dataSource>
</environment>
</environments>
<mappers>
<!--加载sql映射文件-->
<mapper resource="UserMapper.xml"/>
</mappers>
</configuration>
编写映射文件Mapper.xml
- 添加mybatis依赖
- 创建logback的配置文件(under resources folder)
- 编写 MyBatis 核心配置文件(mybatis-config.xml under resources folder)
- 编写 SQL 映射文件 (UserMapper.xml under resources folder)
- 编码
- 在
com.itheima.pojo包下创建 User类 - 在
com.itheima包下编写 MybatisDemo 测试类
- 在
<?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="test">
<select id="selectAll" resultType="com.itheima.pojo.User">
select * from tb_user;
</select>
</mapper>
编写pojo类
- 添加mybatis依赖
- 创建logback的配置文件(under resources folder)
- 编写 MyBatis 核心配置文件(mybatis-config.xml under resources folder)
- 编写 SQL 映射文件 (UserMapper.xml under resources folder)
- 编码
- 在
com.itheima.pojo包下创建 User类 - 在
com.itheima包下编写 MybatisDemo 测试类public class User { private int id; private String username; private String password; private String gender; private String addr; //省略了 setter 和 getter }
- 在
编写测试类
- 添加mybatis依赖
- 创建logback的配置文件(under resources folder)
- 编写 MyBatis 核心配置文件(mybatis-config.xml under resources folder)
- 编写 SQL 映射文件 (UserMapper.xml under resources folder)
- 编码
- 在
com.itheima.pojo包下创建 User类 - 在
com.itheima包下编写 MybatisDemo 测试类
- 在
public class MyBatisDemo {
public static void main(String[] args) throws IOException {
//1. 加载mybatis的核心配置文件,获取 SqlSessionFactory
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//2. 获取SqlSession对象,用它来执行sql
SqlSession sqlSession = sqlSessionFactory.openSession();
//3. 执行sql
List<User> users = sqlSession.selectList("test.selectAll"); //参数是一个字符串,该字符串必须是映射配置文件的namespace.id
System.out.println(users);
//4. 释放资源
sqlSession.close();
}
}
Mapper代理开发
目的:解决原生方式中的硬编码
- 添加mybatis依赖
- 创建logback的配置文件(under resources folder)
- 编写 MyBatis 核心配置文件(mybatis-config.xml under resources folder)
- 编写 SQL 映射文件 (UserMapper.xml under resources folder)
- 编码
- 在
com.itheima.pojo包下创建 User类 - 在
com.itheima包下编写 MybatisDemo 测试类
- 在
public class MyBatisDemo {
public static void main(String[] args) throws IOException {
//1. 加载mybatis的核心配置文件,获取 SqlSessionFactory
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//2. 获取SqlSession对象,用它来执行sql
SqlSession sqlSession = sqlSessionFactory.openSession();
/*//3. 执行sql
List<User> users = sqlSession.selectList("test.selectAll"); //参数是一个字符串,该字符串必须是映射配置文件的namespace.id
System.out.println(users);*/
//3. 获取接口代理对象
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
//4. 执行方法,其实就是执行sql语句
//5. 释放资源
sqlSession.close();
}
}
使用Mapper代理的要求
- 定义Mapper接口,Mapper接口和Mapper.xml在同一目录下(酱可以使用包扫描的方式简化SQL映射文件的加载)
- 修改Mapper.xml的namespace:为Mapper接口的全限定名
- 在 Mapper 接口中定义方法,方法名就是SQL映射文件中sql语句的id,并保持参数类型和返回值类型一致(returnType可以用类型别名简化书写)
类型别名
在映射配置文件中的 resultType 属性需要配置数据封装的类型(类的全限定名)。而每次这样写是特别麻烦的,Mybatis 提供了 类型别名(typeAliases) 可以简化这部分的书写。
首先需要在核心配置文件(mybatis-config.xml)中配置类型别名,也就意味着给pojo包下所有的类起了别名(别名就是类名),不区分大小写。内容如下:
<typeAliases>
<!--name属性的值是实体类所在包-->
<package name="com.itheima.pojo"/>
</typeAliases>
通过上述的配置,我们就可以简化映射配置文件中 resultType 属性值的编写
<mapper namespace="com.itheima.mapper.UserMapper">
<select id="selectAll" resultType="user">
select * from tb_user;
</select>
</mapper>
使用resultMap定义字段(表)和属性(实体类)的映射关系
-
实体类属性名 和 数据库表列名 不一致,不能自动封装数据
-
在映射配置文件中使用resultMap定义 字段 和 属性 的映射关系
<resultMap id="brandResultMap" type="brand"> <!-- id:完成主键字段的映射 column:表的列名 property:实体类的属性名 result:完成一般字段的映射 column:表的列名 property:实体类的属性名 --> <result column="brand_name" property="brandName"/> <result column="company_name" property="companyName"/> </resultMap>注意:在上面只需要定义 字段名 和 属性名 不一样的映射,而一样的则不需要专门定义出来。
-
SQL语句正常编写, resultType="brand"改为resultMap="brandResultMap".
<select id="selectAll" resultMap="brandResultMap"> select * from tb_brand; </select>
安装 MyBatisX 插件
-
主要功能
- XML映射配置文件 和 接口方法 间相互跳转
- 根据接口方法生成 statement
(可以在mapper接口中定义方法,自动生成映射配置文件中的
statement. 在爆红的地方使用alt+回车-> click'generate statement')
参数占位符
mybatis提供了两种参数占位符:
- #{}: 执行SQL时,会将 #{} 占位符替换为?,将来自动设置参数值。从上述例子可以看出使用#{} 底层使用的是
PreparedStatement - ${}: 拼接SQL。底层使用的是
Statement,会存在SQL注入问题。
以后开发我们使用 #{} 参数占位符。
<select id="selectById" resultMap="brandResultMap">
select *
from tb_brand where id = #{id};
</select>
接口中多参数实现
-
使用
@Param("参数名称")标记每一个参数,在映射配置文件中就需要使用#{参数名称}进行占位List<Brand> selectByCondition(@Param("status") int status, @Param("companyName") String companyName,@Param("brandName") String brandName); -
将多个参数封装成一个 实体对象 ,将该实体对象作为接口的方法参数。该方式要求在映射配置文件的SQL中使用
#{内容}时,里面的内容必须和实体类属性名保持一致。List<Brand> selectByCondition(Brand brand); -
将多个参数封装到map集合中,将map集合作为接口的方法参数。该方式要求在映射配置文件的SQL中使用
#{内容}时,里面的内容必须和map集合中键的名称一致。List<Brand> selectByCondition(Map map);
SQL语句特殊字段
- 特殊字段:比如<, >等这些字符在xml中有特殊含义,不能直接使用。
- 解决方法:
- 转义:例如
<就是<的转义字符。
- 转义:例如
parameterType使用
动态SQL
注解实现CRUD
- 注解是用来替换映射配置文件方式配置的,所以使用了注解,就不需要再映射配置文件中书写对应的
statement - 而是直接在Mapper接口方法上添加注解
- ==注解完成简单功能,配置文件完成复杂功能。==
@Select(value = "select * from tb_user where id = #{id}")
public User select(int id);
Mybatis 针对 CURD 操作都提供了对应的注解,已经做到见名知意。如下:
- 查询 :@Select
- 添加 :@Insert
- 修改 :@Update
- 删除 :@Delete
Mybatis参数传递
Session
- 服务端会话跟踪技术:将数据保存到服务端
- 获取Session对象
HttpSession session = request.getSession(); - 存储数据
session.setAttribute
启动Tomcat
Terminal输入
cd /Applications/apache-tomcat-11.0.0-M4/bin
./startup.sh
浏览器访问:http://localhost:8080/
关闭Tomcat
./shutdown.sh
创建Maven Web项目
部署web项目
推荐使用Maven中的Tomcat插件