一. Mybatis简介
MyBatis原本是Apache下的一个项目,但是在MyBatis2.0 及 1.0版本的时候,人家不叫MyBatis,而是叫做IBatis,所以以后大家不管是MyBatis还是IBatis,实际上是一回事。是因为在IBatis3.0版本即将推出的时候,这个团队整体的转战到了谷歌旗下,3.0之后就叫做MyBatis了,MyBatis是一个非常优秀的持久化层的半自动框架,和之前学习的JDBC,DBUtil,JdbcTemplate一样,但是JDBC原生的技术,是Java连接数据库的标准,DBUtil,JdbcTemplate充其量是一个小工具,不能称之为框架,框架一定是一个整体的解决方案。
先回顾一下原生的JDBC开发的操作步骤:
- 加载驱动程序Class.forName(“驱动类的全类名”);
- 取得数据库连接Connection conn = DirverManager.getConnection(…)
- 编写sql
- 数据库操作(Statement,PreparedStatement,ResultSet)
- 如果是增删改,且进行多条sql操作,需要进行事务管理
- 关闭数据库
JDBC的缺点:
- 代码冗余:相似的代码到处都是
- 功能单一:不能完成缓存操作,不能自动的封装结果集
- 代码耦合度高:所有的sql语句都是写在Java程序中,耦合度高,维护不便
这个时候我们不得不使用工具或者框架,但是工具同样存在以上的问题,所以我们必须使用框架完成持久化层开发,目标比较流行的框架有:
**Hibernate:**是一个非常优秀的全自动框架,Hibernate旨在消除sql,意味着一个不懂sql的人,也可以使用Hiberate进行数据访问层开发,在开发过程中,完全针对的是实体类的对象,比如创建一个对象,save(对象),这个对象就通过ORM映射关系保存到表中,但是Hibernate存在问题是,一是不需要编写sql,所以一些复杂的查询由Hibernate自动生成sql,不能进行优化,二是对于复杂查询来说我们还需要编写另外的一种语句叫做HQL,所以学习成本增加,三是Hibernate不许程序员编写sql,而是由Hibernate自动的生成sql,所以执行效率比较低。
**JAP+SpringData:**和Hibernate几乎一样。
**MyBaits:是一个非常优秀的半自动框架,不像Hibernate那样进行黑箱操作,而是将sql的编写交给程序员,而且sql也不用编写在Java程序中,而是使用xml配置方式编写sql语句,所以Mybais的特点:**①sql与Java代码相分离,②SQL语句是程序员编写,可以进行更好的优化,③除了已经学过的sql之前,不会像Hibernate那样学其他的QL语句。
**ORM:**Object Relation Mapping 对象关系映射,实际上就是每个实体类都对应上一张表或者视图。实体类的每个对象就是数据表/视图中的每一笔数据。
二. Mybatis入门小程序
既然是一个全新的框架,那我们首先得搭建环境。
- 创建一个普通的Java项目
- 加入jar包:
log4j-1.2.17.jar (用于打印日志信息)
mybatis-3.5.5.jar (mybatis核心jar包)
mysql-connector-java-5.1.37-bin.jar (数据库驱动jar包)
加入jar包后记得add to build path,将jar包添加到编译环境
- 在项目路径下新建一个source文件夹,取名conf,并将log4j.xml复制到conf目录下
- 编写Mybatis全局配置文件,新建到conf目录下(可参考Mybatis官方文档)
<?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>
<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 resource="com/nhkj/dao/EmpDao.xml" /> <--这里在后续步骤会讲到
</mappers>
</configuration>
- 编写实体类(Emp)
public class Emp {
private Integer empId;
private String empName;
private String empMail;
private Integer empGender;
private Integer deptId;
public Integer getEmpId() {
return empId;
}
public void setEmpId(Integer empId) {
this.empId = empId;
}
public String getEmpName() {
return empName;
}
public void setEmpName(String empName) {
this.empName = empName;
}
public String getEmpMail() {
return empMail;
}
public void setEmpMail(String empMail) {
this.empMail = empMail;
}
public Integer getEmpGender() {
return empGender;
}
public void setEmpGender(Integer empGender) {
this.empGender = empGender;
}
public Integer getDeptId() {
return deptId;
}
public void setDeptId(Integer deptId) {
this.deptId = deptId;
}
@Override
public String toString() {
return "Emp [empId=" + empId + ", empName=" + empName + ", empMail=" + empMail + ", empGender=" + empGender
+ ", deptId=" + deptId + "]";
}
}
- 在conf目录下新建包(com.nhkj.dao),然后在包下新建EmpDao.xml文件(可参考Mybatis官方文档)
<?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.nhkj.dao.EmpDao">
<select id="selectEmp" resultType="com.nhkj.entities.Emp">
select * from Emp where id = #{empId}
</select>
</mapper>
- 然后我们就可以来编写测试类了
@Test
public void test() throws Exception {
//获取全局配置文件字节输入流
InputStream input = Resources.getResourceAsStream("Mybatis.xml");
//获取SqlSessionFactory对象
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(input);
//获取SqlSession对象
SqlSession sqlSession = sqlSessionFactory.openSession();
List<Emp> emps = sqlSession.selectList("com.nhkj.dao.EmpDao.selectEmp");
System.out.println(emps);
System.out.println(emps);
sqlSession.close();
}
- 测试结果
三. 接口式编程
以上的程序,会不会出现问题呢?当然会有问题,我们没有办法指定传入sql的参数类型,可以随意传递任意类型,但是结果却差强人意。而且在开中也存在问题,所谓三层架构,Service层如何调用数据访问层呢?所以我们要使用接口式编程:
- 定义数据访问层接口
- 将数据访问层接口和sql映射文件相绑定
- 将接口的每个方法和sql映射文件中的每一条sql语句相绑定
- 编写接口
public interface EmpDao {
public List<Emp> selectEmp();
public Emp selectEmpByEmpId(Integer empId);
public void insertEmp(Emp emp);
public void deleteEmpByEmpId(Integer empId);
public void updateEmpByEmpId(Integer empId,String empName);
}
- 编写相应的EmpDao.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.nhkj.dao.EmpDao">
<select id="selectEmp" resultType="com.nhkj.entities.Emp">
<!-- select * from emp -->
select emp_id,emp_name,emp_mail,emp_gender,dept_id from emp
</select>
<select id="selectEmpByEmpId" resultType="com.nhkj.entities.Emp">
select emp_id,emp_name,emp_mail,emp_gender,dept_id from emp where emp_id = #{empId}
</select>
<insert id="insertEmp">
insert into emp(emp_name,emp_mail,emp_gender,dept_id) values (#{empName},#{empMail},#{empGender},#{deptId})
</insert>
<delete id="deleteEmpByEmpId">
delete from emp where emp_id = #{empId}
</delete>
<update id="updateEmpByEmpId">
update emp set emp_gender = 1 where emp_id = #{param1} and emp_name = #{param2}
</update>
</mapper>
- 测试
@Test
public void test() throws Exception {
//获取全局配置文件字节输入流
InputStream input = Resources.getResourceAsStream("Mybatis.xml");
//获取SqlSessionFactory对象
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(input);
//获取SqlSession对象
SqlSession sqlSession = sqlSessionFactory.openSession();
/*List<Emp> emps = sqlSession.selectList("com.nhkj.dao.EmpDao.selectEmp");
System.out.println(emps);*/
//接口式编程
EmpDao empDao = sqlSession.getMapper(EmpDao.class);
List<Emp> emps = empDao.selectEmp();
System.out.println(emps);
sqlSession.close();
}
@Test
public void testSelectEmpByEmpId() throws Exception {
//获取全局配置文件字节输入流
InputStream input = Resources.getResourceAsStream("Mybatis.xml");
//获取SqlSessionFactory对象
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(input);
//获取SqlSession对象
SqlSession sqlSession = sqlSessionFactory.openSession();
//接口式编程
EmpDao empDao = sqlSession.getMapper(EmpDao.class);
Emp emp = empDao.selectEmpByEmpId(1);
System.out.println(emp);
sqlSession.close();
}
小结
Mybatis是一款非常优秀的持久化框架,后面我将详细介绍配置文件中各个标签及其属性的作用。