目录
MyBatis
MyBatis本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation迁移到了google code,并且改名为MyBatis。
MyBatis解决的主要问题:减轻JDBC的复杂性,不用编写重复的创建Connection、Statement,不用编写关闭资源代码。
MyBatis可以完成:
- 注册数据库的驱动
 - 创建
JDBC中必须使用的对象 - 从
xml中获取sql,并执行sql语句,把ResultSet结果转化成Java对象 
<dependency>
  <groupId>org.mybatis</groupId>
  <artifactId>mybatis</artifactId>
  <version>xxx</version>
</dependency>
<dependency>
  <groupId>mysql</groupId>
  <artifactId>mysql-connector-java</artifactId>
  <version>5.1.9</version>
</dependency>
<build>
  <!-- 资源插件,处理src/main/Java目录中的xml -->
  <resources>
    <resource>
      <directory>src/main/java</directory>
      <includes>
        <include>**/*.proterties</include>
        <include>**/*.xml</include>
      </includes>
      <filtering>false</filtering>
    </resource>
  </resources>
</build>
 
MyBatis简介和配置
MyBatis的XML配置
mapper是根标签。namespace:命名空间, 必须有值,不能为空。唯一值。推荐使用Dao接口的全限定名称,作用:参与识别sql语句的作用。- 在
mapper里面可以写<insert>,<update>,<delete>,<select>等标签。<insert>里面是insert语句,<update>里面是update语句,<delete>里面是delete语句,<select>表示执行的是select操作。 
<?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="org.mybatis.example.BlogMapper">
    <!--查询一个学生Student
    <select>:表示查询操作,里 面是select语句
        id:要 执行的sql语句的唯一标识,是一 一个自定义字符串。
        推荐使用dao接口中的方法名称
    resultType:告诉mybatis,执行sql语句, 把数据赋值给那个类型的java对象。
        resultType的值现在使用的java对象的全限定名称
	-->
    <select id="com.bjpowernode.dao.StudentDao" resultType="com.bjpowernode.domain.Student">
        select id, name, email, age from Student where id=1001
    </select>
</mapper>
 
MyBatis主文件配置,XML配置文件中包含了对MyBatis系统的核心设置,包括获取数据库连接实例的数据源(DataSource)以及决定事务作用域和控制方式的事务管理器。
<?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"/>
            <!-- 配置数据源,创建connect对象 -->
            <dataSource type="POOLED">
                <!--驱动的内容-->
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <!--连接数据库的url-->
                <property name="url" value="jdbc:mysql://81.68.246.231:3306/ssm"/>
                <!--账号-->
                <property name="username" value="test"/>
                <!--密码-->
                <property name="password" value="123456"/>
            </dataSource>
        </environment>
    </environments>
    <!--指定其他mapper文件位置-->
    <mappers>
<!--        <mapper resource="org/mybatis/example/BlogMapper.xml"/>-->
        <mapper resource="com/bjpowernode/dao/StudentDao.xml"/>
    </mappers>
</configuration>
 
这个配置文件有何用?
占位符
<?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="com.bjpowernode.dao.StudentDao">
    <select id="selectStudentById" resultType="com.bjpowernode.domain.Student">
        select id, name, email, age from Student where id=# {studentid}
    </select>
</mapper>
 
// <T> T selectOne(String var1, Object var2);
Student st = session.selectOne(sqlid, 1001);
 
 
MyBatis日志
Mybatis 通过使用内置的日志工厂提供日志功能。内置日志工厂将会把日志工作委托给下面的实现之一:
SLF4JApache Commons LoggingLog4j 2Log4j (deprecated since 3.5.9)JDK logging
在主xml文件中
<configuration>
  <settings>
    ...
    <setting name="logImpl" value="LOG4J"/>
    ...
  </settings>
</configuration>
 
logImpl 可选的值有:SLF4J、LOG4J、LOG4J2、JDK_LOGGING、COMMONS_LOGGING、STDOUT_LOGGING、NO_LOGGING;value指的是日志模块名。
MyBatis基础
MyBatis对象分析
Resources:mybatis框架中的对象,一个作用读取主配置信息。
SqlSessionFactoryBuilder:负责创建SqISessionFactory对象。
SqlSessionFactory:重要对象
SqlSessionFactory是重量级对象:创建此对象需要使用更多的资源和时间。在项目 中有一个就可以了。SqlSessionFactory接口:作用是SqlSession的工厂,就是创建SqlSession对象。DefaultSqlSessionFactory实现类
SqlSession对象是通过SqlSessionFactory获取的。SqlSession本身是接口,DefaultSqlSession:实现类
工具类和模板
创建模板,mapper文件模板和mybatis主文件模板,此处略过
因为SqlSessionFactory创建较为耗时,因此创建工具类对象,来持久化运行
package com.bjpowernode.utils;
/**
 * 工具类 创建sqlsession对象
 */
import java.io.IOException;
import java.io.InputStream;
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 = null;
    static {
        String config = "mybatis.xml";
        try {
            InputStream inputStream = Resources.getResourceAsStream(config);
            factory = new SqlSessionFactoryBuilder().build(inputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    public static SqlSession getSqlSession() {
        SqlSession session = null;
        if (factory != null) {
            session = factory.openSession(true);
        }
        return session;
    }
}
 
实现接口和实现类的组合
前面都是SqlSession配合接口与.xml的配置来进行数据库的操作,此时我们采用第二种模式,接口和实现类的组合,去体现面向对象的特性
接口实现类
package com.bjpowernode.dao;
import com.bjpowernode.domain.Student;
import com.bjpowernode.utils.MyBatisUtil;
import org.apache.ibatis.session.SqlSession;
import java.util.List;
public class StudentDaoImpl implements StudentDao {
    @Override
    public Student selectById(Integer id) {
        SqlSession session = MyBatisUtil.getSqlSession();
        String sqlid = "com.bjpowernode.dao.StudentDao.selectById";
        Student st = session.selectOne(sqlid, id);
        session.close();
        return st;
    }
    @Override
    public List<Student> selectList() {
        SqlSession session = MyBatisUtil.getSqlSession();
        String sqlid = "com.bjpowernode.dao.StudentDao" + "." + "selectList";
        List<Student> st = session.selectList(sqlid);
        session.close();
        return st;
    }
}
 
测试代码
package com.bjpowernode;
import com.bjpowernode.dao.StudentDao;
import com.bjpowernode.dao.StudentDaoImpl;
import com.bjpowernode.domain.Student;
import com.bjpowernode.utils.MyBatisUtil;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;
import java.util.List;
public class MyTest {
    @Test
    public void Test() {
        StudentDao sd = new StudentDaoImpl();
        List<Student> sa = sd.selectList();
        for (Student s: sa) {
            System.out.println(s);
        }
        System.out.println("====================");
        Student sp = sd.selectById(1001);
        System.out.println(sp);
    }
}
 
输出如下
com.intellij.rt.junit.JUnitStarter -ideVersion5 -junit4 com.bjpowernode.MyTest
Logging initialized using 'class org.apache.ibatis.logging.stdout.StdOutImpl' adapter.
PooledDataSource forcefully closed/removed all connections.
PooledDataSource forcefully closed/removed all connections.
PooledDataSource forcefully closed/removed all connections.
PooledDataSource forcefully closed/removed all connections.
Opening JDBC Connection
Created connection 68326648.
==>  Preparing: select id, name, email, age from Student
==> Parameters: 
<==    Columns: id, name, email, age
<==        Row: 2, liuhao, 2226958871@qq.com, 34
<==        Row: 1, liuhao, 22234, 34
<==        Row: 1001, liuhao, 22234, 34
<==        Row: 123, lasd, qwe, 234
<==      Total: 4
Closing JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@41294f8]
Returned connection 68326648 to pool.
Student{id=2, name='liuhao', email='2226958871@qq.com', age=34}
Student{id=1, name='liuhao', email='22234', age=34}
Student{id=1001, name='liuhao', email='22234', age=34}
Student{id=123, name='lasd', email='qwe', age=234}
====================
Opening JDBC Connection
Checked out connection 68326648 from pool.
==>  Preparing: select id, name, email, age from Student where id=?
==> Parameters: 1001(Integer)
<==    Columns: id, name, email, age
<==        Row: 1001, liuhao, 22234, 34
<==      Total: 1
Closing JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@41294f8]
Returned connection 68326648 to pool.
Student{id=1001, name='liuhao', email='22234', age=34}
Process finished with exit code 0
 
进一步进行清除冗余
MyBatis代理
使用代理的要求
在.xml文件中
namespace必须是接口的全限定名称id必须是接口中的方法
MyBatis代理实现方式
使用SqlSession对象的方法getMapper(dap.class)
package com.bjpowernode;
import com.bjpowernode.dao.StudentDao;
import com.bjpowernode.domain.Student;
import com.bjpowernode.utils.MyBatisUtil;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;
import java.util.List;
public class MyTest {
    @Test
    public void Test() {
        SqlSession session = MyBatisUtil.getSqlSession();
        // 动态代理
        StudentDao dao = session.getMapper(StudentDao.class);
        Student st = dao.selectById(1001);
        System.out.println(st);
        session.close();
    }
    @Test
    public void myT() {
        SqlSession session = MyBatisUtil.getSqlSession();
        StudentDao dao = session.getMapper(StudentDao.class);
        List<Student> ss = dao.selectList();
        session.close();
    }
}
 
深入理解参数
通过java程序把数据传入到mapper文件中的sql语句
parameterType
指定dao接口形参的类型这个属性的值可以使用java类型的全限定名称或者mybatis定义的别名
<!--第一种用法 Java类型的全限定类型名称-->
<select id="selectById" parameterType="java.lang.Integer" resultType="com.bjpowernode.domain.Student">
    select id, name, email, age from Student where id=#{studentId}
</select>
 
<!--mybatis内建的别名-->
<select id="selectById" parameterType="int" resultType="com.bjpowernode.domain.Student">
    select id, name, email, age from Student where id=#{studentId}
</select>
 
<!--可不写,mybatis可以通过反射获得-->
<select id="selectById" resultType="com.bjpowernode.domain.Student">
    select id, name, email, age from Student where id=#{studentId}
</select>
 
单个简单参数
即简单数据类型
<!-- #{xxx} -->
 
多个简单参数
第一种实现方式
@Param:在方法的形参前面使用的,定义参数名。这个名称可以用在mapper文件中。
List<T> getInfo(@Param("mya")String a, @Param("myb")Integer b);
 
<!-- 使用@Param中的mybatis命名参数 -->
<select id="selectById" resultType="com.bjpowernode.domain.Student">
    select id, name, email, age from Student where id=#{mya} or age=#{myb}
</select>
 
第二种实现方式
方法的形参是一个对象,表示多个参数,使用对象的属性值作为参数使用
class Student {
    private String name;
    private Integer age;
}
 
<!-- 参数名和对象属性名一致 -->
<select id="selectById" resultType="com.bjpowernode.domain.Student">
    select id, name, email, age from Student where id=#{age} or age=#{name}
</select>
 
 
 
按位置传递参数(仅做了解,不做概述)
使用Map传递参数
Student selectById(Map<String, Object> map);
Map<String, Object> map = new HashMap<>();
map.put("myname", "liuhao");
map.put("myage", 23);
 
<!-- map的key作为xml传入名称 -->
<select id="selectById" resultType="com.bjpowernode.domain.Student">
    select id, name, email, age from Student where id=#{myage} or age=#{myname}
</select>
 
占位符#和$
#{}特点:
- 使用的
PrepareStatement对象,执行sql语句, 效率高。 - 使用的
PrepareStatement对象, 能避免sql语句,sql语句执行更安全。 #{}常常作为列值使用的,位于等号的右侧,#{}位置的值和数据类型有关的。
${字符}特点:mybatis执行${}占位符的sql语句
${}表示字符串连接,把sq1语句的其他内容和,${}内容使用字符串(+)连接的方式连在一起${}占位符的值,使用的字符串连接方式,有sql注 入的风险。有代码安全的问题- 使用
Statement对象,执行sql语句,效率低 ${}数据是原样使用的,不会区分数据类型。










