第一个mybatis项目

Mybatis

1.pom.xml 基础配置:

<?x`ml version="1.0" encoding="UTF-8"?><project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
          <modelVersion>4.0.0</modelVersion>`
<groupId>org.example</groupId>
<artifactId>MavenProject04</artifactId>
<packaging>pom</packaging>
<version>1.0-SNAPSHOT</version>

<modules>
    <module>Mybatis01</module>

    <module>Mybatis02</module>
    <module>Mybatis03</module>

</modules>



<dependencies>
//数据库jar包
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>8.0.19</version>
    </dependency>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.11</version>
        <scope>test</scope>
    </dependency>

  <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis</artifactId>
        <version>3.4.6</version>
    </dependency>
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.18.12</version>
    <scope>provided</scope>
</dependency>
</dependencies>

2.如果遇到资源无法导出的问题在pom.xml配置文件末尾加入:

  <build>
    <resources>
        <resource>
            <directory>src/main/java</directory>
            <includes>
                <include>**/*.properties</include>
                <include>**/*.xml</include>
            </includes>
            <filtering>false</filtering>
        </resource>
        <resource>
            <directory>src/main/resources</directory>
            <includes>
                <include>**/*.properties</include>
                <include>**/*.xml</include>
            </includes>
            <filtering>false</filtering>
        </resource>
    </resources>
</build>

3.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>
//开启驼峰命名

 <settings>
      <setting name="mapUnderscoreToCamelCase" value="true"/>
    </settings>

    <properties resource="db.properties">

    </properties>


    <environments default="test">
        <environment id="test">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="${driver}"/>
                <property name="url" value="${url}"/>
                <property name="username" value="${username}"/>
                <property name="password" value="${password}"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <mapper class="dao.UserMapper"/>
    </mappers>
</configuration>

4.每一个mapper.xml都要在mybatis-config.xml文件中注册

``<ma`ppers>

  `

5.接口对应的Mapper映射文件

<?xml version="1.0" encoding="UTF-8" ?>
<select id="selectUser" resultType="User">
  select * from user
</select>

6.utils代码:

package com.kuang.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 {
 static SqlSessionFactory sqlSessionFactory;


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

    public static SqlSession getSqlsession(){

     return sqlSessionFactory.openSession();

    }

}

7.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.kuang.dao.UserMapper">
<!--实现分页查询-->
    <select id="selectUserLimit" resultType="aa" parameterType="map" >
   select * from user.user limit #{startIndex},#{pageSize}
    </select>
</mapper>

8.db.properties:

driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/user?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone = GMT
username=root
password=123

9.log4j.properties

### 设置###
log4j.rootLogger = debug,stdout,D,E

### 输出信息到控制抬 ###
log4j.appender.stdout = org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target = System.out
log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern = [%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS} method:%l%n%m%n

### 输出DEBUG 级别以上的日志到=log/error.log ###
log4j.appender.D = org.apache.log4j.DailyRollingFileAppender
log4j.appender.D.File = log/log.log
log4j.appender.D.Append = true
log4j.appender.D.Threshold = DEBUG 
log4j.appender.D.layout = org.apache.log4j.PatternLayout
log4j.appender.D.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss}  [ %t:%r ] - [ %p ]  %m%n

### 输出ERROR 级别以上的日志到=E://logs/error.log ###
log4j.appender.E = org.apache.log4j.DailyRollingFileAppender
log4j.appender.E.File =log/error.log 
log4j.appender.E.Append = true
log4j.appender.E.Threshold = ERROR 
log4j.appender.E.layout = org.apache.log4j.PatternLayout
log4j.appender.E.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss}  [ %t:%r ] - [ %p ]  %m%n

10.log4j maven依赖

<!--<dependency>
     <groupId>org.slf4j</groupId>
     <artifactId>slf4j-api</artifactId>
     <version>1.6.6</version>
 </dependency>-->
<dependency>
     <groupId>org.slf4j</groupId>
     <artifactId>slf4j-log4j12</artifactId>
     <version>1.6.6</version>
 </dependency>
<!-- <dependency>
     <groupId>log4j</groupId>
     <artifactId>log4j</artifactId>
     <version>1.2.16</version>
 </dependency>-->

复杂查询环境搭建

1.多对一:称之为关联

1.关于传参

用注解来简化xml配置的时候,@Param注解的作用是给参数命名,参数命名后就能根据名字得到参数值,正确的将参数传入sql语句中

我们先来看Mapper接口中的@Select方法

package` `Mapper; 
 
 
public` `interface` `Mapper { 
 
@Select``(``"select s_id id,s_name name,class_id classid from student where s_name= #{aaaa} and class_id = #{bbbb}"``) 
  ``public` `Student select(``@Param``(``"aaaa"``) String name,``@Param``(``"bbbb"``)``int` `class_id); 
 
@Delete``...... 
   
@Insert``...... 
  
} 

1.@Select(…)注解的作用就是告诉mybatis框架,执行括号内的sql语句

2.s_id id,s_name name,class_id classid 格式是 字段名+属性名,例如s_id是数据库中的字段名,id是类中的属性名

这段代码的作用就是实现数据库字段名和实体类属性的一一映射,不然数据库不知道如何匹配

3.where s_name= #{aaaa} and class_id = #{bbbb} 表示sql语句要接受2个参数,一个参数名是aaaa,一个参数名是bbbb,如果要正确的传入参数,那么就要给参数命名,因为不用xml配置文件,那么我们就要用别的方式来给参数命名,这个方式就是@Param注解

4.在方法参数的前面写上@Param(“参数名”),表示给参数命名,名称就是括号中的内容

public Student select(@Param(“aaaa”) String name,@Param(“bbbb”)int class_id);
给入参 String name 命名为aaaa,然后sql语句…where s_name= #{aaaa} 中就可以根据aaaa得到参数值了

2.在控制台输出日志
<dependency>
     <groupId>org.slf4j</groupId>
     <artifactId>slf4j-log4j12</artifactId>
     <version>1.6.6</version>
 </dependency>

标准日志:在Mybatis-config.xml配置文件中加入

<settings>
    <setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>
3.多对一查询结果处理 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.kuang.mapper.StudentMapper">

    <!--
    根据查询出来的结果来嵌套处理
    -->
    <select id="getStudent1" resultMap="TeacherStudent1" >
select s.num snum,s.name sname,s.timi stimi,t.id tid,t.name tname
from student s,teacher t where s.timi=t.id
    </select>
    <resultMap id="TeacherStudent1" type="com.kuang.pojo.Student">
        <result property="num" column="snum"/>
        <result property="name" column="sname"/>
        <result property="timi" column="stimi"/>
        <association property="teacher" javaType="com.kuang.pojo.Teacher">
            <result property="id" column="tid"></result>
            <result property="name" column="tname"></result>
        </association>
    </resultMap>
    <!--
    查询出所有学生的信息
    根据学生的timi找到对应的老师
    -->
    <select id="getStudent" resultMap="TeacherStudent">
        select * from student
    </select>

    <resultMap id="TeacherStudent" type="com.kuang.pojo.Student">
        <association property="teacher" column="timi" javaType="com.kuang.pojo.Teacher" select="getTeacher"/>
    </resultMap>

    <select id="getTeacher" resultType="com.kuang.pojo.Teacher">
        select * from teacher where id=#{dd}
    </select>

</mapper>
4.实体类
1.student
package com.kuang.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Student {
    private int num;
    private String name;
    private int timi;
    Teacher teacher;

}
2.teacher
package com.kuang.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.List;

@AllArgsConstructor
@Data
@NoArgsConstructor
public class Teacher {
    private int id;
    private String name;
    
}

2.和一对多:称之为集合

1.TeacherStudent.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.kuang.mapper.TeacherMapper">
<select id="getTeacher" resultMap="TeacherStudent1">
select s.num,s.name,s.timi,t.id,t.name from student s,
teacher t where t.id=s.timi

</select>
    <!--

    -->

    <resultMap id="TeacherStudent1" type="com.kuang.pojo.Teacher">
        <result property="id" column="t.id"/>
        <result property="name" column="t.name"/>

        <!--
        collection:一对多
        ofType:集合中泛型信息用ofType获取
        -->
        <collection property="student" ofType="com.kuang.pojo.Student" >
            <result property="num" column="s.num"/>
            <result property="name" column="s.name"/>
            <result property="timi" column="s.timi"/>
        </collection>
    </resultMap>

</mapper>
2.student的实体类:
package com.kuang.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Student {
    private int num;
    private String name;
    private int timi;

}
3.teacher的实体类
package com.kuang.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.List;

@AllArgsConstructor
@Data
@NoArgsConstructor
public class Teacher {
    private int id;
    private String name;
    private List<Student> student;
}

动态sql

1.like通配符

通配符的分类:
%百分号通配符: 表示任何字符出现任意次数 (可以是0次).
_下划线通配符:表示只能匹配单个字符,不能多也不能少,就是一个字符.

like操作符:
LIKE作用是指示mysql后面的搜索模式是利用通配符而不是直接相等匹配进行比较.
注意: 如果在使用like操作符时,后面的没有使用通用匹配符效果是和=一致的,SELECT * FROM products WHERE products.prod_name like '1000';只能匹配的结果为1000,而不能匹配像JetPack 1000这样的结果.

1)%通配符使用:
匹配以"yves"开头的记录:(包括记录"yves")
SELECT * FROM products WHERE products.prod_name like 'yves%';

匹配包含"yves"的记录(包括记录"yves")
SELECT * FROM products WHERE products.prod_name like '%yves%';

匹配以"yves"结尾的记录(包括记录"yves",不包括记录"yves ",也就是yves后面有空格的记录,这里需要注意)
SELECT * FROM products WHERE products.prod_name like '%yves';

2)_通配符使用:
SELECT * FROM products WHERE products.prod_name like '_yves';
匹配结果为: 像"yyves"这样记录.

SELECT * FROM products WHERE products.prod_name like 'yves__';
匹配结果为: 像"yvesHe"这样的记录.(一个下划线只能匹配一个字符,不能多也不能少)

注意事项:

  • 注意大小写,在使用模糊匹配时,也就是匹配文本时,mysql是可能区分大小的,也可能是不区分大小写的,这个结果是取决于用户对MySQL的配置方式.如果是区分大小写,那么像YvesHe这样记录是不能被"yves__"这样的匹配条件匹配的.
  • 注意尾部空格,"%yves"是不能匹配"heyves "这样的记录的.
  • 注意NULL,%通配符可以匹配任意字符,但是不能匹配NULL,也就是说SELECT * FROM products WHERE products.prod_name like '%';是匹配不到products.prod_name为NULL的的记录.

技巧与建议:
正如所见, MySQL的通配符很有用。但这种功能是有代价的:通配符搜索的处理一般要比前面讨论的其他搜索所花时间更长。这里给出一些使用通配符要记住的技巧。

  • 不要过度使用通配符。如果其他操作符能达到相同的目的,应该 使用其他操作符。
  • 在确实需要使用通配符时,除非绝对有必要,否则不要把它们用 在搜索模式的开始处。把通配符置于搜索模式的开始处,搜索起 来是最慢的。
  • 仔细注意通配符的位置。如果放错地方,可能不会返回想要的数.

2.IF

<if test="bookName != null">
    bookName like #{bookName}
</if>
<if test="bookCount != null">
    AND bookCounts like #{bookCount}
</if>

3.trim、where、set

<trim prefix="WHERE" prefixOverrides="AND |OR ">
  ...
</trim>
<trim prefix="SET" suffixOverrides=",">
  ...
</trim>

4.choose、when、otherwise

有时候,我们不想使用所有的条件,而只是想从多个条件中选择一个使用。针对这种情况,MyBatis 提供了 choose 元素,它有点像 Java 中的 switch 语句。

<select id="findActiveBlogLike"
     resultType="Blog">
  SELECT * FROM BLOG WHERE state = ‘ACTIVE’
  <choose>
    <when test="title != null">
      AND title like #{title}
    </when>
    <when test="author != null and author.name != null">
      AND author_name like #{author.name}
    </when>
    <otherwise>
      AND featured = 1
    </otherwise>
  </choose>
</select>

5.sql片段

提取公共部分实现代码复用

<sql id="bookName">将公共部分代码放入sql中,要用的地方加入<include></include标签
    <if test="bookName != null">
        bookName like #{bookName}
    </if>
</sql>
 <include refid="bookName"></include>

6.froeach循环(报错)

select * from books
<where> //collection是map传输进来的
    <foreach collection="list" item="id"  open="and  (" separator="," close=")">
        #{goodsId}>
        bookId=#{id}
    </foreach>
</where>
SqlSession sqlsession = MybatisUtils.getSqlsession();
        BookMapper bookmapper = sqlsession.getMapper(BookMapper.class);
        Map map=new HashMap();
        //map.put("bookName","Mysql数据库");
       // map.put("bookCount",3);
        ArrayList<Integer> list=new ArrayList<Integer>();
        list.add(2);
        list.add(4);
        map.put("list",list);
        List<Book> books = bookmapper.SelectBook(map);
        for (Book bookList: books
             ) {
            System.out.println(bookList);

7.缓存

什么是缓存:存在内存中的临时数据

为什么使用缓存:减少用户与数据库的交互次数,减少系统开销,提高效率

什么时候使用缓存:经常查询且不改变的数据

mybati自带一级缓存和二级缓存。

1.一级缓存:默认情况是开启的(sqlSession级别缓存,又称本地缓存)

 SqlSession sqlsession= MybatisUtils.getsqlSession();
        UserMapper usermapper=sqlsession.getMapper(UserMapper.class);
        List<User>userlist=usermapper.selectUserList();
        for (User user:userlist
             ) {
            System.out.println(user);

        }
        sqlsession.clearCache();//清楚缓存,缓存数据不存在
        List<User>userlist1=usermapper.selectUserList();
        for (User user:userlist1
             ) {
            System.out.println(user);
        }
        System.out.println(userlist==userlist1);
sqlsession.close();

2.二级缓存:需要手动开启,基于namespace级别。

<cache
  eviction="FIFO"
  flushInterval="60000"
  size="512"
  readOnly="true"/>
  这个更高级的配置创建了一个 FIFO 缓存,每隔 60 秒刷新,最多可以存储结果对象或列表的 512 个引用,而且返回的对象被认为是只读的,因此对它们进行修改可能会在不同线程中的调用者产生冲突。

3.缓存的实现原理

serList();
for (User user:userlist
) {
System.out.println(user);

    }
    sqlsession.clearCache();//清楚缓存,缓存数据不存在
    List<User>userlist1=usermapper.selectUserList();
    for (User user:userlist1
         ) {
        System.out.println(user);
    }
    System.out.println(userlist==userlist1);

sqlsession.close();


### 2.二级缓存:需要手动开启,基于namespace级别。


这个更高级的配置创建了一个 FIFO 缓存,每隔 60 秒刷新,最多可以存储结果对象或列表的 512 个引用,而且返回的对象被认为是只读的,因此对它们进行修改可能会在不同线程中的调用者产生冲突。


3.缓存的实现原理

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XGC8juy0-1604053421343)(C:\Users\asus\AppData\Roaming\Typora\typora-user-images\image-20201014135315075.png)]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值