mybatis2

没有结果的努力不叫努力

1.将连接工厂的操作写成工具类

MyBatisUtil
package com.mybatis.util;

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

public class MyBatisUtil {
    static SqlSession sqlSession;
    static SqlSessionFactory sqlSessionFactory;

    static {
        try {
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(Resources.getResourceAsReader("SqlMapConfig.xml"));
        } catch (Exception e) {
            throw new RuntimeException(e.getMessage());
        }
    }

    public static SqlSession getSession(boolean autoCommit) {
        return sqlSessionFactory == null ? null : sqlSessionFactory.openSession(autoCommit);

    }

    public static void close(SqlSession sqlSession) {
        if (sqlSession != null) {
            sqlSession.close();
        }
    }
}

2.不写mapper.xml,采用注解形式

StudentMapper
package com.mybatis.mapper;

import com.mybatis.entity.Student;
import org.apache.ibatis.annotations.Select;

import java.util.List;
/*
* 注解方式
* */
public interface StudentMapper {
    @Select("select * from mybatis_student where name like concat('%',#{value},'%')")
    List<Student> selectStudentByName(String Studentname);

    @Select("select * from mybatis_student where id=#{value}")
    Student selectStudentById(Long id);

    @Select("select * from mybatis_student")
    List<Student> selectAllStudents();

    void delectStudentById(Long id);

    long countStudent();
}

3.动态SQL 

根据实体类的不同取值,使用不同的SQL语句来进行查询,比如在id如果不为空时可以根据id查询,如果username不为空时还要加入用户名作为条件

测试类运行

package com.mybatis.mapper;

import com.mybatis.entity.Student;
import com.mybatis.util.MyBatisUtil;
import junit.framework.TestCase;
import org.junit.Test;

public class StudentMapperTest extends TestCase {

    StudentMapper mapper=MyBatisUtil.getSession(true).getMapper(StudentMapper.class);

    public void testSelectStudentByName() {
        mapper.selectStudentByName("a").forEach(System.out::println);
    }

    public void testSelectStudentById() {
        Student student =mapper.selectStudentById(1L);
        System.out.println(student);
    }
    @Test
    public void testSelectAllStudents() {
        mapper.selectAllStudents().forEach(System.out::println);
    }

    public void testDelectStudentById() {
    }

    public void testCountStudent() {
    }
}

运行结果

4.p6spy用来探测生成的SQL语句中的?的真实值

(1)安装相应的jar包

(2)将数据库连接的驱动换成p6spy的连接

(3)p6spy的数据库连接之前的驱动

按照教程配置,但是控制台不显示,我也不知道为什么

显示在spy.log文件中了

5.sql片段

    <sql id="select_user">
        select * from mybatis_user
    </sql>

    <!--    根据id查询用户-->
    <select id="selectUserById" parameterType="java.lang.Long" resultType="user">
        <include refid="select_user"></include>
        where id=#{value}
    </select>

6.多表查询(一对一)

创建返回Map类,进行映射

<?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">
<!-- namespace:填写映射当前的Mapper接口,所有的增删改查的参数和返回值类型,
		就可以直接填写缩写,不区分大小写,直接通过方法名去找类型-->
<mapper namespace="com.mybatis.mapper.StudentMapper">
    <!--一对一关联查询-->
    <select id="selectStudentById" parameterType="java.lang.Long" resultMap="scMap">
        select s.*,c.id cid, c.name cname from mybatis.mybatis_student s join mybatis.mybatis_clazz c on s.clazz_id=c.id
        where s.id=#{value}
    </select>
    <!--关联查询的映射-->
    <resultMap id="scMap" type="student">
        <!--学生主键-->
        <id property="id" column="id"/>
        <!--学生其他属性-->
        <result column="name" property="name"/>
        <result column="gender" property="gender"/>
        <result column="birthday" property="birthday"/>
        <!--班级信息(一对一)-->
        <association property="clazz" column="clazz">
            <!--班级主键-->
            <id  column="cid" property="id"/>
            <!--班级其他属性-->
            <result column="cname" property="name"/>
        </association>
    </resultMap>

</mapper>

(一对多)

<?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">
<!-- namespace:填写映射当前的Mapper接口,所有的增删改查的参数和返回值类型,
		就可以直接填写缩写,不区分大小写,直接通过方法名去找类型-->
<mapper namespace="com.mybatis.mapper.ClazzMapper">
    <select id="selectClazzById" resultMap="csMap">
        select c.id cid,c.name cname,s.* from mybatis_clazz c left join mybatis_student s
        on s.clazz_id=c.id where c.id=#{value}
    </select>

    <resultMap id="csMap" type="clazz">
        <id property="id" column="cid"/>
        <result property="name" column="cname"/>
        <!--一对多-->
        <collection property="students" ofType="student">
            <id property="id" column="id"/>
            <result column="name" property="name"/>
            <result column="gender" property="gender"/>
            <result column="birthday" property="birthday"/>
        </collection>
    </resultMap>
</mapper>

association映射的是一个JavaBean类,它仅处理一对一的关联关系。
collection则是映射的一个集合列表,它处理的是一对多的关联关系。

自增id

插入数据后,把数据库自增id回绑到对象中selectKey 

<?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">
<!-- namespace:填写映射当前的Mapper接口,所有的增删改查的参数和返回值类型,
		就可以直接填写缩写,不区分大小写,直接通过方法名去找类型-->
<mapper namespace="com.mybatis.mapper.StudentMapper">
    <!--添加学生-->
    <insert id="insertStudent" parameterType="student">
--         order表示何时计算主键值;oracle数据库使用序列进行自增,所以要使用before;mysql数据库使用LAST_INSERT_ID()函数计算,使用After
        <selectKey keyProperty="id" resultType="long" order="AFTER">
            select LAST_INSERT_ID() from dual
        </selectKey>
        insert into mybatis_student(name,gender,birthday,clazz_id) values (#{name},#{gender},#{birthday},#{clazz.id})
    </insert>
    <!--一对一关联查询-->
    <select id="selectStudentById" parameterType="java.lang.Long" resultMap="scMap">
        select s.*,c.id cid, c.name cname from mybatis.mybatis_student s join mybatis.mybatis_clazz c on s.clazz_id=c.id
        where s.id=#{value}
    </select>
    <!--关联查询的映射-->
    <resultMap id="scMap" type="student">
        <!--学生主键-->
        <id property="id" column="id"/>
        <!--学生其他属性-->
        <result column="name" property="name"/>
        <result column="gender" property="gender"/>
        <result column="birthday" property="birthday"/>
        <!--班级信息(一对一)-->
        <association property="clazz" column="clazz">
            <!--班级主键-->
            <id column="cid" property="id"/>
            <!--班级其他属性-->
            <result column="cname" property="name"/>
        </association>
    </resultMap>

</mapper>

 

7.延迟加载

https://www.cnblogs.com/neon/p/10940346.html

就是在需要用到数据时才进行加载,不需要用到数据时就不加载数据。延迟加载也称为懒加载。

好处:先从单表查询,需要时再从关联表去关联查询,大大提高数据库性能,因为查询单表要比关联查询多张表速度要快。

坏处:因为只有当需要用到数据时,才会进行数据库查询,这样在大批量数据查询时,因为查询工作也要消耗时间,所以可能造成用户等待时间变长,造成用户体验下降。

customer

package com.mybatis.entity;

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

import java.util.List;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Customer {
    private Long id;
    private String name;
    private List<Order> orders;

    @Override
    public String toString() {
        return "Customer{" +
                "id=" + id +
                ", name='" + name + '\'' +
                '}';
    }
}

order

package com.mybatis.entity;

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

import java.util.Date;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Order {
    private Long id;
    private String orderno;
    private Double price;
    private Date createDate;

    private Customer customer;

    @Override
    public String toString() {
        return "Order{" +
                "id=" + id +
                ", orderno='" + orderno + '\'' +
                ", price=" + price +
                ", create=" + createDate +
                '}';
    }
}
CustomerAndOrderMapper
package com.mybatis.mapper;

import com.mybatis.entity.Customer;

public interface CustomerAndOrderMapper {
    /**
     * 查询顾客,如果顾客有订单,则级联查询出订单信息
     * 懒加载模式
     * */
    Customer selectCustomerAndOrderById(Long id);
}

CustomerAndOrderMapper.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">
<!-- namespace:填写映射当前的Mapper接口,所有的增删改查的参数和返回值类型,
		就可以直接填写缩写,不区分大小写,直接通过方法名去找类型-->
<mapper namespace="com.mybatis.mapper.CustomerAndOrderMapper">
    <select id="selectCustomerAndOrderById" parameterType="long" resultMap="coMap">
        select id,name from mybatis_customer where id=#{value}
    </select>
    <select id="selectOrderByCustomerId" parameterType="long" resultType="order">
        select * from mybatis_order where customer_id=#{value}
    </select>

    <resultMap id="coMap" type="customer">
        <id column="id" property="id"/>
        <result column="name" property="name"/>
        <!--提供了延迟加载-->
        <collection property="orders" ofType="order" select="selectOrderByCustomerId" column="id"/>
    </resultMap>
</mapper>

SqlMapConfig.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"/>-->
    <!--配置properties-->
    <properties>
        <property name="driver" value="com.p6spy.engine.spy.P6SpyDriver"></property>
        <property name="url" value="jdbc:p6spy:mysql://localhost:3306/mybatis?serverTimezone=Asia/Shanghai"></property>
        <property name="username" value="root"></property>
        <property name="password" value="123456"></property>
    </properties>
    <settings>
        <!--开启延迟加载的支持-->
        <setting name="lazyLoadingEnabled" value="true"/>
        <setting name="aggressiveLazyLoading" value="false"/>
        
        <setting name="logImpl" value="LOG4J"/>
    </settings>
    <!--    别名设置,全路径名改成类名-->
    <typeAliases>
        <!--        该包下面实体类全部采用别名形式-->
        <package name="com.mybatis.entity"/>
    </typeAliases>
    <!--    使用mybatis内置的枚举转换器(默认String)-->
    <typeHandlers>
        <typeHandler handler="org.apache.ibatis.type.EnumOrdinalTypeHandler"
                     javaType="com.mybatis.entity.Gender"></typeHandler>
    </typeHandlers>
    <!--数据库配置环境-->
    <environments default="mysql">
        <!-- 配置mysql的环境-->
        <environment id="mysql">
            <!-- 配置事务 -->
            <transactionManager type="JDBC"></transactionManager>

            <!--配置连接池-->
            <dataSource type="POOLED">
                <property name="driver" value="${driver}"></property>
                <property name="url" value="${url}"></property>
                <property name="username" value="${username}"></property>
                <property name="password" value="${password}"></property>
            </dataSource>
        </environment>
    </environments>
    <!-- 配置映射文件的位置 -->
    <mappers>
        <package name="com.mybatis.mapper"></package>
        <!--        <mapper resource="com/mybatis/mapper/UserMapper.xml"></mapper>-->
    </mappers>
</configuration>
CustomerAndOrderMapperTest
package com.mybatis.mapper;

import com.mybatis.entity.Customer;
import com.mybatis.util.MyBatisUtil;
import junit.framework.TestCase;

public class CustomerAndOrderMapperTest extends TestCase {
    CustomerAndOrderMapper mapper = MyBatisUtil.getSession(true).getMapper(CustomerAndOrderMapper.class);

    public void testSelectCustomerAndOrderById() {
        Customer customer = mapper.selectCustomerAndOrderById(1L);
        //如果只使用顾客,则延迟加载策略会暂时屏蔽订单的查询
        System.out.println(customer);
        //当要使用订单信息时,将会打破延迟加载,查询订单信息
        customer.getOrders().forEach(System.out::println);
    }
}

运行结果

8.一级缓存

当第一次时,和数据库发生交互,执行SQL语句,并且把查询到的数据放入缓存中。如果第二次查询,查询的内容是一样的,则直接从一级缓存中获取数据,不和数据库发生交互,从而提高查询性能。

注意:如果查询后把sqlsession提交或关闭了,则一级缓存数据将清空。

9.二级缓存

作用范围是sqlsessionfactory,是多个sqlsession共享,默认关闭,需要配置开启,

可以使用默认的缓存,也可以使用第三方缓存工具(ehcache)

配置方法

1.在mapper.xml映射文件中添加<cache></cache>

2.在sql标签中使用useCache=true

3.把实体类实现java.io.serializable接口

企业使用数据库代替缓存redis

10.PageHelper

11.逆向工程

用的不多

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值