MyBatis笔记

1.简单入门

中文文档:https://mybatis.org/mybatis-3/zh/getting-started.html
1.创建数据库表
create database `mybatis`;
use `mybatis`;


create table `user`(
	`id` int(10) not null primary key,
	`username` varchar(30) default null,
	`password` varchar(30) default null

) engine=innodb charset=utf8;
insert into `user`(`id`,`username`,`password`) values
		(1,'snow','666666'),
		(2,'rain','666666'),
		(3,'sunny','666666')
2.创建一个maven项目

导入依赖

 <dependencies>
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.2</version>
        </dependency>
        <!--junit-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
        </dependency>

        <!--    mysql依赖-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.47</version>
        </dependency>

3.核心配置文件

resource下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">
        <environment id="development">
<!--            失误管理com-->
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
<!--              &amp;相当于转义符-->
                <property name="url" value="jdbc:mysql://localhost:3306/mybatis?useSSL=true&amp;serverTimezone=UTC&amp;useUnicode=true&amp;characterEncoding=utf8"/>
                <property name="username" value="root"/>
                <property name="password" value="196"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <mapper resource="org/mybatis/example/BlogMapper.xml"/>
    </mappers>
</configuration>
4.sqlsessionFactory解读

官网上说:

从 XML 中构建 SqlSessionFactory

每个基于 MyBatis 的应用都是以一个 SqlSessionFactory 的实例为核心的。SqlSessionFactory 的实例可以通过 SqlSessionFactoryBuilder 获得。而 SqlSessionFactoryBuilder 则可以从 XML 配置文件或一个预先定制的 Configuration 的实例构建出 SqlSessionFactory 的实例。

从 XML 文件中构建 SqlSessionFactory 的实例非常简单,建议使用类路径下的资源文件进行配置。 但是也可以使用任意的输入流(InputStream)实例,包括字符串形式的文件路径或者 file:// 的 URL 形式的文件路径来配置。MyBatis 包含一个名叫 Resources 的工具类,它包含一些实用方法,可使从 classpath 或其他位置加载资源文件更加容易。

String resource = "org/mybatis/example/mybatis-config.xml";//resource中的mybatis-config路径
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

创建一个工具类MybatisUtils

/*
mybatis工具类,
读取resource下的mybatis-config中生成SqlSessionFactory类
 */
package com.snow.utils;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import java.io.IOException;
import java.io.InputStream;

public class MybatisUtils {

    private static SqlSessionFactory sqlSessionFactory;


    static {
        try {
            String resource = "mybatis-config.xml";
            InputStream inputStream = Resources.getResourceAsStream(resource);
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static SqlSession getSqlSession() {
        return sqlSessionFactory.openSession();
    }
}

5.Mapper
public interface UserMapper {
    List<User> getUserList();

}

6.mapper.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">
<mapper namespace="com.snow.dao.UserMapper">
    <select id=" getUserList" resultType="com.snow.pojo.User">
    select * from user where id = #{id}
  </select>
</mapper>
7.测试
public class MybatisTest {


    @Test
    public void test(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        List<User> userList = mapper.getUserList();
        System.out.println(userList.size());
        for (User user : userList) {
            System.out.println(user);
        }
        sqlSession.close();
    }
}

注意的问题:

1.mapper.xml要绑定对应的mapper类

<mapper namespace="com.snow.dao.UserMapper">

2.每一个mapper.xml要在核心配置文件(mybatis-config.xml)中注册

	 <mappers>
        <mapper resource="UserMapper.xml"/>
    </mappers>

3.在mybatis中,即便是mysql8,但在配置文件中配置drivers时任然用

<property name="driver" value="com.mysql.jdbc.Driver"/>

4.sqlSession用完即关

SqlSessionFactoryBuilder

这个类可以被实例化、使用和丢弃,一旦创建了 SqlSessionFactory,就不再需要它了。 因此 SqlSessionFactoryBuilder 实例的最佳作用域是方法作用域(也就是局部方法变量)。 你可以重用 SqlSessionFactoryBuilder 来创建多个 SqlSessionFactory 实例,但是最好还是不要让其一直存在,以保证所有的 XML 解析资源可以被释放给更重要的事情。

SqlSessionFactory

SqlSessionFactory 一旦被创建就应该在应用的运行期间一直存在,没有任何理由丢弃它或重新创建另一个实例。 使用 SqlSessionFactory 的最佳实践是在应用运行期间不要重复创建多次,多次重建 SqlSessionFactory 被视为一种代码“坏味道(bad smell)”。因此 SqlSessionFactory 的最佳作用域是应用作用域。 有很多方法可以做到,最简单的就是使用单例模式或者静态单例模式。

SqlSession

每个线程都应该有它自己的 SqlSession 实例。SqlSession 的实例不是线程安全的,因此是不能被共享的,所以它的最佳的作用域是请求或方法作用域。 绝对不能将 SqlSession 实例的引用放在一个类的静态域,甚至一个类的实例变量也不行。 也绝不能将 SqlSession 实例的引用放在任何类型的托管作用域中,比如 Servlet 框架中的 HttpSession。 如果你现在正在使用一种 Web 框架,要考虑 SqlSession 放在一个和 HTTP 请求对象相似的作用域中。 换句话说,每次收到的 HTTP 请求,就可以打开一个 SqlSession,返回一个响应,就关闭它。 这个关闭操作是很重要的,你应该把这个关闭操作放到 finally 块中以确保每次都能执行关闭。 下面的示例就是一个确保 SqlSession 关闭的标准模式:

try (SqlSession session = sqlSessionFactory.openSession()) {
  // 你的应用逻辑代码
}

2.CRUD

<?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.snow.dao.UserMapper">
    <select id="getUserList" resultType="com.snow.pojo.User">
    select * from user
  </select>
   <select id="getUserById" parameterType="int" resultType="com.snow.pojo.User">
       select * from user where id=#{id} 参数要与mapper中的形参相同,如果参数是对象,参数名同属性名
   </select>
    <insert id="insertUser" parameterType="com.snow.pojo.User">
    insert into user (id, username, password) value (#{id},#{username},#{password})
 </insert>
    <update id="updateUser" parameterType="com.snow.pojo.User" >
        update user set username=#{username}, password=#{password} where id=#{id}
     </update>
    <delete id="deleteById" parameterType="int">
        delete from user where id=#{id}
    </delete>
</mapper>
 public void test(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        List<User> userList = mapper.getUserList();
        System.out.println(userList.size());
        for (User user : userList) {
            System.out.println(user);
        }
        sqlSession.close();
    }
    public  void getUserById(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        User user = mapper.getUserById(2);
        System.out.println(user);

        sqlSession.close();
    }
    @Test
    public void insertUser(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        int i = mapper.insertUser(new User(4, "summer", "password"));
        if(i > 0){
            System.out.println("OK!");
        }
        //增删改必须要提交事物
        sqlSession.commit();
        sqlSession.close();
    }
    @Test
    public void update(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        int summer = mapper.updateUser(new User(3, "summer", "196980"));
        if(summer>0){
            System.out.println("ok");
        }
        sqlSession.commit();
        sqlSession.close();
    }

}

sql语句中{}里的变量要与mapper中的形参相同,如果参数是对象,变量名同属性名

增删改必须要提交事物

sqlSession.commit();

3.用Map 来DML

用map操作的好处是,操作时不用创建对应数据库中字段的对象,可插入的字段数量可以灵活控制,当数据库中的字段很多年的时候,利用map操作的优势就显现出来,其次,利用map操作时是按照map的key插入,key不必要和数据库中的字段名相同。例子:

!--    map 插入-->
    <insert id="insertByMap" parameterType="map">
        insert into user (id,username,password) values(#{UserId},#{name},#{pwd})
    </insert>
    @Test
    public void insertByMap(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();

        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        HashMap<String, Object> userMap = new HashMap<String, Object>();
        userMap.put("UserId", 5);
        userMap.put("name", "winter");
        userMap.put("pwd", "winter");
        mapper.insertByMap(userMap);
        sqlSession.commit();
        sqlSession.close();
    }
4.模糊查询

在java层面传递通配符 % value%

3.MyBatis配置

MyBatis 的配置文件包含了会深深影响 MyBatis 行为的设置和属性信息。 配置文档的顶层结构如下:

1.环境配置(environments)

MyBatis 可以配置成适应多种环境,这种机制有助于将 SQL 映射应用于多种数据库之中, 现实情况下有多种理由需要这么做。例如,开发、测试和生产环境需要有不同的配置;或者想在具有相同 Schema 的多个生产数据库中 使用相同的 SQL 映射。有许多类似的使用场景。

不过要记住:尽管可以配置多个环境,但每个 SqlSessionFactory 实例只能选择一种环境。

所以,如果你想连接两个数据库,就需要创建两个 SqlSessionFactory 实例,每个数据库对应一个。而如果是三个数据库,就需要三个实例,依此类推,记起来很简单:

  • 每个数据库对应一个 SqlSessionFactory 实例

选择环境时,只需修改default的值,其未对应环境的id

<environments default="development">

Mybatis的默认事物管理器是JDBC, 连接池:POOLED

2.属性(properties)

属性都是可外部配置且可动态替换的,既可以在典型的 Java 属性文件中配置(db.properties),亦可通过 properties 元素的子元素来传递。例如:

<dataSource type="POOLED">
  <property name="driver" value="${driver}"/>
  <property name="url" value="${url}"/>
  <property name="username" value="${username}"/>
  <property name="password" value="${password}"/>
</dataSource>

例子:

<configuration>
<!--    引入外部配置文件-->
    <properties resource="db.properties"/>


    <environments default="development">
        <environment id="development">
<!--            事物管理com-->
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
<!--              &amp;相当于转义符-->
                <property name="url" value="${url}"/>
                <property name="username" value="${username}"/>
                <property name="password" value="${password}"/>
            </dataSource>

注意:外部配置文件的优先级最高

在这个配置文件中,标签出现有一定的顺序。

3.别名

在核心配置文件文件中设置别名,在mapper中就可以使用该别名,而不用在写一些冗余和重复的包名。

 <typeAliases >
        <typeAlias type="com.snow.pojo.User" / alias="User">
    </typeAliases>

这样就可以在mappr.xml中直接用User代替com.snow.pojo.User了。

<mapper namespace="com.snow.dao.UserMapper">
    <select id="getUserList" resultType="User">
    select * from user
  </select>

也可以使用包扫描

<typeAliases >
        <typeAlias type="com.snow.pojo.User" />
        <package name="com.snow.pojo"/>
    </typeAliases>

这样就可以扫描包中的bean,在,mapper中可以直接首字母小写写该类。

<select id="getUserById" parameterType="int" resultType="user">
       select * from user where id=#{id}
   </select>

4.setting
mapUnderscoreToCamelCase是否开启自动驼峰命名规则(camel case)映射,即从经典数据库列名 A_COLUMN 到经典 Java 属性名 aColumn 的类似映射。true | falseFalse
5.映射器

注册绑定mapper 文件

方式一:

mybatis-config.xml

<mappers>
        <mapper resource="UserMapper.xml"/>
 </mappers>

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eB9jYTXd-1581602040685)(C:\Users\19698\AppData\Roaming\Typora\typora-user-images\image-20191231172243225.png)]
方式二:

   <mappers>
     <mapper class="com.snow.dao.UserMapper" />
  </mappers>

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qxGPQBzx-1581601911827)(C:\Users\19698\AppData\Roaming\Typora\typora-user-images\image-20191231173439068.png)]

接口和它的mapper.xmL必须文件名相同,并且在同一个包下

方式三、

使用包扫描

<!-- 将包内的映射器接口实现全部注册为映射器 -->
<mappers>
  <package name="com.snow.mappers"/>
</mappers>

4.生命周期与作用域

1.SqlSessionFactoryBuilder

这个类可以被实例化、使用和丢弃,一旦创建了 SqlSessionFactory,就不再需要它了。 因此 SqlSessionFactoryBuilder 实例的最佳作用域是方法作用域(也就是局部方法变量)

2.SqlSessionFactory

SqlSessionFactory 一旦被创建就应该在应用的运行期间一直存在,没有任何理由丢弃它或重新创建另一个实例可以使用单例模式或者静态单例模式

3.SqlSession

每个线程都应该有它自己的 SqlSession 实例。SqlSession 的实例不是线程安全的,因此是不能被共享的,所以它的最佳的作用域是请求或方法作用域。绝对不能将 SqlSession 实例的引用放在一个类的静态域,甚至一个类的实例变量也不行。用完即关

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-b1r0tdXL-1581601911828)(C:\Users\19698\AppData\Roaming\Typora\typora-user-images\image-20191231184915378.png)]

5.结果集映射resultMap

————为了解决数据库中字段和javabean中的属性名不一致的问题

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4x45EuHC-1581601911828)(C:\Users\19698\AppData\Roaming\Typora\typora-user-images\image-20200101145130265.png)]

public class User {
    private int userId;
    private String name;
    private String userPwd;
}

在mapper.xml中

<mapper namespace="com.snow.dao.UserMapper">
    <resultMap id="UserResultMap" type="user">
       <!-- column对应数据库中的字段,property对应bean的属性-->
        <result column="id" property="userId"/>
        <result column="username" property="name"/>
        <result column="password" property="userPwd"/>
    </resultMap>

注:这里的user是在前面的mybatis-config的配置文件中已经开启了包扫描

结果集不必一一映射,只需映射不同的部分,

6.日志

在Mybatis的核心配置文件中开启日志输出

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

value的值为不同的日志包,参考官网文档

开启了日志输出之后还要早pom中导入log4j的依赖,

最后还要创建一个log4j.properties文件对其进行一些配置,可百度

import org.apache.log4j.Logger;
public class MybatisTest {
    private static  Logger logger = Logger.getLogger(MybatisTest.class);

    @Test
    public void testLog4j(){
        logger.info("testLog4j");
        logger.debug("debug");
        logger.error("error");
    }


db.properties-mysql
driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/mybatis?useSSL=false&serverTimezone=UTC&useUnicode=true&characterEncoding=utf8
username=root
password=196

7.分页查询

7.1 limit分页查询
<?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.snow.mapper.UserMapper">
    <resultMap id="UserResultMap" type="user">
        <result column="id" property="userId"/>
        <result column="username" property="name"/>
    </resultMap>
    <select id="queryLimit" resultMap="UserResultMap" parameterType="map">
        select * from user limit #{startIndex},#{size}
    </select>
</mapper>
@org.junit.Test
    public void testLimitQuery(){
        HashMap<String, Integer> map = new HashMap<String, Integer>();
        map.put("startIndex", 1);
        map.put("size", 3);
        
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        
        List<User> users = mapper.queryLimit(map);
        for (User user : users) {
            System.out.println(user);
        }
    }
7.2 RowBounds分页查询

不建议使用

8.使用注解开发

public interface UserMapper {

    @Select("select * from user")
    public List<User> getUserList();
}

在mybatis-config中仍然要去注册

<mappers>
    <mapper class="com.snow.mapper.UserMapper"/>
</mappers>

测试

public class Test {

    @org.junit.Test
    public void test(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();


        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        List<User> userList = mapper.getUserList();
        for (User user : userList) {
            System.out.println(user);
        }
        sqlSession.close();

    }
}

Sqlsession可以开启自动提交事物,但一般不要打开自动提交

mybatis工具类中

return sqlSessionFactory.openSession(true);

使用注解做一些简单的增删改

public interface UserMapper {

    @Select("select * from user")
    public List<User> getUserList();


    @Insert("insert into user(id, username, password) values(#{id},#{username},#{password})")
    public int addUser(User user);

    @Update("update user set name=#{name},password=#{password} where id=#{id}")
    public int updateUser(User user);


    @Delete("delete from user where id=#{userID}")
    public int deleteByID(@Param("userID") int id);
}

注意@Param的用法

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值