Mybatis

Mybatis

一、步骤

1、resources目录

放在resources下的文件相当于放在java类根目录下

2、开发步骤

第一步:打包方式jar
第二步:加入依赖mybatis和Mysql驱动
第三步:配置mybatis-config.xml(一般放于resources下)
第四步:编写XxxMapper.xml文件(编写SQL语句,放于类根目录下)
第五步:在mybatis-config.xml文件中指定XxxMapper.xml的路径(<Mapper resource=” ”>其中resource属性默认是从根路径下)
第六步:编写Mybatis程序。

注意:Sqlsession是专用用来执行SQL语句的,是数据库和Java程序一次连接。要想获得Sqlsession对象,首先要获得SqlSessionFactory对象,通过SqlSessionFactory工厂来产生一个Sqlsession对象。要想获得SqlSessionFactory对象,首先要获得SqlSessionFactoryBuilder对象,通过SqlSessionFactoryBuilder对象的build方法来获得
Mybatis的核心:SqlSessionFactoryBuilder、SqlSessionFactory、Sqlsession

 public static void main(String[] args)  {
        SqlSession sqlSession=null;
        try{
            //获得SqlSessionFactoryBuilder对象
            SqlSessionFactoryBuilder sqlSessionFactoryBuilder=new SqlSessionFactoryBuilder();
            //获得SqlSessionFactory对象
       SqlSessionFactory sqlSessionFactory=sqlSessionFactoryBuilder.build(Resources.getResourceAsStream  ("mybatis-config.xml"));
            //获得Sqlsession对象
            sqlSession =sqlSessionFactory.openSession();
            //执行SQL语句
            int number=sqlSession.insert("insertUser");//XxxMapper.xml中insert的id
            System.out.println("提交成功");
            //手动提交
            sqlSession.commit();
        }catch(Exception e) {
            if (sqlSession != null) {
                sqlSession.rollback();
            }
            e.printStackTrace();
        }finally{
            if(sqlSession!=null){
                sqlSession.close();
            }
        }
    }

3、从xml中构建SqlSessionFactory

4、Mybatis中有两个主要的文件

mybatis-config.xml用来配置数据库信息
XxxMapper.xml专门用来写SQL语句(一个表对应一个xml)

5、Mybatis的事务管理

 <transactionManager type="JDBC"/>

(1)JDBC:默认conn.setAutoCommit(false)开启事务
手动提交conn.commit();
(2)MANAGED:表示事务让其他来管,如spring

6、Junit单元测试

7、Mybatis集成日志组件

在mybatis-config.xml中<configuration><settings>

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

logback是目前日志框架中性能较好的,较流行的,所以我们选它。

引入logback的步骤:

第一步:引入logback相关依赖

<dependency>
  <groupId>ch.qos.logback</groupId>
  <artifactId>logback-classic</artifactId>
  <version>1.2.11</version>
</dependency>

第二步:引入logback相关配置文件(文件名叫做logback.xml或logback-test.xml,放到类路径当中)

<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="false">
    <!-- 控制台输出 -->
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符-->
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
        </encoder>
    </appender>
    <!-- 按照每天生成日志文件 -->
    <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!--日志文件输出的文件名-->
            <FileNamePattern>${LOG_HOME}/TestWeb.log.%d{yyyy-MM-dd}.log</FileNamePattern>
            <!--日志文件保留天数-->
            <MaxHistory>30</MaxHistory>
        </rollingPolicy>
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符-->
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
        </encoder>
        <!--日志文件最大的大小-->
        <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
            <MaxFileSize>100MB</MaxFileSize>
        </triggeringPolicy>
    </appender>

    <!--mybatis log configure-->
    <logger name="com.apache.ibatis" level="TRACE"/>
    <logger name="java.sql.Connection" level="DEBUG"/>
    <logger name="java.sql.Statement" level="DEBUG"/>
    <logger name="java.sql.PreparedStatement" level="DEBUG"/>

    <!-- 日志输出级别,logback日志级别包括五个:TRACE < DEBUG < INFO < WARN < ERROR -->
    <root level="DEBUG">
        <appender-ref ref="STDOUT"/>
        <appender-ref ref="FILE"/>
    </root>

</configuration>

二、工具类

public class SqlSessionUtil {
    private SqlSessionUtil(){}
    private static SqlSessionFactory sqlSessionFactory;
    static{
        try {
            sqlSessionFactory=new SqlSessionFactoryBuilder().build(Resources.getResourceAsStream
("mybatis-config.xml"));
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
    public static SqlSession opensession(){
        return sqlSessionFactory.openSession();
    }
}


    public static void main(String[] args) {
        SqlSession sqlSession=SqlSessionUtil.opensession();
        //执行SQL语句
        int number=sqlSession.insert("insertUser");//XxxMapper.xml中insert的id
        System.out.println("提交成功");
        //手动提交
        sqlSession.commit();
        sqlSession.close();
}

三、传参

占位符:#{}
1、Java程序中可以用Map给SQL语句的占位符传值:

Map<StringObject> map=new HashMap<>();
map.put(“carName”,”比亚迪”);
map.put(“carNumber”,1000);

Insert into car(id,car_name,car_number) value(null,${carName},${carNumber});

2、Java类给SQL语句的占位符传值:

public class car{
private Long id;
private String carName;
private Long carNumber;
//get和set方法
}

<insert id="insertcar">
Insert into car(id,car_name,car_number) value(null,${carName},${carNumber});
</insert>

@Test
public void fun(){
Car car=new car(null,比亚迪,1000);
sqlSession.insert(“insertcar”,car);
}

注:
1、${ }里面的是,getXxx()去掉get再小写。即${xxx}
2、其中delete语句的where id = ${可以任意命名}
3、查询所有用List<类>
4、对于不同的namespace,使用:使用它时用namespace+id,例如sqlSession.insert(“namespace.insertcar”,car)

四、配置多环境

<environments default="development">
<!--default指定时某认环境id-->
        <environment id="development">
            <!-- 配置事务管理器 -->
            <transactionManager type="JDBC"/>
            <!-- 配置数据源 -->
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/mybatisstudy?useSSL=false"/>
                <property name="username" value="root"/>
                <property name="password" value="123456"/>
            </dataSource>
        </environment>
    </environments>

注:environment 可以多个环境,一个数据库对应一个SqlSessionFctory对象
使用:SqlSessionFactoryBuilder().build(Resources.getResourceAsStream(“mybatis-config.xml”),“指定的环境id”)

(1)transactionManager 标签

1、作用:配置事务管理器,指定mybatis使用什么方式去管理
2、JDBC或MANAGED

(2)dataSource标签

提供Connection对象的数据源。dataSource 元素使用标准的 JDBC 数据源接口来配置 JDBC 连接对象的资源。
大多数 MyBatis 应用程序会按示例中的例子来配置数据源。虽然数据源配置是可选的,但如果要启用延迟加载特性,就必须配置数据源。
有三种内建的数据源类型(也就是 type=“[UNPOOLED|POOLED|JNDI]”):
UNPOOLED– 这个数据源的实现会每次请求时打开和关闭连接。虽然有点慢,但对那些数据库连接可用性要求不高的简单应用程序来说,是一个很好的选择。 性能表现则依赖于使用的数据库,对某些数据库来说,使用连接池并不重要,这个配置就很适合这种情形。UNPOOLED 类型的数据源仅仅需要配置以下 5 种属性:
driver – 这是 JDBC 驱动的 Java 类全限定名(并不是 JDBC 驱动中可能包含的数据源类)。
url – 这是数据库的 JDBC URL 地址。
username – 登录数据库的用户名。
password – 登录数据库的密码。
defaultTransactionIsolationLevel – 默认的连接事务隔离级别。
defaultNetworkTimeout – 等待数据库

(3)properties标签

1、正常情况下:

<!-- 配置数据源 -->
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/mybatisstudy?useSSL=false"/>
                <property name="username" value="root"/>
                <property name="password" value="123456"/>
            </dataSource>

2、但可以采用变量:

<properties>
<property name="jdbc.driver" value="com.mysql.jdbc.Driver"/>
       <property name="jdbc.url" value="jdbc:mysql://localhost:3306/mybatisstudy?useSSL=false"/>
       <property name="jdbc.username" value="root"/>
       <property name="jdbc.password" value="123456"/>
</properties>
<!-- 配置数据源 -->
            <dataSource type="POOLED">
                <property name="driver" value="${jdbc.}"/>
                <property name="url" value="${jdbc.url}"/>
                <property name="username" value="${jdbc.username}"/>
                <property name="password" value="${jdbc.password}"/>
            </dataSource>

3、还可采用配置文件jdbc.properties来配置

在配置文件中写入参数
jdbc.driver=com.mysql.jdbc.Drive       
jdbc.url=jdbc:mysql://localhost:3306/mybatisstudy?useSSL=false
jdbc.username=root
jdbc.password=123456
再到mybatis-config.xml中引入  <properties  resource="jdbc.properties"/>
注:resource是相当路径而url是绝对路径

(4)mapper标签

 <!-- 配置映射器 -->
    <mappers>
        <mapper resource="UserMapper.xml"/>
</mappers>

是来映射SQL语句的xml文件
resource:这种从根路径下开始查找资源
url:这种方式是绝对路径
class:写全限定接口名,这个位置提供的是mapper接口的全限定接口名,必须带有包名

四、web中应用

1、步骤:

(1)maven中导入依赖,mybatis、MySQL、logbcak、servlet
(2)配置tomcat和development
(3)新建包:com.公司.项目名.dao/pojo/service/utils/web
(4)核心配置文件xml

2、在Html中

<form action="/项目名/服务名"  method="post">
<input type="text" name="text1">
<input type="text" name="text2">
<input type="text" name="number">
<input type="submit" value="转账">
</form>

3、在web包中继承HttpServlet获取数据

@WebServlet("/服务名")
public class servlet extends HttpServlet {
    private Service service=new ServiceImpl();
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException {
        //1、获取表单数据
        String text1=request.getParameter("text1");
        String text2=request.getParameter("text2");
        double number=Double.parseDouble(request.getParameter("number"));
        //2、调用service(调业务层)
response.sendRedirect(request.getContextPath()+"/页面路径");
    }
}

4、在service中用接口

public interface Service{
    void funtion(String text1,String text2,double number);
}

5、在service/impl中实现

public class ServiceImpl implements Service{
    private ServiceDao dao=new DaoImpl();
    @Override
    public void funtion(String text1,String text2,double number){
类名 类名=dao.selectById(text1);
//书写各种方法
    }
}

6、在dao创建接口

public interface ServiceDao{
    类名 selectById(String id);
}

7、在dao/Impl中实现dao接口

public class DaoImpl implements ServiceDao{
    @Override
    public 类名 selectById(String id){
        SqlSession sqlSession= SqlSessionUtil.opensession();
        类名 类名=(类)sqlSession.select("selectById",类中的id名);
        return null;
    }
}

8、在类Mapper.xml中书写SQL语句

<select id="selectById" resultType="com.公司.项目名.pojo.类名">
        select * from 表名 where id=#{属性名}
</select>

注:namespace中必须是Dao类的名字,例如com.powernode.bank.AccountDao
Id必须是方法名/函数名,例如selectById

9、注意事务的提交

应该将SqlSessionUtil中

public class SqlSessionUtil {
    private SqlSessionUtil(){}
    private static SqlSessionFactory sqlSessionFactory;
    static{
        try {
            sqlSessionFactory=new SqlSessionFactoryBuilder().build(Resources.getResourceAsStream("mybatis-config.xml"));
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
    private static ThreadLocal<SqlSession> loacl=new ThreadLocal<SqlSession>();

    public static SqlSession opensession(){
        SqlSession sqlSession=loacl.get();
        if (sqlSession==null){
            sqlSession=sqlSessionFactory.openSession();
            //将sqlSession与线程绑定
            loacl.set(sqlSession);
        }
        return sqlSession;
    }
    public static void close(SqlSession sqlSession){
        if(sqlSession!=null){
            sqlSession.close();
            //移除sqlSession与线程绑定
            loacl.remove();
        }
    }
    
}

五、自动生成类

package com.wms.common;


import com.baomidou.mybatisplus.core.exceptions.MybatisPlusException;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.InjectionConfig;
import com.baomidou.mybatisplus.generator.config.*;
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

// 演示例子,执行 main 方法控制台输入模块表名回车自动生成对应项目目录中
public class CodeGenerator {

    /**
     * <p>
     * 读取控制台内容
     * </p>
     */
    public static String scanner(String tip) {
        Scanner scanner = new Scanner(System.in);
        StringBuilder help = new StringBuilder();
        help.append("请输入" + tip + ":");
        System.out.println(help.toString());
        if (scanner.hasNext()) {
            String ipt = scanner.next();
            if (StringUtils.isNotBlank(ipt)) {
                return ipt;
            }
        }
        throw new MybatisPlusException("请输入正确的" + tip + "!");
    }

    public static void main(String[] args) {
        // 代码生成器
        AutoGenerator mpg = new AutoGenerator();

        // 全局配置
        GlobalConfig gc = new GlobalConfig();
        String projectPath = System.getProperty("user.dir")+"/wms";//生成的代码找到wms文件
        gc.setOutputDir(projectPath + "/src/main/java");
        gc.setAuthor("wms");
        gc.setOpen(false);
        // gc.setSwagger2(true); 实体属性 Swagger2 注解
        mpg.setGlobalConfig(gc);

        // 数据源配置
        DataSourceConfig dsc = new DataSourceConfig();
        dsc.setUrl("jdbc:mysql://localhost:3306/wms?useUnicode=true&useSSL=false&characterEncoding=utf8");
        // dsc.setSchemaName("public");
        dsc.setDriverName("com.mysql.jdbc.Driver");
        dsc.setUsername("root");
        dsc.setPassword("123456");
        mpg.setDataSource(dsc);

        // 包配置
        PackageConfig pc = new PackageConfig();
        //pc.setModuleName(scanner("模块名"));
        pc.setParent("com.wms")
            .setEntity("entity")
                    .setMapper("mapper")
                            .setService("service")
                                    .setServiceImpl("service.impl")
                                            .setController("controller");
        mpg.setPackageInfo(pc);

        // 自定义配置
        InjectionConfig cfg = new InjectionConfig() {
            @Override
            public void initMap() {
                // to do nothing
            }
        };

        // 如果模板引擎是 freemarker
        String templatePath = "/templates/mapper.xml.ftl";
        // 如果模板引擎是 velocity
        // String templatePath = "/templates/mapper.xml.vm";

        // 自定义输出配置
        List<FileOutConfig> focList = new ArrayList<>();
        // 自定义配置会被优先输出
        focList.add(new FileOutConfig(templatePath) {
            @Override
            public String outputFile(TableInfo tableInfo) {
                // 自定义输出文件名 , 如果你 Entity 设置了前后缀、此处注意 xml 的名称会跟着发生变化!!
                return projectPath + "/src/main/resources/mapper/" + pc.getModuleName()
                        + "/" + tableInfo.getEntityName() + "Mapper" + StringPool.DOT_XML;
            }
        });
        /*
        cfg.setFileCreate(new IFileCreate() {
            @Override
            public boolean isCreate(ConfigBuilder configBuilder, FileType fileType, String filePath) {
                // 判断自定义文件夹是否需要创建
                checkDir("调用默认方法创建的目录,自定义目录用");
                if (fileType == FileType.MAPPER) {
                    // 已经生成 mapper 文件判断存在,不想重新生成返回 false
                    return !new File(filePath).exists();
                }
                // 允许生成模板文件
                return true;
            }
        });
        */
        cfg.setFileOutConfigList(focList);
        mpg.setCfg(cfg);

        // 配置模板
        TemplateConfig templateConfig = new TemplateConfig();

        // 配置自定义输出模板
        //指定自定义模板路径,注意不要带上.ftl/.vm, 会根据使用的模板引擎自动识别
        // templateConfig.setEntity("templates/entity2.java");
        // templateConfig.setService();
        // templateConfig.setController();

        templateConfig.setXml(null);
        mpg.setTemplate(templateConfig);

        // 策略配置
        StrategyConfig strategy = new StrategyConfig();
        strategy.setNaming(NamingStrategy.underline_to_camel);
        strategy.setColumnNaming(NamingStrategy.underline_to_camel);
//        strategy.setSuperEntityClass("你自己的父类实体,没有就不用设置!");
        strategy.setEntityLombokModel(true);
        strategy.setRestControllerStyle(true);
        // 公共父类
//        strategy.setSuperControllerClass("你自己的父类控制器,没有就不用设置!");
        // 写于父类中的公共字段
//        strategy.setSuperEntityColumns("id");
        strategy.setInclude(scanner("表名,多个英文逗号分割").split(","));
        strategy.setControllerMappingHyphenStyle(true);
        strategy.setTablePrefix(pc.getModuleName() + "_");

        mpg.setStrategy(strategy);
        mpg.setTemplateEngine(new FreemarkerTemplateEngine());
        mpg.execute();
    }

}

六、javassist动态生成类

导入依赖javassist帮助生成class

七、${}和#{}的注意

注:#{}:底层使用的是PreparedStatement。特点:先进行SQL语句的编译,然后给SQL语句的占位符?传值,可以避免SQL注入的风险
${}:底层使用的是Statement。特点:先进行SQL语句的拼接,然后再对SQL语句进行编译。存在SQL注入的风险.
#{}则是传值,如:str =“123,456”到#{str}则是,先去掉双引号再加上单引号,即‘123,456’
${}可以进行拼接,如:str =“123,456”到${str}则是,直接去掉双引号,即123,456,主要用于拼接

1、批量删除

(1)or
Delete from 表 where id=1 or id=2 or id=3;
(2)in
Delete from 表 where id in(1,2,3);
应该用${}

2、模糊查询like

例子:

Public interface CarMapper{
	List<Car> selectByBrand(String brand);
}

<mapper namespcase=com.powernode.mapper.CarMapper>
<select id=”selectByBrand” resultType=”com.powernode.pojo.car”>
Select 
	id,
	car_num as carNum, 
	brand
	guide_price as guidePrice
From
	car
Where
	brank like ‘%${brand}%//或者brank like concat(‘%’,#{brand},’%’ )
</select>

测试:

Public class CarMapperTest{
	@Test
	Public void test selectByBrand(){
		SqlSession sqlsession = SqlSessionUtil.openSession();
		CarMapper mapper = sqlsession.getMapper(CarMapper.class);
		List<Car> cars=mapper.selectByBrand(“奔驰”);
		Cars.forEach(car -> System.out.println(car));
		sqlsession.close();
	}
}

3、起别名

在mybatis-config.xml中起别名

<typeAliases>
<typeAliase type=”com.powernode.pojo.car” alias=”aaa”>
<package type=”com.powernode.pojo”>
</typeAliases>

则在SQL的xml文件中可以直接用
省略alias则默认为简名car/Car/cAr不区分大小写
Namescape不能起别名
package可以使得pojo包下的类起别名,使用简名

八、Mapper配置

mybatis-config.xml中的mapper标签中:
resource:这是从类的根路径下开始查找
url:绝对路径
class:提供mapper接口的全限定接口名,必须带有包名。

<mapper class=com.powenode.mybatis.mapper.CarMapper/>

则在java包下的com.powenode.mybatis.mapper.包中的CarMapper.xml,注意要求resoucers中的包和java包是一样的即同个目录名下

最终写法:

<package name=”com.powenode.mybatis.mapper”/>

九、自定义一键设置

在这里插入图片描述

十、插入数据时获得主键

<insert id=”方法名” useGeneratedKeys=true” keyProperty=”id”>

十一、参数问题

1、对于Date参数

(其实date也是普通参数)

Public class CarMapperTest{
	@Test
	Public void testselectByDate(){
		SqlSession sqlsession = SqlSessionUtil.openSession();
		CarMapper mapper = sqlsession.getMapper(CarMapper.class);

		SimpleDateFormat sdf=new SimpleDateFormat(“yyyy-MM-dd”);
		Date birth=sdf.pares(2024-01-10);

		List<Car> cars=mapper.selectByDate(birth);
		Cars.forEach(car -> System.out.println(car));
		sqlsession.close();
	}
}

2、Map参数

Public class CarMapperTest{
	@Test
	Public void testinsertCarByDirver(){
		SqlSession sqlsession = SqlSessionUtil.openSession();
		CarMapper mapper = sqlsession.getMapper(CarMapper.class);

		Map<String,Object> map=new HashMap<>();
		Map.put(“姓名”,”张三”);
		Map.put(“日期”,new Date() );
		Map.put(“年龄”,12);
		Mapper.insertCarByDirver(map);

		Sqlsession.commit();
		sqlsession.close();
	}
}

<insert id=”insertCarByDirver” parameterType=”map”>
		Insert into car(id,name,date,age) values(null.#{姓名}.#{日期}.#{年龄})
</insert>

3、POJO实体类参数

Public class CarMapperTest{
	@Test
	Public void testinsertCarByDirver(){
		SqlSession sqlsession = SqlSessionUtil.openSession();
		CarMapper mapper = sqlsession.getMapper(CarMapper.class);

		Car car =new car();
		car .setname(”张三”);
		car .setdate(new Date() );
		car .setage(12);


		Mapper.insertCarByDirver(car);
		Sqlsession.commit();
		sqlsession.close();
	}
}



<insert id=”insertCarByDirver” parameterType=”car”>
	Insert into car(id,name,date,age) values(null.#{name}.#{date}.#{age})
</insert>

4、多参数

多参数的话,自动创建Map集合:
map.put(“arg0”,name);
map.put(“arg1”,age);
或
map.put(“param1”,name);
map.put(“param2”,age);


List<car> 方法名(String name,Character age);

<select id=”方法名” resultType=”car”>
	Select * from car where name=#{arg0} and age=#{arg1}
</select >

5、Param注解

该注解是给默认map集合起别名的,arg失效,但param还可以用

List<car> 方法名(@Param(value=”name”)String name,@Param(value=”age”)String age);

<select id=”方法名” resultType=”car”>
	Select * from car where name=#{name} and age=#{age}
</select >

6、返回的类型

返回单个实体类:car selectByid(Integer id);
返回多个实体类:List<car> selectAll( ); 输出:car.forEach(car->System.out.println(car));
模糊查询:where brand like “%”#{brand}“%” 输出:List<car>
用Map返回一个:Map<String,Objetct> selectBymap(Integer id); 其中 ReusltType=”map“
用Map返回多个:List<Map<String,Objetct>> selectAll( );
用Map返回大Map:Map<Long,Map<String,Objetct>>
这样查找出来的map中容易拿出指定table

7、ResultType返回结果映射

(1)用as起别名
<select id="selectById" resultType="car">
        select
            id,
            car_num as carNum,
            brand,
            guide_price as guidePrice,
            produce_time as produceTime,
            car_type as carType
        from t_car where id=#{id}
    </select>
(2)使用<resultMap id="唯一标识CarResultMap" type="POJO实体类名"></resultMap>
<resultMap id="CarResultMap" type="car">
        <id property="id" column="id"/>
        <result property="carNum" column="car_num"/>
        <result property="guidePrice" column="guide_price"/>
        <result property="produceTime" column="produce_time"/>
        <result property="carType" column="car_type"/>
</resultMap>

<select id="selectById" resultMap ="CarResultMap">
 		Select *  from t_car where id=#{id}
 </select>
(3)驼峰命名自动映射(在mybatis核心配置文件中配置)
<settings>
        <setting name="mapUnderscoreToCamelCase" value="ture"/>
</settings>

Java命名规则:首字母小写,后面接的单词首字母大写
SQL命名规则:全小写,单词之间用_隔开
这样的命名规则mybatis自动会转换

8、返回总记录条数

Select count(*) from t_car

十二、动态SQL

1、if标签

List<Car> select(@Param("brand") String brand,@Param("guidePrice")Double guidePrice,@Param("carType") String carType);
注意:不能用&&得用and

<select id="select" resultType="car">
        select * from t_car where 1=1
        <if test="brand !=null and brand!=''">
            and brand like "%"#{brand}"%"
        </if>
        <if test="guidePrice !=null and guidePrice!=''">
            and guide_price > #{guidePrice}
        </if>
        <if test="carType !=null and carType!=''">
            and car_type > #{carType}
        </if>
    </select>

2、where标签

自动去除多余的and或or
<select id="select" resultType="car">
        select * from t_car 
        <where>
        <if test="brand !=null and brand!=''">
            brand like "%"#{brand}"%"
        </if>
        <if test="guidePrice !=null and guidePrice!=''">
            and guide_price > #{guidePrice}
        </if>
        <if test="carType !=null and carType!=''">
            and car_type > #{carType}
        </if>
        </where>
</select>

3、trim标签

 <select id="select" resultType="car">
    select * from t_car
    <trim prefixOverrides="删除前缀" prefix="增加前缀" suffixOverrides="删除后缀" suffix="增加后缀">
    		SQL句子
    </trim>
    </select>

例如:where + SQL 句子 + and ,此时增减前缀where ,并且and就多余,要删除后缀and

4、set标签

<update id="updateByid">
        update t_car set
            brand=#{brand},
            car_type=#{carType}
        where id=#{id}
    </update>
    
注:set标签会自动去除逗号
<update id="updateByid">
        update t_car 
        <set>
            <if test="brand !=null and brand!=''">brand=#{brand}, </if>
            <if test="car_type !=null and car_type!=''"> car_type=#{carType}, </if>
            where id=#{id}
        </set>     
</update>

5、Choose when otherwise标签

<chose>
        <when test=””></when>
        <when test=””></when>
        <otherwise></otherwise>
</chose>
等价于
if(   ){
    }else if(   ){
    else{
    }

6、foreach批量删除

int deleteByid(@Param(“ads”)Long[] ads);


<delete id="deleteByID">
        delete from t_car where id in (
            <foreach collection="ads" item="aaa" separator=",">
                #{aaa}
            </foreach>
            )
</delete>

Separator:自动添加逗号
Collection:为array或者arg0,若有配@Param,则直接用自定义名

<delete id="deleteByID">
        delete from t_car where id in 
            <foreach collection="ads" item="aaa" separator="," open="(" close=")">
                #{aaa}
            </foreach>
</delete>
或者用or
<delete id="deleteByID">
        delete from t_car where
            <foreach collection="ads" item="aaa" separator="or" open="(" close=")">
                Id=#{aaa}
            </foreach>
</delete>

7、foreach批量插入

int insertBatch(@Param("cars") List<Car> cars);


 <insert id="insertBatch">
        insert into t_car values 
        <foreach collection="cars" item="aaa" separator=",">
            (null,#{aaa.carNum},#{aaa.brand},#{aaa.guidePrice},#{aaa.produceTime},#{aaa.carType})
        </foreach>
 </insert>

8、SQL标签和include标签

 <select id="selectById" resultType="car">
        select
            id,
            car_num as carNum,
            brand,
            guide_price as guidePrice,
            produce_time as produceTime,
            car_type as carType
        from t_car where id=#{id}
</select>

等价于下面,提取公共得SQL代码:

<sql id="carColumn">
        id,
            car_num as carNum,
            brand,
            guide_price as guidePrice,
            produce_time as produceTime,
            car_type as carType
    </sql>

    <select id="selectById" resultType="car">
        select
          <include refid="carColumn"></include>
        from t_car where id=#{id}
    </select>

十三、高级映射

在这里插入图片描述

1、多对一,联级查询(1)

public class student {
    private Integer id;
    private String name;
    private gradeclass gradeclass1;
}

public class gradeclass {
    private Integer cid;
    private String clazz;
}

public interface studentMapper {
    student selectByid(Integer id);
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
t_student s left join t_gradeclass c on s.cid=c.cid左连接当且仅当on后面条件达到

2、多对一,association(2)

在这里插入图片描述

3、多对一,分布查询(3)

在这里插入图片描述
在这里插入图片描述
调用selectBycid进行sql查询得到cid再传给resultMap的cloum,association通过得到的cloum中cid跳到select给定的接口去查到,最后返回赋给property
注:fetchType="lazy"为懒加载模式,用到就查询,不用就不查询,提高性能
在核心配置文件中setting配置lazyloadingEnabled=ture则为全局懒加载

4、一对多,collection集合

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

5、一对多,延迟加载

在这里插入图片描述
在这里插入图片描述

十四、mybatis的缓存

一级Sqlseeeion缓存:通过同一个Sqlsession对象,默认开启 手动清空缓存:Sqlsession.clearCache()
二级SqlsessionFactory缓存:默认开启,SQLMapper.xml添加</cache>,将Pojo实体类implements serializable接口
Sqlsession对象关了,一级缓存的东西才会放到二级缓存
两次查询之间出现其他增删改,任何缓存一定失效

十五、Mybatis的逆向工程

根据数据库表逆向生成实体类、SqlMapper.xml、Mapper接口等

###第一步:在pom中添加逆向工程插件

<!--定制构建过程-->
<build>
  <!--可配置多个插件-->
  <plugins>
    <!--其中的一个插件:mybatis逆向工程插件-->
    <plugin>
      <!--插件的GAV坐标-->
      <groupId>org.mybatis.generator</groupId>
      <artifactId>mybatis-generator-maven-plugin</artifactId>
      <version>1.4.1</version>
      <!--允许覆盖-->
      <configuration>
        <overwrite>true</overwrite>
      </configuration>
      <!--插件的依赖-->
      <dependencies>
        <!--mysql驱动依赖-->
        <dependency>
          <groupId>mysql</groupId>
          <artifactId>mysql-connector-java</artifactId>
          <version>8.0.30</version>
        </dependency>
      </dependencies>
    </plugin>
  </plugins>
</build>

第二步:配置generatorConfig.xml

该文件名必须叫做:generatorConfig.xml
该文件必须放在类的根路径下。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
        PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
        "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">

<generatorConfiguration>
    <!--
        targetRuntime有两个值:
            MyBatis3Simple:生成的是基础版,只有基本的增删改查。
            MyBatis3:生成的是增强版,除了基本的增删改查之外还有复杂的增删改查。
    -->
    <context id="DB2Tables" targetRuntime="MyBatis3">
        <!--防止生成重复代码-->
        <plugin type="org.mybatis.generator.plugins.UnmergeableXmlMappersPlugin"/>
      
        <commentGenerator>
            <!--是否去掉生成日期-->
            <property name="suppressDate" value="true"/>
            <!--是否去除注释-->
            <property name="suppressAllComments" value="true"/>
        </commentGenerator>

        <!--连接数据库信息-->
        <jdbcConnection driverClass="com.mysql.cj.jdbc.Driver"
                        connectionURL="jdbc:mysql://localhost:3306/powernode"
                        userId="root"
                        password="root">
        </jdbcConnection>

        <!-- 生成pojo包名和位置 -->
        <javaModelGenerator targetPackage="com.powernode.mybatis.pojo" targetProject="src/main/java">
            <!--是否开启子包-->
            <property name="enableSubPackages" value="true"/>
            <!--是否去除字段名的前后空白-->
            <property name="trimStrings" value="true"/>
        </javaModelGenerator>

        <!-- 生成SQL映射文件的包名和位置 -->
        <sqlMapGenerator targetPackage="com.powernode.mybatis.mapper" targetProject="src/main/resources">
            <!--是否开启子包-->
            <property name="enableSubPackages" value="true"/>
        </sqlMapGenerator>

        <!-- 生成Mapper接口的包名和位置 -->
        <javaClientGenerator
                type="xmlMapper"
                targetPackage="com.powernode.mybatis.mapper"
                targetProject="src/main/java">
            <property name="enableSubPackages" value="true"/>
        </javaClientGenerator>

        <!-- 表名和对应的实体类名-->
        <table tableName="t_car" domainObjectName="Car"/>

    </context>
</generatorConfiguration>

第三步:启动

在这里插入图片描述

// 查一个
        Car car = mapper.selectByPrimaryKey(89L);
        System.out.println(car);
        // 查所有
        List<Car> cars = mapper.selectByExample(null);
        cars.forEach(c -> System.out.println(c));
        // 多条件查询
        // QBC 风格:Query By Criteria 一种查询方式,比较面向对象,看不到sql语句。
//用.createCriteria()创造查询条件
        CarExample carExample = new CarExample();
        carExample.createCriteria()
                .andBrandEqualTo("丰田霸道")
                .andGuidePriceGreaterThan(new BigDecimal(60.0));
//or指的是上面和下面是or的关系
        carExample.or().andProduceTimeBetween("2000-10-11", "2022-10-11");

        mapper.selectByExample(carExample);
        sqlSession.commit();

十六、MyBatis使用PageHelper

1、limit

mysql的limit后面两个数字:
● 第一个数字:startIndex(起始下标。下标从0开始。)
● 第二个数字:pageSize(每页显示的记录条数)
假设已知页码pageNum,还有每页显示的记录条数pageSize,第一个数字可以动态的获取吗?
● startIndex = (pageNum - 1) * pageSize
所以,标准通用的mysql分页SQL:

select  *  from   tableName 
limit   (pageNum - 1) * pageSize, pageSize


List<Car> selectByPage(@Param("startindex")int startindex,@Param("pageside")int pageside);
<select id="selectByPage" resultType="Car">
    select * from t_car limit #{startindex},#{pageside}
  </select>

2、PageHelper插件

第一步:引入依赖

<dependency>
  <groupId>com.github.pagehelper</groupId>
  <artifactId>pagehelper</artifactId>
  <version>5.3.1</version>
</dependency>

第二步:在mybatis-config.xml文件中配置插件

<plugins>
  <plugin interceptor="com.github.pagehelper.PageInterceptor"></plugin>
</plugins>

第三步:编写Java代码

List<Car> selectAll();

<select id="selectAll" resultType="Car">
  select * from t_car
</select>
@Test
public void testPageHelper() throws Exception{
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(Resources.getResourceAsStream("mybatis-config.xml"));
SqlSession sqlSession = sqlSessionFactory.openSession();
CarMapper mapper = sqlSession.getMapper(CarMapper.class);

// 执行SQL之前开启分页,第2页显示3条
    PageHelper.startPage(2, 3);
// 执行查询语句
    List<Car> cars = mapper.selectAll();
// 获取分页信息对象,导航的卡片的数量是5
    PageInfo<Car> pageInfo = new PageInfo<>(cars, 5);
    System.out.println(pageInfo);
}


结果:
PageInfo{
  pageNum=2, pageSize=2, size=2, startRow=3, endRow=4, total=6, pages=3, 
  list=Page{count=true, pageNum=2, pageSize=2, startRow=2, endRow=4, total=6, pages=3, reasonable=false, pageSizeZero=false}
  [Car{id=86, carNum='1234', brand='丰田霸道', guidePrice=50.5, produceTime='2020-10-11', carType='燃油车'}, 
  Car{id=87, carNum='1234', brand='丰田霸道', guidePrice=50.5, produceTime='2020-10-11', carType='燃油车'}], 
  prePage=1, nextPage=3, isFirstPage=false, isLastPage=false, hasPreviousPage=true, hasNextPage=true, 
  navigatePages=5, navigateFirstPage=1, navigateLastPage=3, navigatepageNums=[1, 2, 3]
}
pageInfo中有很多方法,可以得到信息返回前端显示

十七、MyBatis的注解式开发

1、@Insert

在这里插入图片描述

2、@Delete

在这里插入图片描述

3、@Update

在这里插入图片描述

4、@Select

在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值