MyBatis 是当下最流行的持久层框架,也是ORM框架,本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis 。2013年11月迁移到Github。iBATIS一词来源于“internet”和“abatis”的组合,是一个基于Java的持久层框架。iBATIS提供的持久层框架包括SQL Maps和Data Access Objects(DAOs)。
其中,ORM是指对象-关系映射(OBJECT/RELATIONALMAPPING,简称ORM),是随着面向对象的软件开发方法发展而产生的。用来把对象模型表示的对象映射到基于SQL 的关系模型数据库结构中去。这样,我们在具体操作实体对象的时候,就不需要再去和复杂的 SQ L 语句打交道,只需简单地操作实体对象的属性和方法 。ORM 技术是在对象和关系之间提供了一座桥梁,前台的对象型数据和数据库中的关系型的数据通过这个桥梁来相互转化。
MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 POJOs(Plain Old Java Objects,普通的 Java对象)映射成数据库中的记录。
mybatis的特点是:
(1)简单易学:本身就很小且简单。没有任何第三方依赖,安装简单,只要两个jar文件(如:mybatis-3.2.8.jar,mysql-connector-java-5.1.7-bin.jar)+配置几个sql映射文件,易于学习,易于使用,通过文档和源代码,可以比较完全地掌握它的设计思路和实现。
(2)灵活:mybatis不会对应用程序或者数据库的现有设计强加任何影响。 sql写在xml里,便于统一管理和优化。通过sql基本上可以实现我们不使用数据访问框架可以实现的所有功能,甚至更多。
(3)解除sql与程序代码的耦合:通过提供DAL层(Data Access Layer,数据访问层),将业务逻辑和数据访问逻辑分离,使系统的设计更清晰,更易维护,更易单元测试。sql和代码的分离,也提高了可维护性。
(4)提供映射标签,支持对象与数据库的orm字段关系映射。
(5)提供对象关系映射标签,支持对象关系组建维护。
(6)提供xml标签,支持编写动态sql。
在使用mybatis时,添加mybatis所依赖的jar包。然后配置两个xml文件:
mybatis-config.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> <environments default="development"> <environment id="development"> <transactionManager type="JDBC"/> <dataSource type="POOLED"> <property name="driver" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/XXX?useUnicode=true&characterEncoding=UTF-8"/> <property name="username" value="root"/> <property name="password" value="2018"/> </dataSource> </environment> </environments> <!--这个地方也需要配一下。。 引入其他单个实体的ORM映射文件 --> <mappers> <mapper resource="config/User.xml"/> </mappers> </configuration>
User.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="User"> 保证命名空间,和接口的全类名一致,还可以下面这样写,指定一个包可以映射 --> <mapper namespace="com.itszt.dao.UserDao"> <!-- 映射表和类 --> <resultMap id="user2Map" type="user2"> <id property="uid" column="uid"></id> <result property="username1" column="username"></result> <result property="userage1" column="userage"></result> <result property="usersalary1" column="usersalary"></result> <result property="regTime1" column="regTime"></result> </resultMap> <!-- id:将来调用该功能的唯一标识,要和方法名保持一致 parameterType:传给通配的参数类型 resultType:最后返回的实体类型 #{uid}:等价于原来的问号通配 uid不是必须写的名称,我们出于见名知意 的原则这样去取名 --> <select id="findUserByUid" parameterType="int" resultType="com.itszt.User"> SELECT * FROM user WHERE uid=#{uid} </select> <!-- resultMap为映射后的类的对象 --> <select id="findUserByID" parameterType="int" resultMap="user2Map"> SELECT * FROM user WHERE uid=#{uid} </select> <!-- 传入一个实体,插入到数据库,实体的ID由java程序赋值 --> <insert id="insertTest1" parameterType="itszt.User"> INSERT INTO user VALUES (#{uid},#{username},#{userage},#{usersalary},#{regTime}); </insert> <!-- 传入一个实体,插入到数据库,实体的ID由数据库自动增加 --> <insert id="insertTest2" parameterType="itszt.User"> INSERT INTO user(username,userage,usersalary,regTime) VALUES (#{username},#{userage},#{usersalary},#{regTime}); </insert> <!-- 传入一个实体,插入到数据库,实体的ID由数据库自动增加,并且返回新插入的数据的ID --> <insert id="insertTest3" parameterType="itszt.User"> INSERT INTO user(username,userage,usersalary,regTime) VALUES (#{username},#{userage},#{usersalary},#{regTime}); <selectKey keyProperty="uid" keyColumn="uid" resultType="int" order="AFTER"> select last_insert_id(); </selectKey> </insert> <!-- 传入一个实体,插入到数据库,实体的ID由数据库自动增加,并且返回新插入的数据的ID,使用order="BEFORE" --> <insert id="insertTest4" parameterType="itszt.User2"> INSERT INTO user2 VALUES (#{uid},#{username},#{userage},#{usersalary},#{regTime}); <selectKey keyProperty="uid" keyColumn="uid" resultType="String" order="BEFORE"> select uuid() </selectKey> </insert> <!-- 查询1:传入一个匹配参数,查询返回单个实体对象 --> <select id="findUserByUid" parameterType="int" resultType="itszt.User"> SELECT * FROM user WHERE uid=#{uid} </select> <!-- 1.传入一个实体对象,删除 2.传入一个ID,根据ID进行删除 --> <delete id="deleteTest1" parameterType="itszt.User"> DELETE FROM user WHERE uid=#{uid} </delete> <!-- 更新 --> <update id="updateTest1" parameterType="itszt.User"> UPDATE user set username=#{username} ,userage=#{userage} WHERE uid=#{uid} </update> <!-- 查询1:传入一个匹配参数,查询返回单个实体对象 --> <select id="findUserByUid" parameterType="int" resultType="itszt.User"> SELECT * FROM user WHERE uid=#{uid} </select> <!-- 查询2:查询多个实体对象,排序 limit resultType:依然填写单个实体类型即可 --> <select id="findUser2" parameterType="double" resultType="itszt.User"> SELECT * FROM user WHERE usersalary>#{value} ORDER BY usersalary DESC limit 0,3 </select> <select id="findUser3" parameterType="String" resultType="itszt.User"> SELECT * FROM user WHERE username LIKE #{value}; </select> <select id="findUser4" parameterType="String" resultType="itszt.User"> SELECT * FROM user WHERE username LIKE '%${value}%'; </select> <select id="findUsersByIDArrays" parameterType="Integer[]" resultType="user"> SELECT * FROM user WHERE uid IN <foreach collection="array" open="(" close=")" separator="," item="uid"> #{uid} </foreach> </select> <!--进行抽取--> <sql id="sqlUsernamePart"> <if test="username!=null"> AND username=#{username} </if> </sql> <sql id="sqlUseragePart"> <if test="userage!=null"> AND userage=#{userage} </if> </sql> <!--演示Sql片段1--> <select id="testSqlPart1" parameterType="hashMap" resultType="user"> SELECT * FROM user WHERE 1=1 <if test="username!=null"> AND username=#{username} </if> <if test="userage!=null"> AND userage=#{userage} </if> </select> <!--演示Sql片段2--> <select id="testSqlPart2" parameterType="hashMap" resultType="user"> SELECT * FROM user <where> <if test="username!=null"> AND username=#{username} </if> <if test="userage!=null"> AND userage=#{userage} </if> </where> </select> <!--演示Sql片段3--> <select id="testSqlPart3" parameterType="hashMap" resultType="user"> SELECT * FROM user <where> <include refid="sqlUsernamePart"></include> <include refid="sqlUseragePart"></include> </where> </select> </mapper>
下面是User实体类:
package com.itszt; /** * 实体类 */ public class User { private int uid; private String username, userpwd; public int getUid() { return uid; } public void setUid(int uid) { this.uid = uid; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getUserpwd() { return userpwd; } public void setUserpwd(String userpwd) { this.userpwd = userpwd; } @Override public String toString() { return "User{" + "uid=" + uid + ", username='" + username + '\'' + ", userpwd='" + userpwd + '\'' + '}'; } }
测试类:
import com.itszt.User; import org.apache.ibatis.io.Resources; import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.session.SqlSessionFactoryBuilder; import java.io.IOException; import java.io.InputStream; /** * 测试类 */ public class Test { public static void main(String[] args) throws IOException { //1.基于全局配置文件,加载出一个SqlSessionFactory对象 String resource = "config/mybatis-config.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); //2.通过SqlSessionFactory,来获取一个SqlSession,将来我们对于数据库的操作,都是通过SqlSession完成的 SqlSession sqlSession = sqlSessionFactory.openSession(); //3.基于sqlsession调用我们之前在xml中配置好的功能 User user=sqlSession.selectOne("User.findUserByUid",4); System.out.println("user = " + user); //4.释放资源 sqlSession.close(); } }
MyBatis 是当下最流行的持久层框架,也是ORM框架,本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis 。2013年11月迁移到Github。
iBATIS一词来源于“internet”和“abatis”的组合,是一个基于Java的持久层框架。iBATIS提供的持久层框架包括SQL Maps和Data Access Objects(DAOs)