入门:Mybatis
关于JDBC
依赖包
mysql-connector-java-5.1.7-bin.jar
:Mysql驱动ojdbc14-10.2.0.1.0.jar
:Oracle驱动
JDBC步骤
- 加载数据库驱动;
- 创建并获取数据库链接;
- 创建statement对象;
- 编写sql语句;
- 设置sql语句中的参数(使用preparedStatement);
- 通过statement执行sql并获取结果;
- 对sql执行结果进行解析处理;
- 释放资源(resultSet、preparedstatement、connection);
JDBC代码
package cn.xxx.jdbc;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class JdbcTest {
public static void main(String[] args) {
//数据库连接
Connection connection = null;
//预编译的Statement,使用预编译的Statement提高数据库性能
PreparedStatement preparedStatement = null;
//结果集
ResultSet resultSet = null;
try {
//加载数据库驱动
Class.forName("com.mysql.jdbc.Driver");
//通过驱动管理类获取数据库链接
connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8", "root", "admin");
//定义sql语句 ?表示占位符
String sql = "select * from user where username = ?";
//获取预处理statement
preparedStatement = connection.prepareStatement(sql);
//设置参数,第一个参数为sql语句中参数的序号(从1开始),第二个参数为设置的参数值
preparedStatement.setString(1, "王五");
//向数据库发出sql执行查询,查询出结果集
resultSet = preparedStatement.executeQuery();
//遍历查询结果集
while(resultSet.next()){
System.out.println(resultSet.getString("id")+" "+resultSet.getString("username"));
}
} catch (Exception e) {
e.printStackTrace();
}finally{
//释放资源
if(resultSet!=null){
try {
resultSet.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(preparedStatement!=null){
try {
preparedStatement.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(connection!=null){
try {
connection.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
JDBC问题
- 数据库链接创建、释放频繁造成系统资源浪费从而影响系统性能,如果使用数据库链接池可解决此问题。
- 采用硬编码方式,不能灵活操作数据库,代码不易维护。
- sql语句、查询条件、preparedStatement向占有位符号传参数、结果集解析,均是硬编码方式写入代码;
Mybatis
介绍
Mybatis 是三层架构【表示层(UI)、业务逻辑层(BLL)和数据访问层(DAL)】中的数据访问层(持久层)框架。
Mybatis 把对jdbc的操作数据库的过程都进行了封装(不再需要关注注册驱动、创建connection、创建statement、手动设置参数、结果集检索等),使开发更专注于SQL本身:
- 通过xml或注解的方式将要执行的各种statement(statement、preparedStatemnt、CallableStatement)配置起来,并通过java对象和statement中的sql进行映射生成最终执行的sql语句,最后由mybatis框架执行sql并将结果映射成java对象并返回。
相对于Hibernate更加轻量。Hibernate更加关注实体对象,而Mybatis更加关注sql语句。
相关包
- 核心包:
mybatis-3.2.7.jar
- 数据驱动包:
mysql-connector-java-5.1.7-bin.jar
ojdbc14-10.2.0.1.0.jar
- 依赖包:
asm-3.3.1.jar
:Java字节码操纵框架cglib-2.2.2.jar
:动态代理jar包(依赖于asm)commons-logging-1.1.1.jar
:日志处理javassist-3.17.1-GA
:字节码编辑工具log4j-1.2.17.jar
:slf4j(日志框架)log4j-api-2.0-rc1.jar
:..log4j-core-2.0-rc1.jar
:..slf4j-api-1.7.5.jar
:slf4j(用户日志系统的facade)slf4j-log4j12-1.7.5.jar
:slf4j与log4j的桥接包
- 其他
junit-4.9.jar
:单元测试包
架构
架构图 | |
---|---|
组件 | 说明 |
SqlMapConfig.xml | mybatis的全局配置文件,包括:
|
SqlSessionFactory | 通过SqlMapConfig.xml中的环境配置信息构造SqlSessionFactory(会话工厂) |
sqlSession | 由SqlSessionFactory创建sqlSession(会话),通过sqlSession进行数据库操作 |
Executor | mybatis底层自定义了Executor(执行器)接口操作数据库:
|
Mapped Statement | mybatis的底层封装对象,它包装了mybatis配置信息及sql映射信息等:
|
入门程序
SqlSession的使用范围
- SqlSession中封装了对数据库的操作,如:查询、插入、更新、删除等。
- SqlSession是通过SqlSessionFactory创建;
- SqlSessionFactory是通过SqlSessionFactoryBuilder进行创建(根据配置配置文件流)。
public class Mybatis_first {
//会话工厂
private SqlSessionFactory sqlSessionFactory;
@Before
public void createSqlSessionFactory() throws IOException {
// mybatis配置文件
String resource = "SqlMapConfig.xml";
// 得到配置文件流
InputStream inputStream = Resources.getResourceAsStream(resource);
// 使用SqlSessionFactoryBuilder从xml配置文件中创建SqlSessionFactory
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
}
public void testFindUserById() {
// 数据库会话实例
SqlSession sqlSession = null;
try {
// 创建数据库会话实例sqlSession
sqlSession = sqlSessionFactory.openSession();
// SqlSession中封装了对数据库的操作,如:查询、插入、更新、删除等
// selectOne
User user = sqlSession.selectOne("test.findUserById", 10);
// selectList
List<User> list = sqlSession.selectList("test.findUserByUsername", "张");
// insert
sqlSession.insert("test.insertUser", user);
// update
sqlSession.update("test.updateUser", user);
// delete
sqlSession.delete("test.deleteUserById",18);
...
} catch (Exception e) {
e.printStackTrace();
} finally {
if (sqlSession != null) {
sqlSession.close();
}
}
}
}
SqlSessionFactoryBuilder
用于创建SqlSessionFacoty,SqlSessionFacoty一旦创建完成就不需要SqlSessionFactoryBuilder了,因为SqlSession是通过SqlSessionFactory生产,所以可以将SqlSessionFactoryBuilder当成一个工具类使用,最佳使用范围是方法范围,即方法体内局部变量;
SqlSessionFactory
是一个接口,定义了openSession的不同重载方法,SqlSessionFactory的最佳使用范围是整个应用运行期间,一旦创建后可以重复使用,通常以单例模式管理SqlSessionFactory;
SqlSession
是一个面向用户的接口, sqlSession中定义了数据库操作,默认使用DefaultSqlSession实现类;
每个线程都应该有它自己的SqlSession实例。SqlSession的实例不能共享使用,它也是线程不安全的。因此最佳的范围是请求或方法范围。绝对不能将SqlSession实例的引用放在一个类的静态字段或实例字段中。
打开一个 SqlSession;使用完毕就要关闭它。通常把这个关闭操作放到 finally 块中以确保每次都能执行关闭。如下:
SqlSession session = sqlSessionFactory.openSession();
try {
// do work
} finally {
session.close();
}
Dao开发
使用Mybatis开发Dao,通常有两个方法,即原始Dao开发方法和Mapper接口开发方法。
原始Dao开发方式
原始Dao开发方法需要程序员编写Dao接口和Dao实现类。