iBatis

iBatis内容包括

iBatis 简介
搭建环境
配置文件
读取配置
基本的CRUD操作
模糊查询
自动主键selectKey
优点


iBatis 简介

   iBATIS一词来源于“internet”和“abatis”的组合,是一个由Clinton Begin在2001年发起的开放源代码项目。于2010年6月16号被谷歌托管,改名为MyBatis。是一个基于SQL映射支持Java和·NET的持久层框架。

   Ibatis是开源软件组织Apache推出的一种轻量级的对象关系映射(ORM)框架,和Hibernate、Toplink等在java编程的对象持久化方面深受开发人员欢迎。

   对象关系映射(ORM):简单原理是通过面向对象方式操作关系型数据库,目前存储数据最常用最流行的工具是关系型数据库,其操作方式是通过 SQL语句操作数据库的表,但是对于Java面向对象编程语言中,所有的操作对象都是对象,因此对象关系映射就是把数据库表和java编程语言中的对象对 应起来,把表的列同java对象中的字段对应起来,程序员在程序开发过程中不再是使用原始SQL语句去直接操作数据库,而是通过ORM提供的查询语句操作 普通的java对象,ORM将其提供的对普通java对象的查询语句翻译成SQL语句来操作数据库,从而屏蔽了不同数据库SQL语句的差别,简化了程序开 发工作,提高了程序的可移植性。


环境搭建

导入jar包

ibatis-2.3.4.726.jar
sqljdbc.jar

配置文件

这是总配置文件 SqlMapConfig.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE sqlMapConfig
PUBLIC "-//iBATIS.com//DTD SQL Map Config 2.0//EN"
"http://www.ibatis.com/dtd/sql-map-config-2.dtd" > <sqlMapConfig>

<properties resource="Resources/SqlMap.properties"/>

<transactionManager type ="JDBC" >
<!-- 定义了ibatis的事务管理器有3中(JDBC,JTA,EXTERNAL) -->

<dataSource type ="SIMPLE">

<!-- type属性指定了数据源的链接类型,也有3种类型(SIMPLE,DBCP,JNDI) -->

<property name ="JDBC.Driver" value ="${driver}" />

<property name ="JDBC.ConnectionURL" value ="${url}" />

<property name ="JDBC.Username" value ="${username}" />

<property name ="JDBC.Password" value ="${password}" />

<property name ="Pool.MaximumActiveConnections" value ="10"/>

<!-- 连接池维持的最大容量 -->
<property name ="Pool.MaximumIdleConnections" value ="5" />

<!-- 连接池允许挂起的最大连接 -->
<property name ="Pool.MaximumCheckoutTime" value ="120000" />

<!-- 连接被某个任务所允许占用的最大时间 -->

<property name ="TimeToWait" value ="500" />

<!-- 线程允许等待的最大时间 -->

</dataSource >

</transactionManager >

<sqlMap resource = "cn/shelhon/Student.xml" />

</sqlMapConfig >

这是映射文件 student.xml
表示实体类的映射文件,它的里面是对实体的一些操作,即增、删、改、查。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE sqlMap
PUBLIC "-//ibatis.apache.org//DTD SQL Map 2.0//EN"
"http://ibatis.apache.org/dtd/sql-map-2.dtd">

<sqlMap>

<!-- 定义别名,可以在指定类型时不用输入类型全路径 方便开发-->
<typeAlias alias="Student" type="cn.shelhon.Student"/>

<select id="selectAllStudent" resultClass="Student">

select *

from student

</select>

<select id="selectAllStudentByID" parameterClass="int" resultClass="Student">

select * from student

where sid= #sid#

</select>

</sqlMap>

其中映射文件可以不断修改来增加功能

属性文件 SqlMap.properties

1
2
3
4
driver=com.mysql.jdbc.Driver 
url=jdbc:mysql://localhost/test
username=root
password=12345

创建实体类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
package cn.shelhon;

import java.sql.Date;

public class Student {
private int sid = 0;
private String sname =null;
private String major =null;
private Date birth= null;
private float score = 0;

public Date getBirth() {
return birth;
}

public void setBirth(Date birth) {
this.birth = birth;
}

public int getSid() {
return sid;
}

public void setSid(int sid) {
this.sid = sid;
}

public String getSname() {
return sname;
}

public void setSname(String sname) {
this.sname = sname;
}

public String getMajor() {
return major;
}

public void setMajor(String major) {
this.major = major;
}

public float getScore() {
return score;
}

public void setScore(float score) {
this.score = score;
}

@Override
public String toString() {
return "Student{" +
"sid=" + sid +
", sname='" + sname + '\'' +
", major='" + major + '\'' +
", birth=" + birth +
", score=" + score +
'}';
}
}

创建接口类

1
2
3
4
5
6
7
8
9
10
11
12
13
package cn.shelhon;

import java.util.List;

public interface IStudentDAO {
public void addStudent (Student student);
public void addStudentBySequence(Student student);
public void deleteStudentByID(int id);
public void updateStudent(Student student);
public List<Student> queryAllStudent();
public List<Student> queryStudentByName(String name);
public Student queryStudentByID(int id);
}

然后再创建实现类来实现方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
package cn.shelhon;

import com.ibatis.sqlmap.client.SqlMapClient;

import java.io.IOException;
import java.io.Reader;
import java.sql.SQLException;
import java.util.List;


public class IStudentDAOImpl implements IStudentDAO{
private static SqlMapClient sqlMapClient= null;

//读取配置信息
static {
try{
Reader reader=com.ibatis.common.resources.Resources.getResourceAsReader("SqlMapConfig.xml");
sqlMapClient = com.ibatis.sqlmap.client.SqlMapClientBuilder.buildSqlMapClient(reader);
reader.close();
} catch (IOException e){
e.printStackTrace();
}
}

@Override
public void addStudent(Student student) {

}

@Override
public void addStudentBySequence(Student student) {

}

@Override
public void deleteStudentByID(int id) {

}

@Override
public void updateStudent(Student student) {

}

//查询所有信息
@Override
public List<Student> queryAllStudent() {
List<Student> studentList =null;
try {
studentList = sqlMapClient.queryForList("selectAllStudent");
} catch (SQLException e) {
e.printStackTrace();
}
return studentList;
}

@Override
public List<Student> queryStudentByName(String name) {
return null;
}

//通过id来查询信息
@Override
public Student queryStudentByID(int id) {
Student student= null;
try {
student = (Student) sqlMapClient.queryForObject("selectAllStudentByID",id);
} catch (SQLException e) {
e.printStackTrace();
}
return student;
}

public static void main(String[] args) {
IStudentDAO dao =new IStudentDAOImpl();


/* for(Student student:dao.queryAllStudent()){
System.out.println(student); }*/

Student student=dao.queryStudentByID(1);
System.out.println(student);
}

}

查询所有对象

  1. 增加查询接口
1
public List<Student> queryAllStudent();
  1. 映射文件
1
2
3
<select id="selectAllStudent" resultClass="Student">
select * from student
</select>
  1. 实现接口
1
2
3
4
5
6
7
8
9
10
11
//查询所有对象
@Override
public List<Student> queryAllStudent() {
List<Student> studentList =null;
try {
studentList = sqlMapClient.queryForList("selectAllStudent");
} catch (SQLException e) {
e.printStackTrace();
}
return studentList;
}

测试

1
2
3
4
5
public static void main(String[] args) {
IStudentDAO dao =new IStudentDAOImpl();
for(Student student:dao.queryAllStudent()){
System.out.println(student); }
}

查询指定id的对象

  1. 接口

    1
    public void deleteStudentByID(int id);
  2. 映射文件

    1
    2
    3
    4
    <select id="selectAllStudentByID" parameterClass="int" resultClass="Student">
    select * from student
    where sid= #sid#
    </select>
  3. 方法

1
2
3
4
5
6
7
8
9
10
11
//通过id来查询信息
@Override
public Student queryStudentByID(int id) {
Student student= null;
try {
student = (Student) sqlMapClient.queryForObject("selectAllStudentByID",id);
} catch (SQLException e) {
e.printStackTrace();
}
return student;
}
  1. 测试
1
2
3
4
5
public static void main(String[] args) {
IStudentDAO dao =new IStudentDAOImpl();
Student student=dao.queryStudentByID(1);
System.out.println(student);
}

增加对象

  1. 接口
1
public void addStudent (Student student);
  1. 映射文件
1
2
3
4
<insert id="insertStudent" parameterClass="Student">
insert into Student (sid,sname,major,birth,score)
values (#sid#,#sname#,#major#,#birth#,#score#);
</insert>
  1. 实现类
1
2
3
4
5
6
7
public void addStudent(Student student) {
try {
sqlMapClient.insert("insertStudent",student);
} catch (SQLException e) {
e.printStackTrace();
}
}
  1. 测试
1
2
3
4
5
6
7
8
9
10
public static void main(String[] args) {
IStudentDAO dao = new IStudentDAOImpl();
Student student = new Student();
student.setSid(3);
student.setMajor("体育");
student.setBirth(Date.valueOf("1993-10-11"));
student.setSname("qsx");
student.setScore(919);
dao.addStudent(student);
}

删除指定id的对象

  1. 接口
1
public void deleteStudentByID(int id);
  1. 映射文件

    1
    2
    3
    4
    5
    <delete id="deleteStudentByID" parameterClass="int">
    delete
    from student
    where sid =#sid#
    </delete>
  2. 实现

1
2
3
4
5
6
7
8
// 通过id删除对象 
public void deleteStudentByID(int id) {
try { System.out.println(sqlMapClient.delete("deleteStudentByID",id));
//为了验证效果,打印影响了几行
} catch (SQLException e) {
e.printStackTrace();
}
}
  1. 测试
1
2
3
4
5
public static void main(String[] args) {
IStudentDAO dao = new IStudentDAOImpl();
//测试删除id为13的对象
dao.deleteStudentByID(13);
}

注意在映射文件的mysql语句
where sid = #sid#
后面的 #sid#
可以写成

任意内容

因为这两个#号只是占位符,会自动匹配
但是在多个值要输入的时候,就还是按照模板来写,不然还是会报错
因为错误的值会导致找不到对应对象里面的get方法

更新修改对象

  1. 接口

    1
    public void updateStudent(Student student);
  2. 映射文件

1
2
3
4
5
6
7
<update id="updateStudentByID" parameterClass="Student">
update Student
set sname=#sname#,
major=#major#,
score=#score#,
birth=#birth#
where sid=#sid# </update>

特别要注意里面set sname 、major、score、birth之间要加逗号
不然又是语法错误

  1. 实现

    1
    2
    3
    4
    5
    6
    7
    @Override // 修改对象 public void updateStudent(Student student) {
    try {
    System.out.println(sqlMapClient.update("updateStudentByID",student));
    } catch (SQLException e) {
    e.printStackTrace();
    }
    }
  2. 测试

1
2
3
4
5
6
7
8
9
10
public static void main(String[] args) {
IStudentDAO dao = new IStudentDAOImpl();
Student student =new Student();
student.setSid(2);
student.setScore(10);
student.setSname("shelhon");
student.setBirth(Date.valueOf("1993-12-30"));
student.setMajor("科学");
dao.updateStudent(student);
}

通过名字模糊查找

  1. 接口
1
public List<Student> queryStudentByName(String name);
  1. 映射文件
1
2
3
4
5
<select id="selectStudentByName" parameterClass="String" resultClass="Student">
select sid,sname,score,major,birth
from Student
where sname like '%$sname$%'
</select>

这里要注意最后的符号问题!!!

1
'%$sname$%'
  1. 实现
1
2
3
4
5
6
7
8
9
10
11
@Override 
//通过名字模糊查询
public List<Student> queryStudentByName(String name) {
List<Student> studentList=null;

try { studentList=sqlMapClient.queryForList("selectStudentByName",name);
} catch (SQLException e) {
e.printStackTrace();
}
return studentList;
}
  1. 测试
1
2
3
4
5
6
IStudentDAO dao = new IStudentDAOImpl();

for(Student student:dao.queryStudentByName("q"))
{
System.out.println(student);
}

通过序列插入对象

  1. 接口
1
public void addStudentBySequence(Student student);
  1. 映射文件
1
2
3
4
5
6
7
<insert id="addStudentBySequence" parameterClass="Student">
<selectKey resultClass="int" keyProperty="sid">
SELECT @@IDENTITY as sid
</selectKey>
insert into Student (sid, sname, major, birth, score)
value (#sid#,#sname#,#major#,#birth#,#score#)
</insert>
  1. 实现
1
2
3
4
5
6
7
8
9
10
11
@Override 
// 增加序列
public void addStudentBySequence(Student student) {
try {
//1从数据库序列中获取主键值
//2往student表中插入记录
sqlMapClient.insert("addStudentBySequence",student);
} catch (SQLException e) {
e.printStackTrace();
}
}
  1. 测试
1
2
3
4
5
6
7
Student student =new Student();
student.setSid(2);
student.setScore(100);
student.setSname("qsx");
student.setBirth(Date.valueOf("1993-12-30"));
student.setMajor("科学1");
dao.addStudentBySequence(student);

由于视频学习的是Oracle的数据库操作,然后我使用的是mysql的,所以在配置上有点不同,但是我个人觉得,MySQL数据库在添加对象的时候,没必要输入id,因为数据库的主键id可以自增,直接不输入id,表生成的时候id就会自己添加进去。效果跟这个通过序列插入对象是一样的。

优缺点

优点
与JDBC相比:

  • 减少了百分之60的代码量
  • 简单
  • 架构级性能增强
  • SQL语句和程序代码分离
  • 简化项目中的分工
  • 增强了移植性

缺点:

  • SQL需要自己写
  • 参数数量只能是一个
  • 已经出了第三代Mybatis的版本,ibatis已经落后了
Just for fun!
------------- 文章已经到尾 -------------