Mybatis高效精华版总结,从零搭建,可直接上手

1.Mybatis介绍

MyBatis 是持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息,将接口和Java对象映射成数据库

2.搭建Mybatis

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

<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.6</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.40</version>
</dependency>

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

连接数据库的配置文件的作用:
(1).指定连接数据库的url,username,password,driver
(2).由框架自动获取连接
(3).指定了事务的管理对象
配置文件中default要和id值相同,default表示默认访问环境

<?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>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/dbName"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</dataSource>
</environment>
</environments>
<!-- 指定maper文件的路径(maven项目从resources源文件夹下找资源)-->
<mappers>
<mapper resource="包名/mapper文件名"/>
</mappers>
</configuration>

2.3创建实体类和接口类

2.4添加mapper文件

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

<mapper namespace="接口的完整路径">
<insert id="方法名" parameterType="参数类型">
//sql
</insert>
<select id="方法名" resultType="查询后的返回值类型">
//sql语句---注:sql语句没有分号
</select>
</mapper>

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 id="jisuan" resultType="map">

在做查询时,如果需要将查询的结果和实体类属性自动对应的话,要求:属性名=列名
添加:session.insert(“namespace+id”[,传递给sql的参数值]);
修改:session.update(“namespace+id”[,传递给sql的参数值]);
删除:session.delete(“namespace+id”[,传递给sql的参数值]);
单行:session.selectOne(“namespace+id”[,传递给sql的参数值]);
多行:session.selectList(“namespace+id”[,传递给sql的参数值]);
处理多个聚合函数:使用map作为方法的返回值,默认key是列名
注意:增删改的时候需要提交事务
session.commit();
session.rollback();
查询的时候要添加resultType属性

4.省略实现类

Reader r=Resources.getResourceAsReader("mybatis.xml");
SqlSession session = new SqlSessionFactoryBuilder().build(r).openSession();
//参数是接口的class类
StudentDao dao=session.getMapper(StudentDao.class);

5.ThreadLocal处理sqlSession

介绍:ThreadLocal是什么呢?是threadlocalvariable(线程局部变量)。功能非常简单,就是为每一个使用该变量的线程都提供一个变量值的副本,是Java中一种较为特殊的线程绑定机制,是每一个线程都可以独立地改变自己的副本,而不会和其它线程的副本冲突

5.1SessionUtil类:

public class mybatisUtil {
private static ThreadLocal<SqlSession> threadLcoal = new ThreadLocal<SqlSession>();
private static SqlSessionFactory SqlSessionFactory;
/**
*
* 加载配置文件
*/
static{
try{
Reader reader = Resources.getResourceAsReader("mybatis.cfg.xml");
SqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
}catch(IOException e){
e.printStackTrace();
throw new RuntimeException(e);
}
}
/**
*
* 获取SqlSession
* @return
*/
public static SqlSession getSqlSession(){
//从当前线程获取
SqlSession sqlSession = threadLcoal.get();
if(sqlSession == null){
sqlSession = SqlSessionFactory.openSession();
//将sqlSession与当前线程绑定
threadLcoal.set(sqlSession);
}
return sqlSession;
}
/**
* 关闭Session
*/
public static void closeSqlSession(){
//从当前线程获取
SqlSession sqlSession = threadLcoal.get();
if(sqlSession != null){
sqlSession.close();
threadLcoal.remove();
}
}
}

6.给类起别名typeAliases

<typeAliases>
<!--<typeAlias alias="u" type="com.yhp.bean.Users"></typeAlias>-->
<!--指定哪些包的类可以使用别名,默认别名:类名首字母小写(实际使用的时候,全部小写也可以做结果映射) -->
<package name="bean"></package>
</typeAliases>

7.获得新增数据的id

适用于可以自增的主键列上

<insert useGeneratedKeys="true" keyProperty="userid">

8.log4j显示sql语句

<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.5</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.12</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>

修改log4j.properties

log4j.rootLogger=DEBUG, Console
log4j.appender.Console=org.apache.log4j.ConsoleAppender
log4j.appender.Console.layout=org.apache.log4j.PatternLayout
log4j.appender.Console.layout.ConversionPattern=%d [%t] %-5p [%c] - %m%n
log4j.logger.java.sql.ResultSet=INFO
log4j.logger.org.apache=INFO
log4j.logger.java.sql.Connection=DEBUG
log4j.logger.java.sql.Statement=DEBUG
log4j.logger.java.sql.PreparedStatement=DEBUG

9.Mybatis复杂查询

9.1 in 查询

foreach标签中属性说明:
item 表示集合中每一个元素进行迭代时的别名,等同于c 标签中的var
index 指定一个名字,用于表示在迭代过程中,每次迭代到的位置,可以不写
open 表示该语句以什么开始,
separator 表示在每次进行迭代之间以什么符号作为分隔符,
close 表示以什么结束,

注意:在使用foreach 的时候最关键的也是最容易出错的就是collection 属性,
collection该属性是必须指定的list 时取值list,数组时取值array,map 时取值map 的key 值

(1)参数是list
<select id="findall" resultType="bean.Emp">
select * from emp where empno in
<foreach collection="list" index="b" item="a" open="("
separator="," close=")" >
#{a}
</foreach>
</select>

注意:parameterType 的值可以省略

(2)参数是数组
<select id="findall" resultType="bean.Emp">
select * from emp where empno in
<foreach collection="array" index="b" item="a" open="("
separator="," close=")" >
#{a}
</foreach>
</select>
(3)参数Map

传的值:
Map map=new HashMap();
map.put(“keya”, list1);

<select id="findall" resultType="bean.Emp">
select * from emp where empno in
<foreach collection="keya" index="b" item="a" open="(" separator="," close=")" >
#{a}
</foreach>
</select>

9.2 模糊查询

(1)模糊查+分页

如果传递的参数是多个时?------使用Map 集合
String sql;
StringBuffer sql;//动态sql的保存

(2)动态sql

模糊查询:

<if test="属性名!=属性值">
and ename like '${属性名}'
</if>

注意:test属性中读取属性值时直接写属性名
模糊查询读取属性时使el 表达式,${属性名}
除以上位置外,都使用#{属性名}
多个条件时使用and,or 拼接
如果传递过来的是map类型,则test属性中写的是key

<if test="ename!=null and ename!=''">
and ename like '%${属性名}%'
</if>
或者:
and sname like "%"#{username}"%"

9.3 区间查询

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

<if test="stu.endTime!=null and stu.endTime!=''">
and regdate <![CDATA[ <= ]]> #{stu.endTime}
</if>

9.4 resultMap

(1)处理单表关系

通过给列起别名,让别名=属性名,也可以实现数据对应
resultType=“指定返回值的类型”//当列名和属性名一致时使用
resultMap=“key 值” //1.当列名和属性名不一致 2.做多表查询时
mybatis 能实现的是单标的自动操作

<resultMap id="aaa" type="bean.Dept">
	<!-- 可以手动指定列名和属性名的关系 ,非主键列使用result 标签,主键
	列使用id 标签-->
	<id property="dept_no" column="deptno"></id>
	<result property="d_name" column="dname"/>
	<result property="d_loc" column="loc"/>
</resultMap>
(2)处理多表关系

两表联查:一对多和多对一
存的是集合的话使用Collection 子标签
存的是一方的话使用association 子标签

一对多
<resultMap type="" id="自定义名称">
	<id property="id" column="dept_id" /><!--主键列-->
	<result property="java 属性名" column="列名" />
	<collection property="属性名" ofType="java 类型">
	<id property="属性名" column="列名" />
	<result property="属性名" column="列名" />
	</collection>
</resultMap>
多对一
<resultMap type="" id="">
	<id property="" column="" />
	<result property="" column="" />
	<association property="" javaType="">
	<id property="" column="" />
	<result property="" column="" />
	</association>
</resultMap>

注意:JavaType和ofType都是用来指定对象类型的,但是JavaType是用来指定pojo中属性的类型,而ofType指定的是映射到list集合属性中pojo的类型。

10.pageHelper分页

(a)导入jar 包

<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>5.1.6</version>
</dependency>

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

<plugins>
<!-- PageHelper4.1.6 -->
<plugin interceptor="com.github.pagehelper.PageHelper">
<property name="dialect" value="mysql"/>
</plugin>
</plugins>

© 在执行查询之前设置
PageHelper.startPage(当前页,每页条数)

//分页查询(注意事项:设置分页的值一定要在查询之前)
//1.在工具类中指定页码值和显示条数
PageHelper.startPage(2,5);
//2.调取查询的方法,得到结果集
Student student1=new Student();
//student1.setStuname("aa");
// student1.setAddress1("昌平");
List<Student> list=dao.findall(student1);
//3.将list集合封装到PageInfo对象中
PageInfo pageInfo=new PageInfo(list);
List<Student> 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 的缓存 —>需要手动开启。
映射配置文件中配置

<mapper namespace="接口路径">
	<cache eviction="FIFO"
	flushInterval="60000"
	size="512"
	readOnly="true"/>
</mapper>

参数说明:
eviction: 二级缓存中,缓存的对象从缓存中移除的策略,回收策略为先进先出
flushInterval: 刷新缓存的事件间隔,单位:毫秒
size: 缓存对象的个数
readOnly: 是否是只读的

注意:使用二级缓存时,映射的java对象必须Serializable接口的序列化和反序列化操作,因为二级缓存数据存储介质多种多样,不一定在内存,有可能是硬盘或者远程服务器。

12.Mybatis注解

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

<mapper class="com.dao.StudentDao"></mapper>

12.1增加

@Insert("insert into student(username,password,birthday) values(#{user_name},#{password},#{birthday})")
@Options(useGeneratedKeys = true,keyProperty = "userid") //获取插入后的主键id
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 查询->property和column匹配映射

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

@SelectProvider(type = 自定义sql所在的类.class, method = “sql定义的方法”)

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

@ResultMap(“mapper文件中的id名即可”)
public List findall33()

12.5 Provider 自定义sql所在的类,美化Dao

@SelectProvider(type = 自定义sql所在的类.class, method = “sql定义的方法”)
@InsertProvider(type = SqlTemp.class,method = “insert”)
@DeleteProvider(type = SqlTemp.class,method = “delete”)
@UpdateProvider(type = SqlTemp.class,method = “update”)

12.6 返回类型注解ResultType

@ResultType(Student.class)
public List<Student> findall44();

12.7 两表联查,在mapper中配置ResultMap关系信息

  <resultMap id="rs3" type="com.zzuli.bean.Student">
        <id column="studentid" property="studentId"></id>
        <result column="stuname" property="stuName"></result>
        <result column="studentno" property="studentNo"></result>
        <result column="stuage" property="age"></result>
        <association property="grade" javaType="com.zzuli.bean.Grade">
            <id column="gid" property="gid"></id>
            <result column="gname" property="gname"></result>
        </association>
    </resultMap>
@ResultMap("com.zzuli.dao.StudentDao.r1")  //@ResultMap("mapper文件中的id名即可")
@Select("select * from student s,grade g where s.gradeid=g.gid")
public List<Student> getAllStudent();

注意:
(1)mapper文件中namespace的值要写当前接口的全路径
(2)配置文件中加载接口和mapper.xml二选一

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

@CacheNamespace(size = 512) : 定义在该命名空间内允许使用内置缓存,最大值为512个对象引用,读写默认是开启的,缓存内省刷新时间为默认3600000毫秒,用来修饰接口

12.11 动态sql 最好写在配置文件里

@Select(" <script>select * from student where 1=1 " +
" <if test=\"name!=null and name!=''\">" +
" and username like '%${name}%'" +
" </if>" +
" <if test=\"'pass!=null'\">" +
" and password like '%${pass}%'"+
" </if></script>")
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值