mybatis作为一种ORM框架,实现了数据库中表和普通java pojo的映射,使得我们从繁重和重复的jdbc中解脱出来。
举个例子:假如我们有下面一张表
很简单,表名称是t_user,字段如图所示。
我们知道写sql语句可以将表里的数据查询出来,如果使用java将数据查询出来,需要用到mysql的jdbc驱动,然后针对jdbc去编写查询的逻辑。大概的过程如下
//第一步:加载MySQL的JDBC的驱动
Class.forName("com.mysql.jdbc.Driver");
//取得连接的 url,能访问MySQL数据库的用户名,密码;数据库名
String url = "jdbc:mysql://localhost:3306/tyz";
String user = "tyzdb";
String password = "db";
//第二步:创建与MySQL数据库的连接类的实例
conn = DriverManager.getConnection(url, user, password);
//第三步:用conn创建Statement对象类实例 stmt
stmt = conn.createStatement();
//第四步:执行查询,用ResultSet类的对象,返回查询的结果
String sql = "select * from age";
rs = stmt.executeQuery(sql);
while(rs.next()){
System.out.println(rs.getString("id")); //取得数据库中的数据
System.out.println(rs.getString("name"));
}
其中的rs.getString("id")中的参数id为t_user的列名,上面的只是一个简单的demo实际上查询完还要释放连接,这只是一个表的查询(不包含增删改),如果有几百张表每个都去这么写,估计要死人的。实际上上面的代码有很多重复和冗余的部分,这部分代码完全可以抽象出一个框架来完成,mybatis就是这样一个框架。提供了连接的管理,关系的映射等等功能。
接下来讲讲mybatis,连接数据库需要知道数据库的地址,用户名等等信息,同样用mybatis操作数据库中的数据同样需要这些信息,mybatis需要从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>
<typeAliases>
<!-- 别名 type配置为类的全路径 -->
<typeAlias alias="User" type="com.tang.mybatis.domain.User"/>
</typeAliases>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<!-- 此处配置数据库的信息 -->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<!-- url oracle和mysql的url不同 -->
<property name="url" value="jdbc:mysql://localhost:3306/tyz"/>
<property name="username" value="tyzdb"/>
<property name="password" value="huawei"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="mapping\mapping_user.xml"/>
</mappers>
</configuration>
该配置文件核心的内容差不多都张这样,里面配置了驱动信息,连接信息,用户名和密码。有了这些mybatis就可以连接到数据库了。
就像我们平时操作数据库一样,输入一个select * from t_user 语句就能得到想要的数据,mybatis同样可以做到甚至更好,通过在代码测建立一个domain对象和t_user表字段做一一对应,这就完成了映射的过程。
一个User类如下:
package com.tang.mybatis.domain;
import java.util.Date;
/**
* domain对象,该类的字段和数据库user表的列一一对应
*
* @author Administrator
*
*/
public class User {
// 用户id
private int id;
// 用户名
private String name;
// 密码
private String password;
// 年龄
private int age;
// 出生日期
private Date birth;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Date getBirth() {
return birth;
}
public void setBirth(Date birth) {
this.birth = birth;
}
}
可以看到上面的pojo相当简单,没有任何逻辑,纯粹的是字段和getter,setter,但是注意这些字段和数据库的t_user表列名一一对应。我们想要做到的一个效果就是告诉mybatis我要查询的语句,比如select * from t_user where id=1,然后mybaits连接数据库执行这个语句,将结果完美的放到User类中,比如有如下一条数据:
使用mybatis应该达到的效果如下:
mybatis提供的查询方法,返回值为User
//调用完后打印获取到值
System.out.println(user.getId());
System.out.println(user.getName());
System.out.println(user.getPassword());
System.out.println(user.getAge());
System.out.println(user.getBirth());
上面的代码应该将数据库中的值一一对应的打印出来。
实际上mybatis就是完成的这样一种工作,此时可能你会有个疑问,mybatis是怎么知道t_user表的id列的值要赋给User对象的id字段,大概可以猜到两种可能:
1、约定因为字段名字都是id,其他类似,也就是列名和字段名称一样
2、通过配置文件配置或者代码指定
实际上mybatis就是这么干的,这个配置文件就是dbsource.xml中指定的,术语叫映射文件,如下:
<mappers>
<mapper resource="mapping\mapping_user.xml"/>
</mappers>
就在这个mapper标签中指定,我们的项目中已经配置好了mapping_user.xml,可以猜测一下这个文件长什么样,首先mybatis需要知道查询语句,然后需要按照约定将查出的结果赋值给User对象,因此mybatis需要知道User类的类路径,好了,看下mapping_user.xml文件:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//ibatis.apache.org//DTD Mapper 3.0//EN"
"http://ibatis.apache.org/dtd/ibatis-3-mapper.dtd">
<mapper namespace="com.tang.mybatis.domain.UserMapper">
<!-- resultType指定映射为User,在dbsource.xml已为User配置类全路径 -->
<select id="findUserById" resultType="User" >
select * from t_user where id = #{id}
</select>
</mapper>
基本上和我们猜测的差不多<select>标签代表查询相应的还有update,delete,insert标签,<select>标签中指定了sql语句,关注下resultType属性,这里配置为User,强调一下这个User只是一个别名,这个别名背后真正的含义在dbsource.xml中已经指定了,如下:
<typeAliases>
<!-- 别名 type配置为类的全路径 -->
<typeAlias alias="User" type="com.tang.mybatis.domain.User"/>
</typeAliases>
type是关键点一定要是类的全路径,配置resultType的意思就是当查询到了结果后赋值给User对象。
注意到select的另外一个属性id,这个属性也很重要,因为我们在代码中是通过这个id告诉mybatis要执行哪条sql语句的。
但是这里的sql语句又和我们平时用的不一样,它最后面有个#{id}这种奇怪的符号,这是动态参数,动态参数就是这个id值我们在java 程序中根据不同的场景传入,不是固定的。
mybatis基本的配置文件全部讲解完毕,下面看下代码中怎么使用:
package mybatis;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import com.tang.mybatis.domain.User;
/**
* 测试类
* @author Administrator
*
*/
public class Test {
//sessionFactory
private static SqlSessionFactory sessionFactory;
private static Reader reader;
private static final String APP_PATH = System.getProperty("user.dir");
static
{
try {
//读取conf下的dbsource配置文件
reader = new FileReader(new File(APP_PATH + "\\conf\\dbsource.xml"));
//应用该配置文件建立session工厂
sessionFactory = new SqlSessionFactoryBuilder().build(reader);
} catch (IOException e) {
e.printStackTrace();
}
}
public static SqlSessionFactory getSession()
{
return sessionFactory;
}
public static void main(String[] args) {
//打开一个到数据的连接
SqlSession session = sessionFactory.openSession();
//调用配置好的查询id,并传入参数1,参数1将被mapping_user.xml中的select * from t_user where id = #{id} 最后的#{id}替换
//#{id}表示动态参数,此处演示的最简单的一种
User user = (User)session.selectOne("findUserById", 1);
//调用完后打印获取到值
System.out.println(user.getId());
System.out.println(user.getName());
System.out.println(user.getPassword());
System.out.println(user.getAge());
System.out.println(user.getBirth());
}
}
没错就是这么简单,开发模式是这样的,每次新增加一张表,我们同步新增加一个对应该表的java对象,然后提供一份mapping_*.xml文件,配置增删改查标签,别名。就可以在程序中随意获取数据库的值了,非常的简单。
完整的代码工程见附件。注意:
运行的时候请指定conf目录到classpath下,不知道怎么操作的话看下图:
在项目工程上右键选择Run configurations,选择classpath标签,选择User Entries ,看右边,选择Advanced,弹出选项框,选择第一项Add Folders,选择项目的confi目录然后一路ok。