Mybatis简化JDBC

JDBC

  1. 概念:就是使用Java语言操作关系型数据库的一套API

  2. 本质:使用JDBC接口编程,驱动jar包中的实现类

  3. 好处:

  • 各数据库厂商使用相同的接口,Java代码不需要根据不同的数据库而变化
  • 随时更换底层数据库,Java代码基本不变
  1. 使用:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
00.创建工程,导入驱动jar包
mysql-connector-java-8.0.33.jar
01.注册驱动
Class.forName("com.mysql.jdbc.Driver"):
2.获取连接
Connection conn = DriverManager.getConnection(url, username, passw
3.定义SQL语句
String sql = “update...
4.获取执行SQL对象
Statement stmt = conn.createStatement();
//防止sql注入
PreparedStatement ps = connection.prepareStatement(sql);
5.执行SQL
ResultSet rs = stmt.executeUpdate(sql);
6.处理返回结果,rs中就是操作的结果集,通过next()方法移动游标
rs.next()

7.释放资源,注意关闭顺序
conn.close()
stmt.close()
rs.close()
  1. 事务管理
1
2
3
4
5
6
Connection接口定义了三个对应的方法
开启事务:setAutoCommit(boolean autoCommit):true为自动提交事务;false为手动提交事务,即为开启事务
try carh 中进行数据回滚的操作
提交事务:
commit()
回滚事务:rollback()
  1. 创建工具类通过静态代码块获取连接对象,防止多次创建数据库连接对象
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
import java.sql.*;
public class DbUtil {
private static final String DRIVER="com.mysql.cj.jdbc.Driver";
private static final String URL="jdbc:mysql://localhost:3306/数据库名称?characterEncoding=utf-8";
private static final String USERNAME="root";
private static final String PWD="root";
static {
try {
Class.forName(DRIVER);//静态代码块
} catch (ClassNotFoundException e) {
e.printStackTrace();
}

}
public static Connection getCon()throws Exception{//获取数据库连接
try {
return DriverManager.getConnection(URL, USERNAME, PWD);
}catch(SQLDataException e){
e.printStackTrace();
}
return null;
}
public static ResultSet getRs(String sql){//懂得都懂
try {
PreparedStatement ps = getCon().prepareStatement(sql);
return ps.executeQuery();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}

public static void closeCon(Connection con){
if(con!=null){
try {
con.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
public static void closepstm(PreparedStatement pstem){
if(pstem!=null){
try {
pstem.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
public static void colseRes(ResultSet rs){
if(rs!=null){
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
  1. 通过数据库连接池连接数据库

好处:资源复用、提升系统响应速度、避免数据库连接遗漏

Druid连接池

1
2
3
4
5
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.2.1</version>
</dependency>

通过配置文件获取连接池对象

1
2
3
4
5
6
7
8
9
10
driver = com.mysql.cj.jdbc.Driver
url = jdbc:mysql://localhost:3306/db_book
username = root
password = root
# 初始化连接数量
initialsize=5
# 最大连接数
maxActive=10
# 最大等待时间
maxWait=3000

代码实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import com.alibaba.druid.pool.DruidDataSourceFactory;
import javax.sql.DataSource;
import java.io.InputStream;
import java.sql.Connection;
import java.util.Properties;
public class dome {
public static void main(String[] args) throws Exception {
final Properties properties = new Properties();
//使用类加载器获取资源流,而不是直接使用 FileInputStream,这样可以避免路径问题
InputStream in = dome.class.getClassLoader().getResourceAsStream("DB.properties");
properties.load(in);
final DataSource dataSource = DruidDataSourceFactory.createDataSource(properties);
final Connection connection = dataSource.getConnection();
System.out.println(connection);

}
}

工具类实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
import com.alibaba.druid.pool.DruidDataSourceFactory;
import javax.sql.DataSource;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;

public class DruidUtil {
//druid连接池对象
private static final DataSource dataSource;

static {
final Properties properties = new Properties();
try {
InputStream in = DruidUtil.class.getClassLoader().getResourceAsStream("DB.properties");
properties.load(in);
dataSource = DruidDataSourceFactory.createDataSource(properties);
} catch (Exception e) {
throw new RuntimeException(e);
} {

}

}
//获取数据库连接
public static Connection getConnection(){
try {
return dataSource.getConnection();
} catch (SQLException e) {
throw new RuntimeException(e);
}

}
//关闭数据库连接
public static void close(Connection conn) {
if (conn != null) {
try {
conn.close(); // 归还连接给连接池
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}

使用Mybatis

  1. 一款优秀的的持久化框架

  2. maven坐标

1
2
3
4
5
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>x.x.x</version>
</dependency>
  1. 配置文件,配置文件的顺序有要求
QQ_1733880187375
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<?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.hngy.pojo"/>
</typeAliases>

<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</dataSource>
</environment>
</environments>
<mappers>
<!--扫描mapper-->
<package name="com.hngy.mapper"/>
</mappers>
</configuration>
  1. 配置文件放置目录,目录结构和上方java代码包结构相一致,注意配置文件的名称mybatis-config.xml软件包分隔用/
QQ_1733880264709
  1. 使用静态代码块创建工厂连接对象,解决多次创建共厂的问题
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import java.io.IOException;
import java.io.InputStream;

public class SqlSessionFactoryUtil {
private static SqlSessionFactory sqlSessionFactory;

static {
try {
//设置路经
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
} catch (IOException e) {
e.printStackTrace();
}


}
public static SqlSessionFactory getSqlSessionFactory() {
return sqlSessionFactory;
}
}

  1. 通过连接对象操作,增删改要手动提交事务
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class BrandService {
SqlSessionFactory sqlSessionFactory;
/*查询结果*/
public List<Brand> selectBrandAll(){
sqlSessionFactory = getSqlSessionFactory();
SqlSession sqlSession = sqlSessionFactory.openSession();
//BrandMapper.class放置自己编写的sql语句
BrandMapper mapper = sqlSession.getMapper(BrandMapper.class);
List<Brand> brands = mapper.selectBrands();

//sqlSession.commit();增删改要手动提交事务

sqlSession.close();
return brands;
}

使用配置文件编写sql语句

  1. 简单sql语句采用注解的形式书写

  2. 实体类属性名和数据包字段名不一致需要用resultMap映射,可以配置开启自动驼峰命名映射

1
2
3
4
5
6
7
8
9
10
11
12
13
    <resultMap id="brandResultMap" type="brand">
<result column="brand_name" property="brandName"></result>
<result column="company_name" property="companyName"></result>
</resultMap>
<!--resultType:返回类型 resultMap:映射关系-->
<select id="selectUser" resultType="com.hngy.pojo.User" resultMap="brandResultMap">
select * from tb_user where username = #{username} and password = #{password};
</select>
<!--执行后添加属性的主键值-->
<insert id="save" useGeneratedKeys="true" keyProperty="id">
</insert>

<!--注解上使用 @ResultMap("brandResultMap")-->
  1. 用param注解的方式,告诉下面的SQL语句,传递过来的参数代表的占位符,封装对象传递属性要和字段名相对应

  2. 动态SQL标签,动态标签中的列名必须用数据库中的字段名,开启了驼峰映射也没有用

Mybatis是如何简化JDBC的

  1. JDBC 中,每次进行数据库操作都需要手动获取连接、创建 Statement 或者 PreparedStatement、执行 SQL 语句、处理结果集,并且需要手动关闭连接和释放资源,在 MyBatis 中,这些步骤都被封装在 SqlSession ,只需要通过 SqlSession 获取 Mapper 接口对象,然后调用方法即可
  2. MyBatis 中,SQL 语句通过 XML 或注解的形式进行编写和处理,支持动态SQL
  3. 通过配置 resultMap 或使用注解等方式将查询结果集映射到 Java 对象中