当Java程序需要与数据库进行通信时,需要借助JDBC才能实现这个过程,接下来我们看看这个过程。
JDBC实现和数据库的通信
public static void main(String[] args) throws Exception {
//读取数据库的配置文件
try (InputStream in = Demo.class.getClassLoader().getResourceAsStream("db.properties")) {
Properties properties = new Properties();
properties.load(in);
String driver = properties.getProperty("drive_name");
String url = properties.getProperty("url");
String username = properties.getProperty("username");
String password = properties.getProperty("password");
//加载MySQL驱动
Class.forName(driver);
//创建连接
try (Connection connection = DriverManager.getConnection(url, username, password)) {
//创建具有高安全性的SQL语句
try (PreparedStatement preparedStatement = connection.prepareStatement("select * from student where id=?")) {
//设置参数
preparedStatement.setInt(1, 1);
//发送SQL到MySQL执行并获取结果
try (ResultSet resultSet = preparedStatement.executeQuery()) {
//迭代结果集合
while (resultSet.next()) {
//获取列的值
System.out.println(resultSet.getInt("id"));
System.out.println(resultSet.getString("name"));
}
}
}
}
}
}
上面的示例展示了一个查询操作,但从这些简单的代码中却可以看出来很多JDBC的缺点:
- 数据库连接频繁的创建和释放,浪费资源,降低了性能
- SQL语句硬编码在Java代码中,导致SQL维护起来比较困难,需要修改代码才能完成
- 如果改变代码中的SQL,对于SQL中参数类型和数量的变化都会导致维护成本升高,需要修改分散在代码中的类似【setInt】的操作或者是【getString】操作
- 查询类返回的结果不友好,无法直接映射为POJO类,增加额外的处理操作
- 大量的重复代码,可读性差,代码臃肿
虽然有DBCP
和C3P0
这样的数据库连接池管理解决方案和DBUtil
这样的工具包,但是仍不能完全解决上述的种种问题。
初识Mybatis
从官方对Mybatis的定义,可以看出来Mybatis是一个非常优秀的ORM框架,可以几乎避免所有使用JDBC编程带来的缺点,通过简单的配置即可实现对SQL返回结果和POJO之间的映射等等。我们在来看一看使用Mybaits实现同样的查询是怎么样的?
Mybatis 的核心结构
Mybatis 实现和数据库的通信
public static void main(String[] args) throws Exception {
//读取Mybatis配置文件信息
try(InputStream stream =Resources.getResourceAsStream("mybatis-config.xml")) {
//创建SqlSession工厂
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(stream);
//生成SqlSession实例
try (SqlSession session = factory.openSession()) {
//使用SqlSession完成查询操作
List<Student> students = session.selectList("com.vitamin.mybatis.mapper.GetStudents", 1);
for (Student student : students) {
System.out.println(student);
}
}
}
}
mybatis-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">
<configuration>
<!-- 设置properties文件的位置 -->
<properties resource="db.properties" />
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${drive_name}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</dataSource>
</environment>
</environments>
<!-- 映射配置文件的存储位置 -->
<mappers>
<mapper resource="StudentMapper.xml"></mapper>
</mappers>
</configuration>
StudentMapper.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">
<mapper namespace="com.vitamin.mybatis.mapper">
<!-- 查询类SQL语句标签 需要有唯一的id,入参类型和返回值类型 -->
<select id="GetStudents" parameterType="int" resultType="com.vitamin.mybatis.Student">
select * from student where id=#{id}
</select>
</mapper>
上面的示例通过对比JDBC实现的同时也展示了Mybatis的简单用法,Mybatis在代码的实现上将硬编码的内容全部都移动到了配置的Mapper文件中,提高了SQL编写的灵活性并且使用了数据库连接池管理连接,提高了资源利用率和性能。
Mybatis 和 Hibernate 对比
我相信在了解Mybatis之后,必然会碰见另一个鼎鼎大名的ORM框架 Hibernate,同样作为ORM他们之间有什么区别呢?来对比一下:
- Mybatis 相对于 Hibernate 而言属于一个半自动的ORM框架,因为使用Mybatis需要我们手动维护SQL语句。但这也是Mybatis的优点,提高了SQL的灵活性,方便后续优化SQL。而 Hibernate 却可以根据对象自动映射为SQL语句,不易维护,SQL优化的空间比较小。
- Mybatis 需要针对不同的数据库编写不同的SQL,由于手动维护的SQL不能满足所有的数据库。Hibernate 则会根据对象模型针对不同的数据库生成不同的SQL
- Hibernate 比较复杂,庞大,学习时间长 ,但功能却很强大。而Mybatis则相对轻量一些。
无论是 Mybatis 也好,Hibernate 也罢都有适合自己发挥特长的场景,具体何时该使用何种ORM取决于所依赖的场景。
总结
上面的各小节对Mybatis的使用只为了快速入门,简单且直观。但要想在项目中使用Mybatis,往往需要使用更高级的内容,这部分在后续的文章中会有提及。好了,到这里本篇结束了,快把Mybatis使用起来吧。