1,MyBatis简介
MyBatis 是支持普通 SQL查询,存储过程和高级映射的优秀持久层框架。MyBatis 消除了几乎所有的JDBC代码和参数的手工设置以及结果集的检索。MyBatis 使用简单的 XML或注解用于配置和原始映射,将接口和 Java 的POJOs(Plain Ordinary Java Objects,普通的 Java对象)映射成数据库中的记录。
2,搭建MyBatis框架
首先就是导入MyBatis.jar的jar包,然后把jar包和数据库连接的包放置到项目的lib目录下。笔者这里使用的是Oracle数据库。
项目结构图如下:
上面这张图片是整个项目结构,下面开始建立文件。
sqlmap-config.xml文件:
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration PUBLIC "-//ibatis.apache.org//DTD Config 3.0//EN" "http://ibatis.apache.org/dtd/ibatis-3-config.dtd"> <configuration> <!--引入数据库信息文件--> <properties resource="db.properties" /> <environments default="environment"> <environment id="environment"> <transactionManager type="JDBC" /> <dataSource type="POOLED"> <property name="driver" value="${driverClassName}" /> <property name="url" value="${url}"/> <property name="username" value="${username}" /> <property name="password" value="${password}" /> </dataSource> </environment> </environments> <!-- 加载SQL定义文件 --> <mappers> <mapper resource="cn/test/sql/DeptMapper.xml" /> </mappers> </configuration>
DeptMapper.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="cn.test.mapper.DeptMapper"> <!-- 查询操作--> <select id="findAll" resultType="cn.test.entity.Dept"> select * from DEPT </select> <select id="findById" resultType="cn.test.entity.Dept" parameterType="int"> select * from DEPT where DEPTNO=#{no} </select> <!--增加操作--> <insert id="save" parameterType="cn.test.entity.Dept"> <!--#{deptno},#{dname},#{loc} 对应着Dept类中变量名称--> insert into DEPT(DEPTNO,DNAME,LOC) values (#{deptno},#{dname},#{loc}) </insert> <!--修改操作--> <update id="upadteNameByNo" parameterType="java.util.Map"> <!--在map集合中,必需存在两个key,分别为name和no--> update DEPT set dname=#{name} where deptno=#{no} </update> <update id="update" parameterType="cn.test.entity.Dept"> update DEPT set DNAME=#{dname},LOC=#{loc} where DEPTNO=#{deptno} </update> <!-- 如果parameterType为单个值,#{标识符}表达式标识符没有约定 --> <delete id="delete" parameterType="int"> delete from DEPT where DEPTNO=#{id} </delete> </mapper>
在文件中我们看见 #{deptno} 的代码,表示Dept类实例中的deptno变量。这里除了写成 #{deptno} 还可以写成 ${deptno} 。两者的区别就是#在底层是采用SQL语句预编译插入参数的,$在底层是采用拼接SQL语句插入参数的。
db.properties文件:
driverClassName=oracle.jdbc.OracleDriver
url=jdbc:oracle:thin:@localhost:1521:xe
password=517839
username=system
Dept.java文件:
package cn.test.entity;
import java.io.Serializable;
import org.apache.ibatis.type.Alias;
public class Dept implements Serializable{
private int deptno;
private String dname;
private String loc;
public int getDeptno() {
return deptno;
}
public void setDeptno(int deptno) {
this.deptno = deptno;
}
public String getDname() {
return dname;
}
public void setDname(String dname) {
this.dname = dname;
}
public String getLoc() {
return loc;
}
public void setLoc(String loc) {
this.loc = loc;
}
@Override
public String toString() {
return "Dept [deptno=" + deptno + ", dname=" + dname + ", loc=" + loc + "]";
}
}
该实体类的建立,其中实体类的变量名称必须和数据库中表的字段名称一致,否则通过反射就不能赋上正确的值。还有一个小细节,如果数据库中对应表的字段类型为NUMBER,那么在实体类中最好声明为Integer类,而不是基本数据类型int,不过这误伤大雅,因为自从JDK1.5开始支持了自动装箱和自动拆箱了。
笔者的数据库中Dept表结构如下:
DeptMapper.java文件:
package cn.test.mapper; import java.util.List; import java.util.Map; import cn.test.entity.Dept; /** * 方法定义参考 SQL 定义的 id 、 parameterType 、 resultType 属性 * @author Administrator * 1. 方法名与 id 属性一致 * 2. 参数类型与 parameterType 属性一致 * 3. 返回结果:多行查询 List<resultType> ;单行查询 resultType ;增删改为 void 或 int * 4.SQL 定义文件中 namespace="cn.test.mapper.DeptMapper" */ public interface DeptMapper { public List<Dept> findAll(); public Dept findById(int id); public int save(Dept dept); public int update(Dept dept); public int delete(int id); public int upadteNameByNo(Map map); }
该接口中所有方法,都必须和DeptMapper.xml中配置的语句方法相对应。语法为id对应方法名,resultType对应返回值类型(如果有多个结果,可以加上List集合),parameterType为参数类型。比如DeptMapper.xml文件中的:
<select id="findById" resultType="cn.test.entity.Dept" parameterType="int"> select * from DEPT where DEPTNO=#{no} </select>
应该在DeptMapper.java中对应一个方法:
public Dept findById(int id);
MyBatisUtil.java文件:
package cn.test.util; import java.io.IOException; import java.io.Reader; import org.apache.ibatis.io.Resources; import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.session.SqlSessionFactoryBuilder; public class MyBatisUtil { public static SqlSession getSession() throws IOException{ SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder(); Reader reader = Resources.getResourceAsReader("sqlmap-config.xml"); SqlSessionFactory factory = builder.build(reader); SqlSession session = factory.openSession(); return session; } }
这是一个简单的工具类,该工具用于简化SqlSession对象的获取。
MyBatisTest.java文件:
package cn.test.test; import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.ibatis.session.SqlSession; import org.junit.Test; import cn.test.entity.Dept; import cn.test.mapper.DeptMapper; import cn.test.util.MyBatisUtil; public class MyBatisTest { @Test public void testName1() throws Exception { SqlSession session = MyBatisUtil.getSession(); DeptMapper deptDao=session.getMapper(DeptMapper.class); Map map=new HashMap(); map.put("name", "'goslings'"); map.put("no",40); //通过编号更新部门名称 deptDao.upadteNameByNo(map); //查询所有信息 List<Dept> list=deptDao.findAll(); for(Dept d:list){ System.out.println(d); } //提交事务,mybatis默认不提交 session.commit(); session.close(); } }
MyBatis提交事务默认是关闭的,也就是需要手动提交, session.commit(); 。可以进行一些设置,使得Mybatis自动提交事务。
这样为止,一个简单的MyBatis框架就搭建好了。