Mybatis入门

MyBatis是什么

MyBatis是一个ORM的数据库持久化框架。

一.创建一个项目,导包

在这里插入图片描述

二.准备相应的表、domain、dao、测试

在这里插入图片描述

三.入门实现

3.1实现步骤分析

①获取SqlSessionFactory
1 我们需要准备一个核心的Mybatis-config.xml文件
2 拿到SqlSessionFactory之前需要读取核心的xml配置文件
3 需要构造者(SqlSessionFactoryBuilder)来创建它
②映射文件准备
③通过SqlSessionFactory获取SqlSession执行映射SQL

3.2实现

<?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>
    <!--引入jdbc.propeties文件-->
    <properties resource="jdbc.properties" />
    <typeAliases>
        <!-- 单个配置:练习 -->
      <!--  <typeAlias type="cn.itsource.domain.User" alias="user"></typeAlias>-->
        <!-- 包的配置:项目,添加了包之后,类名就是别名 -->
        <package name="cn.itsource.domain"></package>
        <package name="cn.itsource.query"></package>
    </typeAliases>
    <!-- 环境们 (很多环境的意思)
        default:默认使用哪一个环境(必需对应一个环境的id)
     -->

    <environments default="development">
        <!--
            一个环境  id:为这个环境取唯一一个id名称
        -->
        <environment id="development">
            <!--
                事务管理   type:JDBC(支持事务)/MANAGED(什么都不做)
            -->
            <transactionManager type="JDBC" />
            <!-- 数据源, 连接池  type(POOLED):MyBatis自带的连接池 -->
            <dataSource type="POOLED">
                <!-- 连接数据库的参数 -->
                <property name="driver" value="${jdbc.driverClassName}" />
                <property name="url" value="${jdbc.url}" />
                <property name="username" value="${jdbc.username}" />
                <property name="password" value="${jdbc.password}" />
            </dataSource>
        </environment>
    </environments>
    <!-- 这个mappers代表的是相应的ORM映射文件 -->
    <mappers>
        <mapper resource="cn/itsource/domain/UserMapper.xml" />
    </mappers>

</configuration>

3.3 映射文件
①我们的映射文件(就是我们的mapper文件)一般情况下是和它对应的domain实体类在同一个层级
② 这个映射文件的名称一般叫做 XxxMapper.xml (Xxx代表的是实体类名称)
③ namespace的名称为了确定唯一性,请大家根据我的要求取名

<?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">
<!-- orm框架 sql的映射
namespace:命名空间  namespace路径+ id值
          namespace怎么配置 包名.接口名 + queryAll
-->
<mapper namespace="cn.itsource.dao.IUserDao">
    <!-- 查询 queryAll()
        resultType 返回类型
    -->
    <select id="queryAll" resultType="cn.itsource.domain.User">
        select * from t_user
    </select>
    <select id="queryOne" parameterType="long" resultType="User">
        select * from t_user where id=#{id}
    </select>
    <!--新增-->
    <select id="save" parameterType="User">
        insert into t_user(name) values(#{name})
    </select>
    <!--修改-->
    <update id="update" parameterType="User">
        update t_user set name=#{name} where id=#{id}
    </update>
    <!--删除-->
    <delete id="delete" parameterType="long">
        delete from t_user where id=#{id}
    </delete>

    <sql id="TopSql">
        <if test="name!=null">
            and name like #{name}
        </if>
        <if test="age!=null">
            and age = #{age}
        </if>
    </sql>

    <select id="queryList" parameterType="userQuery"  resultType="User">
        select * from t_user
        <where>
            <include refid="TopSql"></include>
        </where>
    </select>

    <!--批量删除-->
    <delete id="deleteBatch" parameterType="list">
        delete from t_user where id in
        <foreach collection="list" item="id"  open="(" separator="," close=")">
        #{id}
        </foreach>
    </delete>
   <!-- 批量新增-->
    <insert id="saveBatch" parameterType="list">
        insert into t_user(name) values
        <foreach collection="list" item="user"  separator="," >
            (#{user.name})
        </foreach>
    </insert>
</mapper>

3.4其他实现

package cn.itsource.dao;

import cn.itsource.domain.User;
import cn.itsource.query.UserQuery;

import java.io.IOException;
import java.util.List;

public interface IUserDao {

    void save(User user) throws IOException;
    void update(User user) throws IOException;;
    void delete(Long id) throws IOException;

    List<User> queryAll() throws IOException;

    User queryOne(Long id)throws IOException;

    //批量删除
    void deleteBatch(List ids) throws Exception;
    //批量新增
    void saveBatch(List users) throws Exception;
    //高级查询方法
    List<User> queryList(UserQuery userQuery) throws Exception;
}

package cn.itsource.dao.impl;

import cn.itsource.dao.IUserDao;
import cn.itsource.domain.User;
import cn.itsource.query.UserQuery;
import cn.itsource.utils.MybatisUtils;
import org.apache.ibatis.session.SqlSession;

import java.io.IOException;
import java.util.List;

public class UserDaoImpl implements IUserDao{
    @Override
    public void save(User user) throws IOException {
        SqlSession sqlSession = MybatisUtils.INSTANCE.getSqlSession();
        sqlSession.insert("cn.itsource.dao.IUserDao.save",user);
        sqlSession.commit();
    }

    @Override
    public void update(User user) throws IOException {
        SqlSession sqlSession = MybatisUtils.INSTANCE.getSqlSession();
        sqlSession.update("cn.itsource.dao.IUserDao.update",user);
        sqlSession.commit();
    }

    @Override
    public void delete(Long id) throws IOException {
        SqlSession sqlSession = MybatisUtils.INSTANCE.getSqlSession();
        sqlSession.delete("cn.itsource.dao.IUserDao.delete",id);
        sqlSession.commit();
    }

    @Override
    public List<User> queryAll() throws IOException {
        SqlSession sqlSession = MybatisUtils.INSTANCE.getSqlSession();
        List<User> users = sqlSession.selectList("cn.itsource.dao.IUserDao.queryAll");
        return users;
    }

    @Override
    public User queryOne(Long id) throws IOException {
        SqlSession sqlSession = MybatisUtils.INSTANCE.getSqlSession();
        User user  = sqlSession.selectOne("cn.itsource.dao.IUserDao.queryOne",id);
        return user;
    }

    @Override
    public void deleteBatch(List ids) throws Exception {
        SqlSession sqlSession = MybatisUtils.INSTANCE.getSqlSession();
        sqlSession.delete("cn.itsource.dao.IUserDao.deleteBatch",ids);
        sqlSession.commit();
    }

    @Override
    public void saveBatch(List users) throws Exception {
        SqlSession sqlSession = MybatisUtils.INSTANCE.getSqlSession();
        sqlSession.insert("cn.itsource.dao.IUserDao.saveBatch",users);
        sqlSession.commit();
    }

    @Override
    public List<User> queryList(UserQuery userQuery) throws Exception {
        SqlSession sqlSession = MybatisUtils.INSTANCE.getSqlSession();
        List<User> users = sqlSession.selectList("cn.itsource.dao.IUserDao.queryList", userQuery);
        return users;
    }

}




测试类

package cn.itsource.test;

import cn.itsource.dao.impl.UserDaoImpl;
import cn.itsource.domain.User;
import cn.itsource.query.UserQuery;
import org.junit.Test;

import java.util.Arrays;
import java.util.List;

public class MybatisTest {
@Test
public void test()throws Exception{
List list = new UserDaoImpl().queryAll();
list.forEach(e->{
System.out.println(e);
});
}

@Test
public void testSave()throws Exception{
    User user = new User();
    user.setName("格林");
    new UserDaoImpl().save(user);
    System.out.println(user);
}
@Test
public void testUpdate()throws Exception {
    User user = new User();
    user.setId(12L);
    user.setName("利欧路");
    new UserDaoImpl().update(user);
}
@Test
public void testDelete() throws Exception{
    List<Long> ids = Arrays.asList(10L, 11L, 12L, 13L);

    new UserDaoImpl().delete(13L);
}
@Test
public void test2() throws Exception{
    System.out.println(new UserDaoImpl().queryOne(1L));
}
@Test
public void testQuerylist()throws Exception{
    UserQuery userQuery = new UserQuery();
    userQuery.setName("%斯%");
    userQuery.setAge(35);
    List<User> users = new UserDaoImpl().queryList(userQuery);
    users.forEach(e->{
        System.out.println(e);
    });

}
@Test
public void testDeleteBatch()throws Exception{
    List<Long> ids = Arrays.asList(12L,14L,15L);
    new UserDaoImpl().deleteBatch(ids);
}

@Test
public void testSaveBatch()throws Exception{
   List<User> users = Arrays.asList(new User("蔡徐坤"),
           new User("吴亦凡"),
           new User("鹿晗"));
   new UserDaoImpl().saveBatch(users);


}

}
四、抽取Mybatis CRUD-工具类
4.1抽取理论

SqlSessionFactoryBuilder
建造者模式:我们最后拿到的这个对象是非常复杂的. 用这个建造者就它先为我们把这些复杂的代码完成. 这个类可以被实例化,使用和丢弃。一旦创建了SqlSessionFactory后,这个类对象就不需要存在了。因此SqlSessionFactoryBuilder实例的最佳范围是方法范围(也就是本地方法变量)。

SqlSessionFactory
一旦被创建,SqlSessionFactory应该在你的应用执行期间都存在。没有理由来处理或重新创建它。使用SqlSessionFactory的最佳实践是在应用运行期间不要重复创建多次。这样的操作将被视为是非常糟糕的。因此SqlSessionFactory的最佳范围是应用范围。有很多方法可以做到,最简单的就是使用单例模式或者静态单例模式。然而这两种方法都不认为是最佳实践。

SqlSession
每个线程都应该有它自己的SqlSession实例。SqlSession的实例不能被共享,也是线程不安全的。因此最佳的范围是请求或方法范围。绝对不能将SqlSession实例的引用放在一个类的静态字段甚至是实例字段中。也绝不能将SqlSession实例的引用放在任何类型的管理范围中,比如Serlvet架构中的HttpSession。如果你现在正用任意的Web框架,要考虑SqlSession放在一个和HTTP请求对象相似的范围内。换句话说,基于收到的HTTP请求,你可以打开了一个SqlSession,然后返回响应,就可以关闭它了。关闭Session很重要,

抽取

package cn.itsource.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.Reader;

public enum MybatisUtils {
    INSTANCE;
    private static SqlSessionFactory sqlSessionFactory;
    static {
        Reader reader = null;
        try {
            reader = Resources.getResourceAsReader("MyBatis-Config.xml");
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
        } catch (IOException e) {
            e.printStackTrace();
            throw new RuntimeException("解析文件出错"+e.getMessage());
        }
    }
    public SqlSession getSqlSession(){
        return sqlSessionFactory.openSession();
    }
}

五、Mybtis使用细节

<!-- 
		parameterType:需要传入我们的对象
		useGeneratedKeys: 是否需要主键 
		keyColumn:主键所在的列
		keyProperty:对象中的属性(代表主键的那个属性)
	 -->
	<insert id="save" parameterType="cn.itsource.domain.Product"
			useGeneratedKeys="true" 
			keyColumn="id"
			keyProperty="id"
		>
		insert into product (productName,dir_id,salePrice,supplier,brand,cutoff,costPrice)
			values (#{productName},#{dir_id},#{salePrice},#{supplier},#{brand},#{cutoff},#{costPrice})
	</insert>

六.查看MyBatis运行日志

在使用MyBatis的很多时候,我们需要把日志打印出来,帮助我们进行分析与排错。特别是大家现在学习阶段,要求大家都MyBatis的日志打开。

# 日志输出级别 输出到控制
log4j.rootLogger=ERROR, stdout
#log4j.rootLogger=NONE
log4j.logger.cn.itsource=TRACE
# 输出到控制台的配置信息
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
# 输出到控制台的 格式类
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - %m%n

七.在MyBatis中别名

在这里插入图片描述

7.1自定义别名

<typeAliases>
		<!-- 单个配置:练习 -->
		<typeAlias type="cn.itsource.mybatis.a_crud.Dept" alias="Dept" />
		<!-- 包的配置:项目,添加了包之后,类名就是别名 -->
		<package name="cn.itsource.mybatis.a_crud" />
</typeAliases>

7.2#与$区别

7.2.1 #{OGNL表达式}

MyBatis会把这个表达式使用?(占位符)替换,作为一个sql参数使用:推荐使用
比如:
定义SQL: select * from t_user where name = #{name}
最终SQL: select * from t_user where name = ?
7.2.2 ${OGNL表达式}

MyBatis会把这个表达式的值替换到sql中,作为sql的组成部分; 把获取到值直接拼接SQL,该方式主要用于程序拼接SQL;
比如:
定义SQL: select id,name,password from t_user where name = nameandpassword=
nameandpassword={password}
最终SQL: select id,name,password from t_user where name=“test” or “1=1” and password=“test” 出现sql注入
除了要拼接sql结构体要用$(是直接拼接sql),其他都用#,因为用#会替换为?,最终通过prepareStament来设置参数,不会有sql注入问提。

八.常用的动态SQL

MyBatis 的一个强大的特性之一通常是它的动态 SQL 能力。如果你有使用 JDBC 或其他
相似框架的经验,你就明白条件地串联 SQL 字符串在一起是多么的痛苦,确保不能忘了空
格或在列表的最后省略逗号。动态 SQL 可以彻底处理这种痛苦。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值