一、MyBatis概述
1.1 原始的JDBC操作
谈及mybatis,必然需要先了解Java和数据库的连接技术——JDBC(Java DataBase Connectivity)。但是原始JDBC操作中,却存在如下缺点:
数据库连接创建、释放频繁造成系统资源浪费从而影响系统性能。
sql语句在代码中硬编译,造成代码不易维护,实际应用sql变化的可能较大,sql变动需要改变Java代码。
查询操作时,需要手动将结果集中的数据手动封装到实体中;插入操作时,需要手动将实体的数据设置到sql语句的占位符位置。
如下为原始JDBC操作:
public class JDBCDemo {
public static void main(String[] args) throws Exception{
//获取数据库连接对象
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/db1","root","root");
//定义sql语句
String sql = "select * from db1.emp";
//获取执行sql的对象Statement
Statement stmt = conn.createStatement();
//执行sql
ResultSet resultSet = stmt.executeQuery(sql);
//处理结果
while(resultSet.next()) {
int id = resultSet.getInt(1); //获取id
String name = resultSet.getString("ename"); //获取姓名
System.out.println("id:" + id + " name:" + name);
}
//释放资源
stmt.close();
conn.close();
}
}
1.2 如何克服JDBC固有缺陷
而面对上述缺点,我们的解决方案是:
使用数据库连接池技术(C3P0或者Druid)初始化连接资源;
将sql语句抽取到xml配置文件中(解耦合);
使用反射、内省等底层技术,自动将实体与表进行属性与字段的自动映射(比较困难)。
因此,mybatis应运而生!
1.3 什么是MyBatis
mybatis 是一个优秀的基于java的持久层框架,它内部封装了 jdbc,使开发者只需要关注sql语句本身,而不需要花费精力 去处理加载驱动、创建连接、创建statement等繁杂的过程。
mybatis通过xml或注解的方式将要执行的各种 statement配 置起来,并通过java对象和statement中sql的动态参数进行 映射生成最终执行的sql语句。
最后mybatis框架执行sql并将结果映射为java对象并返回。采 用ORM思想解决了实体和数据库映射的问题,对jdbc 进行了 封装,屏蔽了jdbc api 底层访问细节,使我们不用与jdbc api 打交道,就可以完成对数据库的持久化操作 。
二、MyBatis传统开发步骤
首先,我们可以先访问一下MyBatis官网地址:http://www.mybatis.org/mybatis-3/,这里有完整的mybatis的介绍。
2.1 添加MyBatis的坐标
把mysql和mybatis的坐标引入pom.xml中。
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.32</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.7</version>
</dependency>
2.2 创建一个实体
在项目下创建一个User.java的实体。
public class User {
private int id;
private String username;
private String password;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + '\'' +
", password='" + password + '\'' +
'}';
}
}
2.3 编写映射文件
在文件夹resources下再创建一个mapper文件夹,再创建映射文件UserMapper.xml。后续我们的sql语句可以全部写到这里。
2.3.1先写一个通用的dtd约束头
<?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">
2.3.2 再配置mapper
这里是select子句,当然也可以时insert、update等等。
<mapper namespace="userMapper">
<select id="findAll" resultType="user">
select * from db1.user
</select>
</mapper>
注意:这里必须先要有一个user数据库表。
2.4 编写核心文件
2.4.1 核心配置文件SqlMapConfig.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文件-->
<properties resource="jdbc.properties"/>
<!--自定义别名-->
<typeAliases>
<typeAlias type="domain.User" alias="user"/>
</typeAliases>
<!--数据源环境-->
<environments default="developement">
<environment id="developement">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</dataSource>
</environment>
</environments>
<!--加载映射文件-->
<mappers>
<mapper resource="mapper/UserMapper.xml"/>
</mappers>
</configuration>
别名 |
数据类型 |
string |
java.lang.String |
long |
java.lang.Long |
java |
java.lang.Integer |
double |
java.lang.Double |
boolean |
java.lang.Boolean |
而后期我们在执行更新操作时,就可以直接使用parameterType="int" 而不是 parameterType="java.lang.Integer",比如:
<update id="update" parameterType="int">
update user set username=#{username},password=#{password} where id=#{id}
</update>
• 使用相对于类路径的资源引用,例如:
<mapper resource="org/mybatis/builder/AuthorMapper.xml"/>
• 使用完全限定资源定位符(URL),例如:
<mapper url="file:///var/mappers/AuthorMapper.xml"/>
• 使用映射器接口实现类的完全限定类名,例如:
<mapper class="org.mybatis.builder.AuthorMapper"/>
• 将包内的映射器接口实现全部注册为映射器,例如:
<package name="org.mybatis.builder"/>
2.4.2 配置文件jdbc.properties
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/db1
jdbc.username=root
jdbc.password=root
2.5 测试
2.5.1 编写测试代码
/**
* 查询
* @throws IOException
*/
@Test
public void test1() throws IOException {
//获得核心配置文件
InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");
//获得session工厂对象
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
//获得session会话对象
SqlSession sqlSession = sqlSessionFactory.openSession();
//执行操作 参数:namespace+id
List<User> userList = sqlSession.selectList("userMapper.findAll");
//打印数据
System.out.println(userList);
//释放资源
sqlSession.close();
}
2.5.2 代码要点
这里我们可以看到,查询数据的一段java代码为:
List<User> userList = sqlSession.selectList("userMapper.findAll");
而这句代码中sqlSession.selectList的参数即我们刚才在UserMapper.xml 中写的代码:
<mapper namespace="userMapper">
<select id="findAll" resultType="user">
select * from db1.user
</select>
</mapper>
同理,我们也可以同样得到添加数据、修改数据和删除数据类似的代码:
sqlSession.insert("userMapper.add", user);
<insert id="add" parameterType="快速入门.User">
insert into user values(#{id},#{username},#{password})
</insert>
sqlSession.update("userMapper.update", user);
<update id="update" parameterType="快速入门.User">
update user set username=#{username},password=#{password} where id=#{id}
</update>
sqlSession.delete("userMapper.delete",3);
<delete id="delete" parameterType="快速入门.User">
delete from user where id=#{id}
</delete>
2.5.3 输出结果
执行编写好的代码,可以看到输出结果:
上面被选中的输出语句为:
[User{id=1, username='zhangsan', password='123'}, User{id=2, username='lisi', password='234'}, User{id=5, username='wangwu', password='abc'}, User{id=6, username='ray', password='111'}]
而我们再看一下数据库当中的数据,判断是否输出正常:
这里我们可以看到,一共4条数据,数据库中的数据已经被我们成功查找到。
三、总结
原来直接使用JDBC的sql代码被我们写入到了映射文件UserMapper.xml中,后续一些动态sql的加入更加简化了xml中代码量的书写。
而在Java代码中,我们只需要新建一些SqlSession对象便可以将xml中的sql语句直接使用。耦合度大大降低
但是我们也不难发现,这样的配置还是相对复杂的,因此就有了后来的MyBatisPlus来更加简化我们的代码书写。