JavaEE之SSM框架——Mybatis

目录

1.Mybatis介绍

2.搭建Mybatis

2.1.添加驱动包(mysql.jar和mybatis的jar包)

2.2.添加配置⽂件:src/mybatis-config.xml

2.3.创建实体类和接⼝类

2.4添加mapper⽂件

2.5修改mybatis的配置⽂件,让该配置⽂件知道mapper⽂件的存在

2.6获得SqlSession,通过该对象进⾏数据的操作

3.Mybatis实现CRUD

4.省略实现类

5.ThreadLocal处理sqlSession

6.给类起别名

7.获得新增数据的id

8.log4j显示sql语句

9.Mybatis复杂查询

9.1 in 查询

9.2 模糊查询

9.3 区间查询

9.4 resultMap

10.pageHelper分页

11.缓存

12.Mybatis注解

12.1

12.2

12.3

12.4

12.5

12.6

12.7

12.8

12.9

13.lombok插件

14.Mybatis⾃动化

避坑指南


1.Mybatis介绍

JavaEE之SSM框架——Mybatis_第1张图片

MyBatis 本是apache的⼀个开源项⽬iBatis, 2010年这个项⽬由apache software foundation 迁移到了google code,并且改名为MyBatis 。2013年11⽉迁移到Github。

iBATIS⼀词来源于"internet"和"abatis"的组合,是⼀个基于Java的持久层框架。iBATIS提供的持久层框架包括SQL Maps和Data Access Objects(DAOs)

MyBatis 是⼀款优秀的持久层框架,它⽀持定制化 SQL、存储过程以及⾼级映射。MyBatis 避免了⼏乎所有的 JDBC 代码和⼿动设置参数以及获取结果集。MyBatis 可以使⽤简单的 XML 或注解来配置和映射原⽣信息,将接⼝和 Java 的 POJOs(Plain Ordinary Java Object,普通的 Java对象)映射成数据库中的记录。

2.搭建Mybatis

2.1.添加驱动包(mysql.jarmybatisjar)

 org.mybatismybatis3.4.6mysqlmysql-connector-java5.1.40

2.2.添加配置⽂件:src/mybatis-config.xml

连接数据库的配置⽂件的作⽤:

(1).指定连接数据库的url,username,password,driver

(2).由框架⾃动获取连接

(3).指定了事务的管理对象

配置⽂件中default要和id值相同,default表示默认访问环境,

但是也可以⾃⼰指定使⽤哪个id数据源,代码如下:

SqlSession session=
​
 new SqlSessionFactoryBuilder().build(r,"a2").openSession();

​

​

2.3.创建实体类和接⼝类

2.4添加mapper⽂件

注:在mapper⽂件中保存sql语句


​

​



    

2.5修改mybatis的配置⽂件,让该配置⽂件知道mapper⽂件的存在

2.6获得SqlSession,通过该对象进⾏数据的操作

//1.加载配置⽂件
​
 Reader r=Resources.getResourceAsReader("mybatis-config.xml");
​
 //2.创建SqlSessionFactoryBuilder对象
​
 SqlSessionFactoryBuilder builder= new SqlSessionFactoryBuilder();
​
 //3.得到session⼯⼚
​
 SqlSessionFactory factory=builder.build(r);
​
 //4.得到session
​
 SqlSession session= factory.openSession();
​
 //5.调取sql语句,insert("⽅法的完整路径"),路径=namespace+id
​
 int rs=session.insert("dao.EmpDao.insertEmp",e);
​
 session.commit();

 

3.Mybatis实现CRUD

mapper⽂件中参数的读取:

单个基本类型参数或 String 类型:

mapper读取参数:#{参数名(也可以是⾃定义名称)}

参数类型为对象类型时,读取参数的语法: #{对象中的属性名}

insert,delete,update,select中的parameterType参数可以省略

多个参数值的情况?

将参数封装到map集合中,再将map集合传递给mapper⽂件取值的时候,#{map的key值}

处理结果没有和实体类做对应的时候,可以返回map类型

 
​
 select * from emp where empno in 
​
  
​
 \#{a} 
​
 

注意:parameterType 的值可以省略

(2)参数是数组

 

注意:parameterType 的值可以省略

(3)参数Map

 

注意:parameterType 的值可以省略

传的值:

Map map=new HashMap();

map.put("keya", list1);

9.2 模糊查询

(1)模糊查+分页

如果传递的参数是多个时?------使⽤Map 集合

String sql;

StringBuffer sql;//动态sql的保存

(2)动态sql

模糊查询:

  
​
 and ename like '${属性名}' 
​
  

注意:test属性中读取属性值时直接写属性名

模糊查询读取属性时使el 表达式,${属性名}

除以上位置外,都使⽤#{属性名}

多个条件时使⽤and,or 拼接

如果传递过来的是map类型,则test属性中写的是key

#{}:相当于占位符

#{id}:其中的id可以表示输⼊参数的名称,如果是简单类型名称可以任意

${}:表示拼接sql语句

:表示获取输⼊的参数值​{}会引起SQL注⼊,⼀般情况下不推荐使⽤。

示例:

 
​
 and ename like '%${属性名}%' 
​
 
​
或者:
​
 and sname like "%"#{username}"%"
​
或者:
​
 sname like concat(concat('%',#{username}),'%')

9.3 区间查询

between 开始值 and 结束值

列名 >=开始时间 and 列名<=结束时间


​
 and regdate  #{stu.endTime}
​

9.4 resultMap

(1)处理单表关系

通过给列起别名,让别名=属性名,也可以实现数据对应

resultType="指定返回值的类型"//当列名和属性名⼀致时使⽤

resultMap="key 值" //1.当列名和属性名不⼀致 2.做多表查询时

mybatis 能实现的是单标的⾃动操作

(2)处理多表关系

两表联查:⼀对多和多对⼀

注:如果是单表查询,select 中使⽤resultType 设置返回的类型即可

但是如果是多表联查,那么select 查询的结果需要单独使⽤resultMap 标签来

进⾏结果的映射

存的是集合的话使⽤Collection ⼦标签

存的是⼀⽅的话使⽤association ⼦标签

resultType 和resultMap 属性只能出现⼀个

格式:

⼀对多:

  

多对⼀:

  

JavaType和ofType都是⽤来指定对象类型的,但是JavaType是⽤来指定pojo中属性的类型,⽽ofType指定的是映射到list集合属性中pojo的类型。

JavaEE之SSM框架——Mybatis_第3张图片

10.pageHelper分页

sql 语句只需要查询数据,不实现分页代码

⽅式1:

Mybatis使⽤RowBounds对象进⾏分页,它是针对ResultSet结果集执⾏的内存分页,⽽⾮物理分页。可以在sql内直接书写带有物理分页的参数来完成物理分页功能,也可以使⽤分页插件来完成物理分页。

优缺点

物理分页每次都要访问数据库,逻辑分⻚只访问⼀次

物理分页占⽤内存少,逻辑分⻚相对较多

物理分页数据每次都是最新的,逻辑分⻚有可能滞后

rowBounds实现分页:

SqlSession sqlSession = new SqlSessionFactoryBuilder()
​
 .build(Resources.getResourceAsReader("mybatis-config.xml"))
​
 .openSession();
​
List usersList =
​
 sqlSession.selectList("com.yhp.dao.UsersDao.findall",
​
 null, new RowBounds(0, 3));//rowBounds(开始位置,显示条数)
​
for (Users users : usersList) {
​
 System.out.println(users.getUsername());
​
}

sql语句:

  

⽅式2:使⽤分页插件

分页插件的基本原理是使⽤Mybatis提供的插件接⼝,实现⾃定义插件,在插件的拦截⽅法内拦截待执⾏的sql,然后重写sql,根据dialect⽅⾔,添加对应的物理分页语句和物理分页参数。

示例:

  

(a)导⼊jar 包

分页插件:pagehelper.jar

sql 解析⼯具:jsqlparser.jar

 com.github.pagehelperpagehelper5.1.6

(b) 在MyBatis 的总体⽂件中配置插件

放到之前

  

注意:插件5.1以后interceptor不同,并且不需要指定数据库名字

(c) 在执⾏查询之前设置

PageHelper.startPage(当前⻚,每⻚条数)

示例:

//分页查询(注意事项:设置分页的值⼀定要在查询之前)
​
 //1.在⼯具类中指定页码值和显示条数
​
 PageHelper.startPage(2,5);
​
 //2.调取查询的⽅法,得到结果集
​
 Student student1=new Student();
​
 //student1.setStuname("aa");
​
// student1.setAddress1("昌平");
​
 List list=dao.findall(student1);
​
 //3.将list集合封装到PageInfo对象中
​
 PageInfo pageInfo=new PageInfo(list);
​
 List list2= pageInfo.getList();
​
 //4.得到结果
​
 for (Student student :list2) {
​
 System.out.println(student.getStuname());
​
 }
​
 System.out.println("每页显示条数:"+pageInfo.getPageSize());
​
 System.out.println("当前页的条数:"+pageInfo.getSize());
​
 System.out.println("总条数:"+pageInfo.getTotal());
​
 System.out.println("总页数:"+pageInfo.getPages());
​
 System.out.println("上⼀页:"+pageInfo.getPrePage());
​
 System.out.println("下⼀页:"+pageInfo.getNextPage());
​
 System.out.println("当前页:"+pageInfo.getPageNum());

11.缓存

缓存:

⼀级缓存

SqlSession 的缓存 ------>⾃动开启

⼆级缓存:

做到从不同的缓存中共享数据

SqlSessionFactory 的缓存 --->需要⼿动开启

映射配置⽂件中配置

 

说明:

eviction: ⼆级缓存中,缓存的对象从缓存中移除的策略,回收策略为先进先出

flushInterval: 刷新缓存的事件间隔,单位:毫秒

size: 缓存对象的个数

readOnly: 是否是只读的

测试代码:

//不同qlSession,要同⼀个sqlSessionFactory
​
SqlSessionFactory factory= new SqlSessionFactoryBuilder()
​
 .build(Resources.getResourceAsReader("mybatis-config.xml"));
​
SqlSession sqlSession1=factory.openSession();
​
Student student = sqlSession1.selectOne("com.yhp.dao.StudentDao.findbystuid",
​
1);
​
System.out.println(student.getSname());
​
sqlSession1.close();
​
System.out.println("===================================");
​
SqlSession sqlSession2= factory.openSession();
​
student = sqlSession2.selectOne("com.yhp.dao.StudentDao.findbystuid", 1);
​
System.out.println(student.getSname());
​
sqlSession2.close();

cache元素⽤来开启当前mapper的namespace下的⼆级缓存,该元素的属性设置如下:

flushInterval:刷新间隔,可以被设置为任意的正整数,⽽且它们代表⼀个合理的毫秒形式的时间段,默认情况下是不设置的,也就是没有刷新间隔,缓存仅仅调⽤语句时刷新。

size:缓存数⽬,可以被设置为任意正整数,要记住你的缓存对象数⽬和你运⾏环境可⽤内存资源数⽬,默认值是1024.

readOnly:只读,属性可以被设置为true或false,只读的缓存会给所有调⽤者返回缓存对象的相同实例,因此这些对象不能被修改。这提供了很重要的性能优势,可读写的缓存会返回缓存对象的拷页(通过序列化),这会慢⼀些,但是安全,因此默认是false。

eviction:收回策略,默认为LRU,有如下⼏种:

LRU:最近最少使⽤的策略,移除最长时间不被使⽤的对象。

FIFO:先进先出策略,按对象进⼊缓存的顺序来移除它们。

SOFT:软引⽤策略,移除基于垃圾回收器状态和软引⽤规则的对象。

WEAK:弱引⽤策略,更积极地移除基于垃圾收集器状态和弱引⽤规则的对象。

注意:使⽤⼆级缓存时,与查询结果映射的java对象必须实现java.io.Serializable接⼝的序列化和反序列化操作,如果存在⽗类,其成员都需要实现序列化接⼝,实现序列化接⼝是为了对缓存数据进⾏序列化和反序列化操作,因为⼆级缓存数据存储介质多种多样,不⼀定在内存,有可能是硬盘或者远程服务器。

12.Mybatis注解

在mybatis中可以将sql语句通过注解的⽅式定义在java中,此时配置⽂件扫描该注解的位置即可,代码如下:

12.1

@Insert("insert into student(username,password,birthday) values(#
​
{user_name},#{password},#{birthday})")
​
 @Options(useGeneratedKeys = true,keyProperty = "userid")
​
 public int insertstu(Student student);

12.2

@Delete("delete from student where userid=#{userid}")
​
 public int deleteuser(int userid);

12.3

@Update("update student set username=#{user_name},sex=#{sex} where userid=#{userid}")
​
public int updateuser(Student stu);

12.4

@Select("select * from student")
​
 /* @Results({
​
 @Result(id = true, property = "id", column = "test_id")
​
 @Result(column = "username",property = "user_name")
​
 })*/

注意:多个@Result的时候两侧加⼤括号{}

12.5

@SelectProvider(type = ⾃定义sql所在的类.class, method = "sql定义的⽅法")

实例:@SelectProvider(type = SqlTemp.class,method ="getall44")

补充:

@InsertProvider(type = SqlTemp.class,method = "insert")

@DeleteProvider(type = SqlTemp.class,method = "delete")

@UpdateProvider(type = SqlTemp.class,method = "update")

public String insertstu(){
​
 return "insert into student(username,password,sex,birthday) values(#
​
{username},#{password},#{sex},#{birthday})";
​
 }
​
 public String gradestudent(Map map){
​
 StringBuffer sql=new StringBuffer("select * from student s,grade g
​
where s.gid=g.gradeid");
​
 if (map.get("uname")!=null){
​
 sql.append(" and username like '%"+map.get("uname")+"%'");
​
 }
​
 if(map.get("gname")!=null){
​
 sql.append(" and gradename like '%"+map.get("gname")+"%'");
​
 }
​
 return sql.toString();
​
 }

12.6

@ResultType(Student.class)
​
public List findall44();

12.7

@ResultMap("mapper⽂件中的id名即可")
​
public List findall33();

注意:(1)mapper⽂件中namespace的值要写当前接⼝的全路径

(2)配置⽂件中加载接⼝和mapper.xml⼆选⼀

实例代码:

接⼝:

@Select("select * from student s ,grade g where s.gid=g.cid")
​
@ResultMap("com.yhp.dao.StudentDao2.a1")
​
public List findstu_grade();

mapper⽂件: 这⾥namespace⼀定是接⼝的完整路径

配置⽂件:只需要扫描mapper⽂件,不需要扫描接⼝

12.8

绑定参数:

@Insert("insert into student(sname1,sex) values(#{sname},#{sex})")
​
@Options(useGeneratedKeys = true,keyProperty = "sid")
​
public int insertStu(@Param("sname") String name, @Param("sex")String usersex);

注意:在⾃定义sql的⽅法⽅法中只能使⽤#{}

12.9

@Options(useCache = true,
​
 flushCache = Options.FlushCachePolicy.FALSE, //表示查询时不刷新缓
​
 timeout = 10000) //表示查询结果缓存10000秒

注意:需要和@CacheNamespace⼀起使⽤,并且对象需要实现序列化接⼝

12.10

@CacheNamespace(size = 512) : 定义在该命名空间内允许使⽤内置缓存,最⼤值为512个对象引⽤,读写默认是开启的,

缓存内省刷新时间为默认3600000毫秒,⽤来修饰接⼝

12.11

动态sql:

@Select(" ")

注意:test后⾯的双引号需要反编译,这条语句必须放在中

13.lombok插件

在idea⼯具中添加lombok插件:

JavaEE之SSM框架——Mybatis_第4张图片

JavaEE之SSM框架——Mybatis_第5张图片

安装:

org.projectlomboklombok1.18.2provided

lombok的使⽤

@Data 注解在类上;提供类所有属性的 getting 和 setting ⽅法,此外还提供了equals、canEqual、hashCode、toString ⽅法

@Setter :注解在属性上;为属性提供 setting ⽅法

@Getter :注解在属性上;为属性提供 getting ⽅法

@Log4j :注解在类上;为类提供⼀个 属性名为log 的 log4j ⽇志对象

@NoArgsConstructor :注解在类上;为类提供⼀个⽆参的构造⽅法

@AllArgsConstructor :注解在类上;为类提供⼀个全参的构造⽅法

@Cleanup : 可以关闭流

@Builder : 被注解的类加个构造者模式

@Synchronized : 加个同步锁

@SneakyThrows : 等同于try/catch 捕获异常

@NonNull : 如果给参数加个这个注解 参数为null会抛出空指针异常

@Value : 注解和@Data类似,区别在于它会把所有成员变量默认定义为private final修饰,并且不会⽣成set⽅法。

@ToString 重写toString()⽅法

14.Mybatis⾃动化

作⽤:反向⽣成实体类,接⼝,mapper.xml

添加依赖包:

 org.mybatis.generatormybatis-generator-core1.3.5

加载插件:

org.mybatis.generatormybatis-generator-maven-plugin1.3.5
​
 
​
src/main/resources/generatorConfig.xmltrueorg.mybatis.generatormybatis-generator-core1.3.5

修改配置⽂件:


​

​

​
 
​
 
​ ​
​ ​

运⾏:maven Project选项卡->plugins->找到mybatis-generator-core,双击运⾏就会⾃动⽣成

注意:运⾏⼀次即可,如果运⾏过程中,未完全成功。则将原来⽣成的代码删除后,再次运⾏。

切记!切记!切记!

避坑指南

1.maven自动化逆向工程报SSL证书的错误。

JavaEE之SSM框架——Mybatis_第6张图片

原因:高版本数据库默认要使用SSL证书进行用户验证

解决办法:在maven自动化逆向工程的配置文件generatorConfig.xml中数据库连接设置中,在数据库地址后面加上useSSL=false参数。

 

你可能感兴趣的:(JavaEE之SSM)