0
点赞
收藏
分享

微信扫一扫

SSM框架中项目Model层:MyBatis

绪风 2022-02-10 阅读 43

目录

MyBatis

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

MyBatis解决的主要问题:减轻JDBC的复杂性,不用编写重复的创建ConnectionStatement,不用编写关闭资源代码。

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 通过使用内置的日志工厂提供日志功能。内置日志工厂将会把日志工作委托给下面的实现之一:

  • SLF4J
  • Apache Commons Logging
  • Log4j 2
  • Log4j (deprecated since 3.5.9)
  • JDK logging

在主xml文件中

<configuration>
  <settings>
    ...
    <setting name="logImpl" value="LOG4J"/>
    ...
  </settings>
</configuration>

logImpl 可选的值有:SLF4JLOG4JLOG4J2JDK_LOGGINGCOMMONS_LOGGINGSTDOUT_LOGGINGNO_LOGGINGvalue指的是日志模块名。

MyBatis基础

MyBatis对象分析

Resourcesmybatis框架中的对象,一个作用读取主配置信息。

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语句,效率低
  • ${}数据是原样使用的,不会区分数据类型。

封装MyBatis输出结果

举报

相关推荐

0 条评论