MyBatis 世界上流行最普遍的基於SQ語句的ORM框架,由Clinton Begin 在2002 年建立,其後,捐獻給了Apache基金會,成立了iBatis 項目。2010 年5 月,將代碼庫遷致Google Code,並改名爲MyBatis.java
MyBatis是一個靈活的DAO層解決方案,知足較高的性能要求,能夠在不少場合使用,但通常如下場合不建議使用:mysql
使用的不是關係數據庫web
新建java項目或web 項目。sql
導入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"> <!--事務管理類型主要有jdbc和managed,前者依賴於數據源得到的鏈接,後者依賴於容器 --> <transactionManager type="JDBC" /> <dataSource type="POOLED"> <property name="driver" value="com.mysql.jdbc.Driver" /> <!-- 若是數據庫設置爲UTF-8,則URL參數鏈接須要添加?useUnicode=true&characterEncoding=UTF-8,以下 --> <property name="url" value="jdbc:mysql://localhost:3306/mybatis?useUnicode=true&characterEncoding=UTF-8" /> <property name="username" value="***" /> <property name="password" value="***" /> </dataSource> </environment> </environments> </configuration>
drop database if exists mybatis; create database mybatis CHARACTER SET UTF8; use mybatis; create table dept( dept_id int primary key auto_increment, dept_name varchar(50), dept_address varchar(50) ); insert into dept(dept_name,dept_address) values('研發部一部','廣州'); insert into dept(dept_name,dept_address) values('研發部二部','廣州'); insert into dept(dept_name,dept_address) values('研發部三部','深圳'); select * from dept;
public class Dept implements Serializable { private Integer deptId; //部門編號 private String deptName;//部門名稱 private String deptAddress;//部門地址 public Integer getDeptId() { return deptId; } public void setDeptId(Integer deptId) { this.deptId = deptId; } public String getDeptName() { return deptName; } public void setDeptName(String deptName) { this.deptName = deptName; } public String getDeptAddress() { return deptAddress; } public void setDeptAddress(String deptAddress) { this.deptAddress = deptAddress; } @Override public String toString() { return "Dept [deptId=" + deptId + ", deptName=" + deptName + ", deptAddress=" + deptAddress + "]"; } }
SQL映射文件:DeptMapper.xml(能夠參考用戶手冊)session
<?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="cn.it.entity.DeptMapper"> <!-- 通常在查詢時使用--> <resultMap type="cn.it.entity.Dept" id="deptResultMap"> <id property="deptId" column="dept_id"/> <result property="deptName" column="dept_name"/> <result property="deptAddress" column="dept_address"/> </resultMap> <!-- 定義插入的sql語句,經過命名空間+id方式被定位 --> <insert id="insert" parameterType="cn.it.entity.Dept"> insert into dept(dept_name,dept_address) values(#{deptName},#{deptAddress}); </insert> </mapper> 修改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"> ………… </environments> <mappers> <mapper resource="cn/it/entity/DeptMapper.xml" /> </mappers> </configuration>
包括操做接口及實現,接口略,實現類爲:DeptDaoImpl.javamybatis
public class DeptDaoImpl { /** * 用於插入數據到dept表。 * @param dept 部門信息 * @return 表示受影響的行數 */ public int insert(Dept dept){ /* * 1.讀取配置信息 * 2.構建session工廠 * 3.建立session * 4.啓動事務(可選) * 5.數據處理 * 6.提交事務、回滾事務(可選) * 7.關閉session */ int i=0; SqlSession session=null; String config="myBatis-config.xml"; Reader reader = null; try { reader=Resources.getResourceAsReader(config); SqlSessionFactory sqlSessionFactory=new SqlSessionFactoryBuilder().build(reader); session=sqlSessionFactory.openSession(); //事務默認自動啓動 //SQL映射文件定義的命名空間+SQL語句的ID定位SQL語句,例以下的:cn.it.entity.DeptMapper.insert i=session.insert("cn.it.entity.DeptMapper.insert",dept); session.commit(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); session.rollback(); }finally{ //關閉reader對象,這裏略 session.close(); } return i; } }
須要導入junit包app
public class DeptTest { private static DeptDaoImpl deptDaoImpl; @BeforeClass public static void setUpBeforeClass() throws Exception { deptDaoImpl=new DeptDaoImpl(); } @AfterClass public static void tearDownAfterClass() throws Exception { deptDaoImpl=null; } @Test public void testInsert() { Dept dept=new Dept(); dept.setDeptName("市場部"); dept.setDeptAddress("深圳"); int i=deptDaoImpl.insert(dept); System.out.println("受影響行數:"+i); } }
對經常使用的 java 類型,已經內置了一些別名支持。這些別名都是不區分大小寫的。(詳細參看用戶手機)框架
在myBatis的主配置文件給cn.it.entity.Dept類建立別名Dept,後繼的DeptMapper.xml配置文件中可使用別名
<!-- 經過別名簡化對類的使用 --> <typeAliases> <typeAlias type="cn.it.entity.Dept" alias="Dept" /> </typeAliases>
public class MyBatisUtil { private static final ThreadLocal<SqlSession> threadLocal = new ThreadLocal<SqlSession>(); private static SqlSessionFactory sessionFactory; private static String CONFIG_FILE_LOCATION = "myBatis-config.xml"; static { try { buildSessionFactory(); } catch (Exception e) { System.err.println("%%%% Error Creating SessionFactory %%%%"); e.printStackTrace(); } } private MyBatisUtil() { } /** * Returns the ThreadLocal Session instance. Lazy initialize * the <code>SessionFactory</code> if needed. * * @return Session * @throws Exception */ public static SqlSession getSession() throws Exception { SqlSession session = (SqlSession) threadLocal.get(); if (session == null) { if (sessionFactory == null) { buildSessionFactory(); } session = (sessionFactory != null) ? sessionFactory.openSession() : null; threadLocal.set(session); } return session; } /** * build session factory * */ public static void buildSessionFactory() { Reader reader=null; try { reader=Resources.getResourceAsReader(CONFIG_FILE_LOCATION); sessionFactory = new SqlSessionFactoryBuilder().build(reader); } catch (Exception e) { System.err.println("%%%% Error Creating SessionFactory %%%%"); e.printStackTrace(); }finally{ try { reader.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } /** * Close the single session instance. * */ public static void closeSession(){ SqlSession session = (SqlSession) threadLocal.get(); threadLocal.set(null); if (session != null) { session.close(); } } /** * return session factory * */ public static SqlSessionFactory getSessionFactory() { return sessionFactory; } }
配置文件DeptMapper.xml使用別名, DeptDaoImpl.java新增方法使用工具類。
修改配置文件DeptMapper.xml(使用別名):
<!--parameterType="Dept"不寫時,也能自動根據代碼傳遞的參數Dept自動匹配 內容--> <insert id="insert" parameterType="Dept"> insert into dept(dept_name) values(#{deptName}); </insert>
修改DeptDaoImpl.java新增方法(使用MyBatisUtil.java工具類):
/** * @param dept 部門信息 * @return 保存信息後受影響的行數 */ public int saveDept(Dept dept) { int i = 0; try { session = MyBatisUtil.getSession(); i = session.insert("cn.it.entity.DeptMapper.insertDept", dept); session.commit(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); session.rollback(); } finally { try { MyBatisUtil.closeSession(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } return i; }
修改配置文件deptMapper.xml,添加
<update id="update" parameterType="Dept"> update dept set dept_name=#{deptName} ,dept_address=#{deptAddress} where dept_id=#{deptId} </update>
修改DeptDaoImpl.java,添加update方法:
public int update(Dept dept){ SqlSession session = null; int i=0; try { session=MyBatisUtil.getSession(); //方法的第一個參數爲DeptMapper.xml文件的命名空間+id i=session.update("cn.it.entity.DeptMapper.update",dept); System.out.println("受影響行數:"+i); session.commit(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); session.rollback(); }finally{ MyBatisUtil.closeSession(); } return i; }
修改配置文件deptMapper.xml,添加
<delete id="delete" parameterType="Dept"> delete from dept where dept_id=#{deptId} </delete>
修改DeptDaoImpl.java,添加delete方法:
public int delete(Dept dept){ int i = 0; try { session=MyBatisUtil.getSession(); //方法的第一個參數爲DeptMapper.xml文件的命名空間+id i=session.delete("cn.it.entity.DeptMapper.delete",dept); //System.out.println("受影響行數:"+i); session.commit(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); session.rollback(); }finally{ MyBatisUtil.closeSession(); } return i; }
配置deptMapper.xml文件的resultMap元素及SQL查詢語句
<!-- 表字段和實體屬性命名一致時能夠不配置 --> <resultMap id="deptResultMap" type="Dept"> <id property="deptId" column="dept_id"/> <result property="deptName" column="dept_name"/> <result property="deptAddress" column="dept_address"/> </resultMap> <!—省略其它的配置信息 --> <!—返回單條記錄,表字段和對應實體屬性命名一致時能夠不使用resultMap屬性配置,直接使用resultType="返回的全類名或別名",建議使用前者;查詢結果爲全部字段時,也能夠用*表示 --> <select id="selectOne" parameterType="int" resultMap="deptResultMap" > select dept_id, dept_name from dept where dept_id=#{deptId} </select>
修改DeptDaoImpl.java,添加selectOne方法:
public Dept selectOne(int deptId){ Dept dept=null; try { session=MyBatisUtil.getSession(); dept=(Dept)session.selectOne("cn.it.entity.DeptMapper.selectOne",deptId); System.out.println("dept:"+dept); } catch (Exception e) { e.printStackTrace(); }finally{ MyBatisUtil.closeSession(); } return dept; }
修改配置文件deptMapper.xml,添加
<!-- 返回多條記錄,返回結果配置的不是集合類型,而是集合元素的類型;參數也能夠經過Map等方式封裝 --> <select id="selectList" parameterType="Map" resultMap="deptResultMap"> select * from dept where dept_name like #{deptName} </select>
修改DeptDaoImpl.java,添加selectList方法:
public List<Dept> selectList(Map map){ List<Dept> depts=null; try { session=MyBatisUtil.getSession(); depts=session.selectList("cn.it.entity.DeptMapper.selectList",map); } catch (Exception e) { e.printStackTrace(); }finally{ MyBatisUtil.closeSession(); } return depts; }
測試類代碼:
@Test public void testSelectList() { Map map=new HashMap(); map.put("deptName", "%研%"); List<Dept> depts=deptDaoImpl.selectList(map); for(Dept dept:depts){ System.out.println("dept:"+dept); } }
建立表及庫,實體類,配置文件(參考上章節內容),如下爲建表和庫的SQL:
drop database if exists mybatis; create database mybatis CHARACTER SET UTF8; use mybatis; create table dept( dept_id int primary key auto_increment, dept_name varchar(50), dept_address varchar(50) ); insert into dept(dept_name,dept_address) values('研發部一部','廣州'); insert into dept(dept_name,dept_address) values('研發部二部','廣州'); insert into dept(dept_name,dept_address) values('研發部三部','深圳'); select * from dept;
修改配置文件deptMapper.xml,添加
<!-- 動態IF條件 --> <select id="selectListUseIf" parameterType="Dept" resultMap="deptResultMap"> select * from dept where 1=1 <if test="deptId!=null"> and dept_id=#{deptId} </if> <if test="deptName!=null"> and dept_name=#{deptName} </if> <if test="deptAddress!=null"> and dept_address=#{deptAddress} </if> </select>
修改DeptDaoImpl.java,添加selectListUseIf方法:
//根據參數使用配置文件的IF語句自動填充查詢的過濾條件 public List<Dept> selectListUseIf(Dept dept){ List<Dept> depts=null; try { session=MyBatisUtil.getSession(); depts=session.selectList("cn.it.entity.DeptMapper.selectListUseIf",dept); } catch (Exception e) { e.printStackTrace(); }finally{ MyBatisUtil.closeSession(); } return depts; }
修改配置文件deptMapper.xml,添加
<!-- 動態Where條件 ,通常也須要與if結合使用,與純if比較,省略了where 1=1--> <select id="selectListUseWhere" parameterType="Dept" resultMap="deptResultMap"> select * from dept <where> <if test="deptId!=null"> and dept_id=#{deptId} </if> <if test="deptName!=null"> and dept_name=#{deptName} </if> <if test="deptAddress!=null"> and dept_address=#{deptAddress} </if> </where> </select>
修改配置文件deptMapper.xml,添加
<!-- 動態choose條件 ,以下配置,能夠完成沒有選擇條件時,查找不出任何數據 --> <select id="selectListUseChoose" parameterType="Dept" resultMap="deptResultMap"> select * from dept where 1=1 <choose> <when test="deptId!=null">and dept_id=#{deptId}</when> <when test="deptName!=null">and dept_name=#{deptName}</when> <when test="deptAddress!=null">and dept_address=#{deptAddress}</when> <otherwise>and !1 = 1</otherwise> </choose> </select>
修改配置文件deptMapper.xml,添加
<!--動態set語句能夠用來更新數據 --> <update id="updateUseSet" parameterType="Dept"> update dept <set> <if test="deptName!=null">dept_name=#{deptName},</if> <if test="deptAddress!=null">dept_address=#{deptAddress},</if> </set> where dept_id=#{deptId} </update>
修改配置文件deptMapper.xml,添加
< <!-- 定義根據多個部門ID查詢部門相關部門信息的SQL語句 ,resultMap的值是指集合裏元素的類型,parameterType不用指定 --> <select id="selectListUseForeach" parameterType="Integer[]" resultMap="deptResultMap"> select * from dept where dept_id in <!-- collection="array或list",array用來對應參數爲數組,list對應參數爲 集合 --> <foreach collection="array" item="deptId" open="(" separator="," close=")"> #{deptId} </foreach> </select>
修改配置文件deptMapper.xml,添加
<!-- 使用include語句動態插入表的字段及對應的值 --> <sql id="key"> <!--suffixOverrides="," 能夠忽略最後「,」號 --> <trim suffixOverrides=","> <if test="deptName!=null"> dept_name, </if> <if test="deptAddress!=null"> dept_address, </if> </trim> </sql> <sql id="value"> <trim suffixOverrides="," > <if test="deptName!=null"> #{deptName}, </if> <if test="deptAddress!=null"> #{deptAddress}, </if> </trim> </sql> <insert id="insertUseInclude" parameterType="Dept"> insert into dept( <include refid="key" /> ) values( <include refid="value"/> ) </insert>