mybatis
一:Mybatis简介
1.名称由来
Mybatis原名叫ibatis.Mybatis一开始属于Apache,2010年从Apache转移到了GoogleCode这个组织中.
2.Mybatis概念
Mybatis是一种基于ORM模式的,作用于Dao层的轻量级框架.和Hibernate类似,也支持各种SQL语句,也支持存储过程和高级映射等操作.
3.Mybatis优点
Mybatis比Hibernate更为轻量级;
Mybatis几乎消除了所有的JDBC代码和参数的手工设置.
4.Mybatis特点
Mybatis具有比较强大的动态语句功能.而且Mybatis在JavaBean和表之间的映射关系建立方面,也更加的便捷灵活.
5.Mybatis的核心API
①.SqlSessionFactoryBuilder:
SqlSessionFactoryBuilder是整个Mybatis框架的入口,提供了一个build()方法,用来创建SqlSessionFactory对象. SqlSessionFactoryBuilder对象一般是在xml文件中通过configuration节点来进行配置.
②.SqlSessionFactory:
用来创建SqlSession.注意:该对象一般只用创建一个对象就可以,也就是不要重复创建该对象!
③.SqlSession:
SqlSession用来实现数据库的各种增删改查操作.
注意:
因为SqlSession对象不是线程安全的,所以在使用该对象的时候,要确保该对象不能被多个方法所共享,当用完该对象之后,就要把该对象close()掉.
6.Mybatis和Hibernate对比
Hibernate相对来说较重,使用和配置起来较麻烦,内存占用和资源消耗较多;Hibernate的查询效率并不突出;Hibernate的入门门槛较高.Hibernate里面的API方法及功能较多.
Mybatis相对来说较轻,.......;Mybatis学习成本较低.
Mybatis相对于Hibernate来说API较少,比较单薄.
二:Mybatis的基本使用
1.利用maven工厂导入所需要的jar包
<dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.0.7</version> </dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.2.7</version> </dependency>
2:创建db.properties.xml文件
该文件用来简化数据库的连接配置,以后数据库有更改,直接在这个文件里面修改即可,可以添加多种不同的数据库。我的如下
mysql.driver=com.mysql.jdbc.Driver mysql.url=jdbc:mysql://localhost:3306/sql05 mysql.username=root mysql.password=123 orcl.driver=oracle.jdbc.driver.OracleDriver orcl.url=jdbc:oracle:thin:@localhost:1521:orcl orcl.username=scott orcl.password=123
3.创建mybatis.xml配置文件
首先引用db.properties.xml文件,
就可以引用db.properties的配置文件了。
如果是mysql的数据库的话,就加载mysql_conn
管理数据源的时候
<property name="driver" value="${mysql.driver}" /> <property name="url" value="${mysql.url}" /> <property name="username" value="${mysql.username}" /> <property name="password" value="${mysql.password}" />
mysql.driver一些分别对应着之前写db.properties配置文件。
接着加载映射文件,加载的映射文件用于配置数据库链接的一些操作
<!-- 加载映射文件 --> <mappers> <mapper resource="PersonMapper.xml"/> </mappers>
4.创建PersonMapper.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"> <!-- namespace:这里的值,可以随便写!但是要保证它的值唯一.一般开发过程中,都是JavaBean的全路径. --> <mapper namespace="com.syc.dao.domain.Person"> <!-- type:要操作的JavaBean的全路径 --> <!-- resultMap:建立起JavaBean和表的映射关系 --> <!-- 直接引用别名 --> <resultMap type="person" id="personMap"> <!-- id:表示主键 --> <id column="pid" property="pid" /> <!-- result:普通列 --> <result column="name" property="name" /> <result column="nickname" property="nickname" /> </resultMap> <!-- insert:添加操作的标签,id:用来引用该标签 --> <insert id="insertPerson"> insert into person (name,nickname) values('王小二','店小二') </insert> <!-- 带参数的标签 --> <insert id="insertPersonWithParams" parameterType="person"> insert into person (name,nickname) values(#{name},#{nickname}) </insert> <!-- 查询标签 --> <!-- resultMap:集合的泛型类 --> <select id="findAll" resultMap="personMap"> select * from person </select> <select id="findById" resultType="person" parameterType="int"> select * from person where pid=#{pid} </select> <!-- 修改 --> <update id="updateById" parameterType="person"> update person set name=#{name},nickname=#{nickname} where pid=#{pid} </update> <!-- 删除 --> <delete id="deleteById" parameterType="person"> delete from person where pid=#{pid} </delete> <!-- 注意:除了查询之外,其他的操作,增删改操作的,起始和标签名称没有关系! --> <delete id="insertWithDeleteTag" parameterType="person"> insert into person (name,nickname) values(#{name},#{nickname}) </delete> </mapper>
5.创建MybatisUtil工具类,加载配置文件
package com.syc.dao.utils; 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 { private static SqlSessionFactory factory; // 解决资源争抢问题. private static ThreadLocal<SqlSession> localSessions = new ThreadLocal<SqlSession>(); static { Reader reader = null; try { // 加载Mybatis的配置文件 reader = Resources.getResourceAsReader("mybatis.xml"); // 创建SqlSessionFactory对象. factory = new SqlSessionFactoryBuilder().build(reader); } catch (IOException e) { e.printStackTrace(); } finally { if (reader != null) { try { reader.close(); } catch (IOException e) { e.printStackTrace(); } } } } // 获取Session对象 public static SqlSession getSession() { SqlSession session = localSessions.get(); if (session == null) { session = factory.openSession(); localSessions.set(session); } return session; } // 关闭session的方法 public static void closeSession() { SqlSession session = localSessions.get(); if (session != null) { session.close(); localSessions.remove(); } } }
创建session对象:
6.创建Person类。
private Integer pid; //id private String name; //姓名 private String nickname; //称呼
7.创建PersonDao类,执行具体的CRUD操作
三: Mybatis配置简化改造
1. 简化数据库连接配置
前面提到了,就是创建一个db.properties.xml配置文件,因为做项目后东西太多,需要一个特定的配置文件去管理,而且数据库使用可能会运用到多个,修改项目时候,在特定的配置文件中修改会更加便捷。mysql和orcal的配置如下,如果当你要调用什么数据库的时候,就加载哪个
mysql.driver=com.mysql.jdbc.Driver mysql.url=jdbc:mysql://localhost:3306/sql05 mysql.username=root mysql.password=123 orcl.driver=oracle.jdbc.driver.OracleDriver orcl.url=jdbc:oracle:thin:@localhost:1521:orcl orcl.username=scott orcl.password=123
2.设置类型别名
3.简化id的引用
因为做项目的时候,有时候包名过多,可能自己填写的时候难免字母会填写错误,给调试出问题带来不必要的麻烦。
四.Mybatis利用标签使用CRUD
1.动态添加
2. 查询操作
<!-- 查询标签 --> <!-- resultMap:集合的泛型类 --> <select id="findAll" resultMap="personMap"> select * from person </select> <select id="findById" resultType="person" parameterType="int"> select * from person where pid=#{pid} </select>
3.修改操作
<!-- 修改 --> <update id="updateById" parameterType="person"> update person set name=#{name},nickname=#{nickname} where pid=#{pid} </update>
4.删除操作
<!-- 删除 --> <delete id="deleteById" parameterType="person"> delete from person where pid=#{pid} </delete>
5.注意:
真正的增删改和标签名没有关系!只和里面的sql语句有关!
<!-- 注意:除了查询之外,其他的操作,增删改操作的,起始和标签名称没有关系! --> <delete id="insertWithDeleteTag" parameterType="person"> insert into person (name,nickname) values(#{name},#{nickname}) </delete>
五:运行测试结果
1.测试数据库链接成功与否
@Test public void test1() { SqlSession session = MybatisUtil.getSession(); Connection conn = session.getConnection(); // Mybatis中可以执行原生的SQL语句! if (conn != null) { System.out.println("数据库已建立连接!"); } else { System.out.println("数据库未建立连接!"); } }
2.添加数据
@Test public void test2(){ PersonDao dao = new PersonDao(); int result = dao.insertPerson(); if (result>0) { System.out.println("添加成功"); } }
PersonMapper.xml对应配置:
<!-- insert:添加操作的标签,id:用来引用该标签 --> <insert id="insertPerson"> insert into person (name,nickname) values('王小二','店小二') </insert>
查询数据库后多了这条数据:
还有一种带参数的标签添加数据
@Test public void test3(){ PersonDao dao = new PersonDao(); Person p = new Person(); p.setName("林冲"); p.setNickname("豹子头"); int result = dao.insertPersonWithParams(p); if (result>0) { System.out.println("添加成功"); } }
测试很多就不一一测试了,DaoTest源码如下
package com.syc.dao.test; import java.sql.Connection; import java.util.List; import org.apache.ibatis.session.SqlSession; import org.junit.Test; import com.syc.dao.dao.PersonDao; import com.syc.dao.domain.Person; import com.syc.dao.utils.MybatisUtil; public class DaoTest { @Test public void test1() { SqlSession session = MybatisUtil.getSession(); Connection conn = session.getConnection(); // Mybatis中可以执行原生的SQL语句! if (conn != null) { System.out.println("数据库已建立连接!"); } else { System.out.println("数据库未建立连接!"); } } @Test
public void test2(){
PersonDao dao = new PersonDao();
int result = dao.insertPerson();
if (result>0) {
System.out.println("添加成功");
}
} @Test public void test3() { PersonDao dao = new PersonDao(); Person p = new Person(); p.setName("林冲"); p.setNickname("豹子头"); int result = dao.insertPersonWithParams(p); if (result > 0) { System.out.println("添加成功!"); } } @Test public void test4(){ PersonDao dao = new PersonDao(); List<Person> persons =dao.findAll(); for (Person p : persons) { System.out.println("name="+p.getName()); } } @Test public void test5() { PersonDao dao = new PersonDao(); Person person = dao.findById(2); System.out.println("name=" + person.getName()); } @Test public void test6(){ PersonDao dao = new PersonDao(); Person person = new Person(); person.setPid(6); person.setName("时迁"); person.setNickname("鼓上蚤"); int result = dao.updateById(person); if (result>0) { System.out.println("修改成功"); } } @Test public void test7(){ PersonDao dao = new PersonDao(); Person p = new Person(); p.setPid(6); int result= dao.deleteById(p); if (result>0) { System.out.println("删除成功"); } } @Test public void test8(){ PersonDao dao = new PersonDao(); Person p = new Person(); p.setName("宋江"); p.setNickname("及时雨"); int result = dao.insertWithDeleteTag(p); if (result>0) { System.out.println("添加成功"); } } }
PersonDao的CURD操作的代码如下
package com.syc.dao.dao; import java.util.List; import org.apache.ibatis.session.SqlSession; import com.syc.dao.domain.Person; import com.syc.dao.utils.MybatisUtil; public class PersonDao { public int insertPerson(){ SqlSession session = null; try { session = MybatisUtil.getSession(); //Mybatis中默认自动开启了事务. //命名空间+某个标签的id! //return session.insert("com.syc.dao.domain.Person.insertPerson") //简化id的引用 return session.insert(Person.class.getName()+".insertPerson"); } catch (Exception e) { e.printStackTrace(); session.rollback(); }finally { //提交事务 session.commit(); MybatisUtil.closeSession(); } return 0; } //带参数的添加操作 public int insertPersonWithParams(Person person){ SqlSession session =null; try { session =MybatisUtil.getSession(); //简化id的引用 return session.insert(Person.class.getName()+".insertPersonWithParams",person); } catch (Exception e) { e.printStackTrace(); session.rollback(); }finally { //提交事务 session.commit(); MybatisUtil.closeSession(); } return 0; } //查询全部 public List<Person> findAll(){ SqlSession session =null; try { session = MybatisUtil.getSession(); //简化id的引用 return session.selectList(Person.class.getName()+".findAll"); } catch (Exception e) { e.printStackTrace(); session.rollback(); }finally { //提交事务 session.commit(); MybatisUtil.closeSession(); } return null; } public Person findById(int pid){ SqlSession session = null; try { session = MybatisUtil.getSession(); //简化id的引用 return session.selectOne(Person.class.getName()+".findById",pid); } catch (Exception e) { e.printStackTrace(); session.rollback(); }finally { //提交事务 session.commit(); MybatisUtil.closeSession(); } return null; } public int updateById(Person person){ SqlSession session =null; try { session = MybatisUtil.getSession(); //简化id的引用 return session.update(Person.class.getName()+".updateById",person); } catch (Exception e) { e.printStackTrace(); session.rollback(); }finally { //提交事务 session.commit(); MybatisUtil.closeSession(); } return 0; } public int deleteById(Person person){ SqlSession session =null; try { session = MybatisUtil.getSession(); //简化id的引用 return session.delete(Person.class.getName()+".deleteById",person); } catch (Exception e) { e.printStackTrace(); session.rollback(); }finally { //提交事务 session.commit(); MybatisUtil.closeSession(); } return 0; } public int insertWithDeleteTag(Person person){ SqlSession session=null; try { session = MybatisUtil.getSession(); //简化id的引用 return session.insert(Person.class.getName()+"insertWithDeleteTag",person); } catch (Exception e) { e.printStackTrace(); session.rollback(); }finally { //提交事务 session.commit(); MybatisUtil.closeSession(); } return 0; } }