没有结果的努力不叫努力
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 selectStudentByName(String Studentname);
@Select("select * from mybatis_student where id=#{value}")
Student selectStudentById(Long id);
@Select("select * from mybatis_student")
List 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片段
select * from mybatis_user
6.多表查询(一对一)
创建返回Map类,进行映射
(一对多)
association映射的是一个JavaBean类,它仅处理一对一的关联关系。
collection则是映射的一个集合列表,它处理的是一对多的关联关系。
自增id
插入数据后,把数据库自增id回绑到对象中selectKey
-- order表示何时计算主键值;oracle数据库使用序列进行自增,所以要使用before;mysql数据库使用LAST_INSERT_ID()函数计算,使用After
select LAST_INSERT_ID() from dual
insert into mybatis_student(name,gender,birthday,clazz_id) values (#{name},#{gender},#{birthday},#{clazz.id})
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 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
SqlMapConfig.xml
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映射文件中添加
2.在sql标签中使用useCache=true
3.把实体类实现java.io.serializable接口
企业使用数据库代替缓存redis
10.PageHelper
11.逆向工程
用的不多