MyBatis学习笔记

目录

步骤

多对一处理

一对多处理

其他标签的使用 

SqlSessionFactoryBuilder

SqlSessionFactory

SqlSession

缓存

依赖


步骤

1.配置文件 mybatis.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>

    <!--导入外部配置-->
    <properties resource="db.properties">
        <!--db.properties优先于内部property    -->
        <property name="" value=""/>
    </properties>

    <settings>
        <setting name="logImpl" value="LOG4J"/>
        <!--    显示的开启全局缓存    -->
        <setting name="cacheEnabled" value="true"/>
    </settings>

    <!--包起别名-->
    <typeAliases>
        <!--        <typeAlias type="com.lzq.pojo.User" alias="User"/>-->
        <package name="com.lzq.pojo"/><!--别名为user-->
        <!--还可以在实体类上使用注解@Alias-->
    </typeAliases>

    <environments default="development">
        <environment id="development">
            <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>

    <!--每一个Mapper.xml对应下面一个<mapper>-->
    <mappers>
        <mapper resource="com/lzq/dao/UserMapper.xml"/>
    </mappers>
</configuration>

2.pojo实体类

@Data
@AllArgsConstructor
@NoArgsConstructor
@Alias("user")
public class User implements Serializable {
    private int id;
    private String name;
}

3. SqlSession工具类,生成SqlSession实例

//SqlSessionFactory --> SqlSession
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(true);
    }
}

4.Mapper接口

public interface UserMapper {

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

    User getUserByID(int id);

    //@Select("select * from user where name like concat('%',#{value},'%')")
    List<User> getUserLike(String value);

    //分页
    List<User> getUserByLimit(Map<String,Object> map);

    int addUser(User user);

    int updateUser(User user);

    int updateUser2(Map<String,Object> map);

    int deleteUserByID(int id);

}

 5.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.lzq.dao.UserMapper">

    <!--  在当前Mapper中使用二级缓存  -->
    <cache eviction="FIFO" flushInterval="60000" readOnly="true" size="512"/>

    <select id="getUserList" resultType="com.lzq.pojo.User" useCache="true" >
        select * from mybatis.user
    </select>

    <select id="getUserByID" resultType="User" parameterType="int">
        select * from mybatis.user where id=#{id}
    </select>

    <!--结果集映射-->
    <resultMap id="UserMap" type="com.lzq.pojo.User">
        <!--column数据库字段名  property实体类属性名-->
        <result column="name" property="name"/>
    </resultMap>

    <select id="getUserLike" resultMap="UserMap">
        select * from mybatis.user where name like "%"#{value}"%"
    </select>

    <!--分页查询-->
    <select id="getUserByLimit" parameterType="map" resultMap="UserMap">
        select * from mybatis.user limit #{startIndex},#{pageSize}
    </select>

    <!--    User对象中的属性可以直接取出来-->
    <insert id="addUser" parameterType="com.lzq.pojo.User">
        insert into mybatis.user (id,name) values (#{id},#{name})
    </insert>

    <update id="updateUser" parameterType="com.lzq.pojo.User">
        update mybatis.user set name=#{name} where id=#{id}
    </update>

    <!--    map类型根据key取出-->
    <update id="updateUser2" parameterType="map">
        update mybatis.user set name=#{Name} where id=#{ID}
    </update>

    <delete id="deleteUserByID" parameterType="int">
        delete from mybatis.user where id=#{id}
    </delete>

</mapper>

6.测试

@Test
    public void getUser() {
        //1.获取SqlSession对象
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        //2.执行sql 方式一 getMapper
        UserMapper userdao = sqlSession.getMapper(UserMapper.class);
        List<User> userList = userdao.getUserList();
        User user1 = userdao.getUserByID(1);
//        //2.执行sql 方式二
//        List<User> userList = sqlSession.selectList("com.lzq.dao.UserDao.getUserList");
//        User user1 = sqlSession.selectOne("com.lzq.dao.UserDao.getUserByID",1);

        for (User user : userList) {
            System.out.println(user);
        }
        System.out.println(user1);

        //3.关闭SqlSession
        sqlSession.close();
    }

其他:log4j属性文件 

log4j.rootLogger=DEBUG,console,file

#??????????
log4j.appender.console = org.apache.log4j.ConsoleAppender
log4j.appender.console.Target = System.out
log4j.appender.console.Threshold=DEBUG
log4j.appender.console.layout = org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=[%c]-%m%n

#?????????
log4j.appender.file = org.apache.log4j.RollingFileAppender
log4j.appender.file.File=./log/lzq.log
log4j.appender.file.MaxFileSize=10mb
log4j.appender.file.Threshold=DEBUG
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=[%p][%d{yyyy-MM-dd HH:mm:ss}][%c]%m%n

#??????
log4j.logger.org.mybatis=DEBUG
log4j.logger.java.sql=DEBUG
log4j.logger.java.sql.Statement=DEBUG
log4j.logger.java.sql.ResultSet=DEBUG
log4j.logger.java.sql.PreparedStatement=DEBUG

多对一处理

多个学生对应一个老师

<!--多对一 联表查询(按照结果嵌套)-->
    <select id="getStudent" resultMap="StudentTeacher">
        select s.id sid,s.name sname,t.id tid,t.name tname
        from student s,teacher t
        where s.tid=t.id
    </select>
    <resultMap id="StudentTeacher" type="Student">
        <result property="id" column="sid"/>
        <result property="name" column="sname"/>
        <!--复杂的属性teacher单独处理,对象用association 集合用collection-->
        <association property="teacher" javaType="Teacher">
            <result property="id" column="tid"/>
            <result property="name" column="tname"/>
        </association>
    </resultMap>

    <!--多对一 子查询(按照查询嵌套)-->
    <!--select * from student where tid=(select id from teacher where id=tid)-->
    <select id="getStudent2" resultMap="StudentTeacher2">
        select * from student
    </select>
    <resultMap id="StudentTeacher2" type="Student">
        <result property="id" column="id"/>
        <result property="name" column="name"/>
        <!--复杂的属性teacher单独处理,对象用association 集合用collection-->
        <association property="teacher" column="tid" javaType="Teacher" select="getTeacher"/>
    </resultMap>
    <select id="getTeacher" resultType="Teacher">
        select * from teacher where id=#{tid}
    </select>

一对多处理

一个老师对应多个学生

<select id="getTeacher" resultType="Teacher">
        select * from teacher
    </select>

    <!--一对多 联表查询-->
    <select id="getTeacherStudentByID" resultMap="TeacherStudent">
        select t.id tid,t.name tname,s.id sid,s.name sname
        from teacher t,student s
        where t.id=s.tid and t.id=#{tid}
    </select>
    <resultMap id="TeacherStudent" type="Teacher">
        <result column="tid" property="id"/>
        <result column="tname" property="name"/>
        <!--复杂的属性students单独处理,对象用association 集合用collection
            javeType="" 指定属性类型  集合中的泛型信息用ofType=""-->
        <collection property="students" ofType="Student">
            <result column="sid" property="id"/>
            <result column="sname" property="name"/>
            <result column="tid" property="tid"/>
        </collection>
    </resultMap>

    <!--一对多 子查询  select * from teacher where id=#{tid} and id=(select tid from student where tid=id)-->
    <select id="getTeacherStudentByID2" resultMap="TeacherStudent2">
        select * from teacher where id=#{tid}
    </select>
    <resultMap id="TeacherStudent2" type="Teacher">
        <result column="id" property="id"/>
        <result column="name" property="name"/>
        <!--复杂的属性students单独处理,对象用association 集合用collection
            javeType="" 指定属性类型  集合中的泛型信息用ofType=""-->
        <collection property="students" column="id" ofType="Student" select="getStudent"/>
    </resultMap>
    <select id="getStudent" resultType="Student">
        select * from student where tid=#{id}
    </select>

其他标签的使用 

<!--sql片段-->
    <sql id="if-title-author">
        <if test="title != null">
            and title like "%"#{title}"%"
        </if>
        <if test="author != null">
            and author like "%"#{author}"%"
        </if>
    </sql>

    <select id="getBlogIFLike" resultType="Blog" parameterType="map">
        select * from blog
        <where>
            <include refid="if-title-author"></include>
        </where>
    </select>

    <select id="getBlogChooseLike" resultType="Blog" parameterType="map">
        select * from blog
        <where>
            <choose>
                <!--选一个!!!!!!!!-->
                <when test="title != null">title like "%"#{title}"%"</when>
                <when test="author != null">author like "%"#{author}"%"</when>
                <otherwise>views = #{views}</otherwise>
            </choose>
        </where>
    </select>

    <!--  select * from blog where (id=1 or id=2 or id=3)  -->
    <select id="getBlogForEach" resultType="Blog" parameterType="map">
        select * from blog
        <where>
            <foreach collection="ids" item="id" open="(" separator="or" close=")">
                id=#{id}
            </foreach>
        </where>
    </select>

    <update id="updateBlog" parameterType="Blog">
        update blog
        <set>
            <if test="title != null">title=#{title},</if>
            <if test="author != null">author=#{author},</if>
            <if test="views != null">views=#{views},</if>
        </set>
        where id=#{id}
    </update>

SqlSessionFactoryBuilder

最佳作用域是方法作用域(也就是局部方法变量)

SqlSessionFactory

最佳作用域是应用作用域。 有很多方法可以做到,最简单的就是使用单例模式或者静态单例模式。

SqlSession

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

缓存

一级缓存:默认开启,只在一次sqlSession会话中有效,sqlSession.close就关闭了

一级缓存失效的情况:

  1. 查询不同的东西
  2. 增删改操作,可能会改变数据,所以必定刷新缓存
  3. 查询不同的Mapper.xml(二级缓存也失效)
  4. 手动清理缓存(sqlSession.clearCache)

二级缓存:namespace级别(Mapper级别),多个SqlSession去操作同一个Mapper的sql语句,多个SqlSession可以共用二级缓存,二级缓存是跨SqlSession的。

1.映射语句文件中的所有 select 语句的结果将会被缓存。

2.映射语句文件中的所有 insert、update 和 delete 语句会刷新缓存。

(均可通过标签属性useCache flushCache等设置)

Ps:所有数据先放到一级缓存,只有会话(sqlSession)提交或关闭时才会提交到二级缓存!

依赖

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.44</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.7</version>
        </dependency>

        <!--在实体类上自动生成get set等方法-->
        <!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.22</version>
            <!--<scope>provided</scope>-->
        </dependency>

        <!-- log4j start -->
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>
            <!--资源加载,使src/main/java下的资源可以加载进去,默认在src/main/resources-->
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                </includes>
                <filtering>false</filtering>
            </resource>

八股

Dao 接口的工作原理是 JDK 动态代理,MyBatis 运行时会使用 JDK 动态代理为 Dao 接口生成代理对象,代理对象拦截接口方法,执行 MappedStatement 所代表的 sql,将执行结果返回。

MyBatis与Hibernate:Hibernate属于全自动 ORM 映射工具,使用 Hibernate 查询关联对象或者关联集合对象时,可以根据对象关系模型直接获取,所以它是全自动的。而 MyBatis 在查询关联对象或关联集合对象时,需要手动编写 sql 来完成,所以,称之为半自动 ORM 映射工具。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值