【mybatis】mybatis入门

来源:互联网 发布:淘宝地址转换微信 编辑:程序博客网 时间:2024/05/16 03:34


jdbc:

1)优点:简单易学,上手快,非常灵活构建SQL,效率高

2)缺点:代码繁琐,难以写出高质量的代码(例如:资源的释放,SQL注入安全性等)

开发者既要写业务逻辑,又要写对象的创建和销毁,必须管底层具体数据库的语法

(例如:分页)。

3)适合于超大批量数据的操作,速度快


hibernate:

1)优点:不用写SQL,完全以面向对象的方式设计和访问,不用管底层具体数据库的语法,(例如:分页)便于理解。

2)缺点:处理复杂业务时,灵活度差, 复杂的HQL难写难理解,例如多表查询的HQL语句

3)适合于中小批量数据的操作,速度慢


为什么要用mybatis?

1)基于上述二种支持,我们需要在中间找到一个平衡点呢?结合它们的优点,摒弃它们的缺点,

这就是myBatis,现今myBatis被广泛的企业所采用。


什么是mybatis?

1)MyBatis 本是apache的一个开源项目iBatis,2010年这个项目由apachesoftware foundation 迁移到了google code,并且改名为MyBatis201311月迁移到Github

2)iBATIS一词来源于“internet”“abatis”的组合,是一个基于Java的持久层框架。iBATIS提供的持久层框架包括SQLMapsDataAccess ObjectsDAO

3)jdbc/dbutils/springdao,hibernate/springorm,mybaits同属于ORM解决方案之一


如何使用mybatis?

首先创建一个web项目,导入mybatis相关的jar包


下面是数据库驱动包


然后项目结构如下:



首先我们在数据库中创建相应的表

mysql

create table students(   id  int(5) primary key,   name varchar(10),   sal double(8,2));

oracle

create table students(   id  number(5) primary key,   name varchar2(10),   sal number(8,2));

然后创建实体类Student

package cn.qblank.entity;public class Student {private int id;private String name;private double sal;public Student(){}public String getName() {return name;}public void setName(String name) {this.name = name;}public double getSal() {return sal;}public void setSal(double sal) {this.sal = sal;}public int getId() {return id;}public void setId(int id) {this.id = id;}public Student(int id, String name, double sal) {super();this.id = id;this.name = name;this.sal = sal;}}

在entity目录下创建一个StudentMapper.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:名称 空间,必须唯一 --><mapper namespace="cn.qblank.entity.Student"><!-- resultMap标签:映射实体和表 type:表示实体全路径id:表示result的唯一标识--><resultMap type="student" id="studentMap"><!-- 实体属性property 表属性:column --><id property="id" column="id"/><result property="name" column="name"/><result property="sal" column="sal"/></resultMap><!-- insert标签:要书写insert这么一个sql语句id属性:为insert这么一个sql语句取一个任意唯一的名字parameterType:要执行的dao中的方法的参数,如果是类的话,必须使用全路径类--><insert id="add1">insert into students(id,name,sal) values(1,'evan_qb',7000)</insert><insert id="add2" parameterType="cn.qblank.entity.Student">insert into students(id,name,sal) values(#{id},#{name},#{sal})</insert></mapper>

然后再src目录下创建总配置文件mybatis.xml、以及数据库配置文件db.properties

<?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><!-- 加载类路径下的属性 --><properties resource="db.properties"></properties><!-- 设置类型别名 --><typeAliases><typeAlias type="cn.qblank.entity.Student" alias="student"/></typeAliases><!-- 设置一个默认的连接配置 --><environments default="mysql_developer"><environment id="mysql_developer"><!-- 进行事务管理 --><transactionManager type="jdbc"></transactionManager><!-- 使用连接池方式来获取连接 --><dataSource type="pooled"><!-- 配置数据库的连接配置 --><property name="driver" value="${mysql.driver}"/><property name="url" value="${mysql.url}"/><property name="username" value="${mysql.username}"/><property name="password" value="${mysql.password}"/></dataSource></environment><environment id="oracle_developer"><!-- 进行事务管理 --><transactionManager type="jdbc"></transactionManager><!-- 使用连接池方式获取连接 --><dataSource type="pooled"><!-- 数据库连接池配置 --><property name="driver" value="${oracle.driver}"/><property name="url" value="${oracle.url}"/><property name="username" value="${oracle.username}"/><property name="password" value="${oracle.password}"/></dataSource></environment></environments><!-- 加载映射文件 --><mappers><mapper resource="cn/qblank/dao/StudentMapper.xml"/></mappers></configuration>

在util包下创建MybatisUtil工具类用于创建SqlSession和关闭SqlSession

package cn.qblank.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 {//创建工厂类private static SqlSessionFactory sqlSessionFactory;private static ThreadLocal<SqlSession> threadLocal = new ThreadLocal<>();/** * 加载配置文件mybatis.xml */static{try {Reader reader = Resources.getResourceAsReader("mybatis.xml");sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);} catch (IOException e) {e.printStackTrace();}}/** * 禁止外界new出对象 */private MybatisUtil(){}/** * 获取SqlSession * @return */public static SqlSession getSqlSession(){//从当前线程中获取SqlSession对象SqlSession sqlSession = threadLocal.get();//如果为空if (sqlSession == null) {//通过SqlSessionFactory获取对象sqlSession = sqlSessionFactory.openSession();//将SqlSession对象和当前线程绑定在一起threadLocal.set(sqlSession);}return sqlSession;}/** * 关闭SqlSession并与当前线程解绑 */public static void closeSqlSession(){//先从当前线程中获取sqlSession对象SqlSession sqlSession = threadLocal.get();if (sqlSession != null) {//关闭sqlSessionsqlSession.close();//解绑threadLocal.remove();}}}

接下来我们需要用到动态代理(JDK代理),所以我们首先创建一个IStudentDao接口

package cn.qblank.dao;import cn.qblank.entity.Student;/** * 接口 * @author Administrator * */public interface IStudentDao {void add1();void add2(Student student);}

在proxy包下创建代理工厂类

package cn.qblank.proxy;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.lang.reflect.Proxy;import org.apache.ibatis.session.SqlSession;import cn.qblank.util.MybatisUtil;public class ProxyFactory {//维护一个目标对象private Object target;public ProxyFactory(Object target){this.target = target;}//给目标对象生成地代理对象public Object getProxyInstance(){return Proxy.newProxyInstance(target.getClass().//指定当前类使用的加载器getClassLoader()//目标对象实现的接口,target.getClass().getInterfaces(), new InvocationHandler() {@Overridepublic Object invoke(Object proxy, Method method, Object[] args)throws Throwable {SqlSession sqlSession = null;Object returnValue = null;try {sqlSession = MybatisUtil.getSqlSession();//开启事务(默认开始)//执行方法returnValue = method.invoke(target, args);//事务提交sqlSession.commit();System.out.println("代理成功!!!!!");} catch (Exception e) {e.printStackTrace();//事务回滚sqlSession.rollback();}finally{MybatisUtil.closeSqlSession();}return returnValue;}});}}

创建一个StudentDao实现IStudentDao接口

package cn.qblank.dao;import org.apache.ibatis.session.SqlSession;import cn.qblank.entity.Student;import cn.qblank.proxy.ProxyFactory;import cn.qblank.util.MybatisUtil;public class StudentDao implements IStudentDao{private SqlSession sqlSession = null;public static void main(String[] args) throws Exception {//创建目标对象IStudentDao dao = new StudentDao();//构建代理对象IStudentDao proxy = (IStudentDao) new ProxyFactory(dao).getProxyInstance();proxy.add1();proxy.add2(new Student(2, "evan_qb2", 4000.0));}/** * 添加学生   实现方式一:无参 * @throws Exception */@Overridepublic void add1(){//次数使用动态JDK代理sqlSession = MybatisUtil.getSqlSession();//读取StudentMapping中的Sql语句int i = sqlSession.insert("cn.qblank.entity.Student.add1");System.out.println("影响了" + i + "行");}/** * 添加学生   方式一:有参数方法: * @throws Exception */@Overridepublic void add2(Student student){//次数使用动态JDK代理sqlSession = MybatisUtil.getSqlSession();//读取StudentMapper.xml映射文件中的SQL语句int i = sqlSession.insert(Student.class.getName() + ".add2",student);System.out.println("影响了" + i + "行");}}

然后我们通过StudentDao下的main方法运行一下,结果如下:



可以看到插入成功,这样我们就完成了第一个mybatis案例

总结下mybatis的工作流程

1) 通过Reader对象读取src目录下的mybatis.xml配置文件(名字可以随便写)

2) 通过SqlSessionFactoryBuilder对象创建SqlSessionFactory对象(SqlSession工厂)

3)  从当前线程中获取SqlSession对象

4) 事务开始,在mybatis中默认

5) 通过SqlSession对象读取StudentMapper.xml映射文件中的操作编号,从而读取sql语句

6) 事务提交(提交必写)

7) 关闭SqlSession对象,并且分开当前线程与SqlSession对象,让GC尽早回收。