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介绍

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)

 <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表示默认访问环境,

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

SqlSession session=
​
 new SqlSessionFactoryBuilder().build(r,"a2").openSession();
<?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语句

<?xml version="1.0" encoding="UTF-8"?>
​
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
​
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
​
<!--namespace="接口的完整路径"-->
<mapper namespace="com.xzk.dao.StudentDao">
<!--    id="方法名"-->
    <select id="getAll" resultType="com.xzk.bean.Student">
        select * from student
    </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属性

调试接⼝和mapper.xml⽂件的插件:

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是什么呢?其实ThreadLocal并⾮是⼀个线程的本地实现版本,它并不是⼀个Thread,⽽是threadlocalvariable(线程局部变量)。也许把它命名为ThreadLocalVar更加合适。线程局部变量(ThreadLocal)其实的功⽤⾮常简单,就是为每⼀个使⽤该变量的线程都提供⼀个变量值的副本,是Java中⼀种较为特殊的线程绑定机制,是每⼀个线程都可以独⽴地改变⾃⼰的副本,⽽不会和其它线程的副本冲突。

示例:

class Test{
​
 private ThreadLocal<String> str = new ThreadLocal<String>();
​
 private List<String> list = new ArrayList<String>();
​
class A extends Thread {
​
 public void run() { 
​
 str.set("zhangsan");
​
System.out.println("A...." + str.get());
​
 list.add("xxx");
​
 System.out.println("A<<<"+list.get(0));
​
 }}
​
class B extends Thread {
​
 public void run() { 
​
 System.out.println("B...." + str.get());
​
 list.add("xxx");
​
 System.out.println("B<<<"+list.get(0));
​
}}}
​
测试代码:
​
 Test2 t=new Test2();
​
 Test2.A a=t.new A();
​
 Test2.B b=t.new B();
​
 a.start();
​
 b.start();

SessionUtil类:

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> 
​
 <!--
​
 <typeAlias alias="u" type="com.yhp.bean.Users"> 
​
 </typeAlias>--> 
​
<!--指定哪些包的类可以使⽤别名,默认别名:类名⾸字⺟⼩写(实际使⽤的时候,全部⼩写也可以做结果映射) --> 
​
 <package name="bean"></package> 
​
 </typeAliases> 

7.获得新增数据的id

适⽤于可以⾃增的主键列上

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

8.log4j显示sql语句

log4j ⽇志记录

步骤:添加jar包和log4j.properties⽂件

<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> 

注意:parameterType 的值可以省略

(3)参数Map

<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> 

注意:parameterType 的值可以省略

传的值:

Map map=new HashMap();

map.put("keya", list1);

9.2 模糊查询

(1)模糊查+分页

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

String sql;

StringBuffer sql;//动态sql的保存

(2)动态sql

模糊查询:

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

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

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

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

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

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

#{}:相当于占位符

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

${}:表示拼接sql语句

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

示例:

<if test="ename!=null and ename!=''"> 
​
 and ename like '%${属性名}%' 
​
 </if>
​
或者:
​
 and sname like "%"#{username}"%"
​
或者:
​
 sname like concat(concat('%',#{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)处理多表关系

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

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

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

进⾏结果的映射

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

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

resultType 和resultMap 属性只能出现⼀个

格式:

⼀对多:

 <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分页

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

⽅式1:

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

优缺点

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

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

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

rowBounds实现分页:

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

sql语句:

 <select id="findall" resultType="com.yhp.bean.Users">
​
 select * from users
​
</select> 

⽅式2:使⽤分页插件

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

示例:

 <select id="findall" resultType="bean.Emp"> 
​
 select * from emp 
​
 </select> 

(a)导⼊jar 包

分页插件:pagehelper.jar

sql 解析⼯具:jsqlparser.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> 

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

<plugins>
​
 <plugin interceptor="com.github.pagehelper.PageInterceptor">
​
 </plugin>
​
</plugins>

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

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: 是否是只读的

测试代码:

//不同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中,此时配置⽂件扫描该注解的位置即可,代码如下:

<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")
​
 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<Student> findall44();

12.7

@ResultMap("mapper⽂件中的id名即可")
​
public List<Student> 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<Student> findstu_grade();

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

<mapper namespace="com.yhp.dao.StudentDao2">
​
 <resultMap id="a1" type="student">
​
 <id property="sid" column="sid"></id>
​
 <result property="sname" column="sname"></result>
​
 <association property="grade" javaType="grade">
​
 <id property="cid" column="cid"></id>
​
 <result property="cname" column="cname"></result>
​
 </association>
​
 </resultMap>
​
</mapper>

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

<mappers>
​
 <mapper resource="resultMapper.xml"></mapper>
​
</mappers>

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(" <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>")

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

13.lombok插件

在idea⼯具中添加lombok插件:

安装:

<dependency>
​
 <groupId>org.projectlombok</groupId>
​
 <artifactId>lombok</artifactId>
​
 <version>1.18.2</version>
​
 <scope>provided</scope>
​
 </dependency>

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

添加依赖包:

 <dependency>
​
 <groupId>org.mybatis.generator</groupId>
​
 <artifactId>mybatis-generator-core</artifactId>
​
 <version>1.3.5</version>
​
 </dependency>

加载插件:

<build>
​
 <plugins>
​
 <plugin>
​
 <groupId>org.mybatis.generator</groupId>
​
 <artifactId>mybatis-generator-maven-plugin</artifactId>
​
 <version>1.3.5</version>
​
 <configuration>
​
 <!--配置⽂件的路径-->
​
 
​
<configurationFile>src/main/resources/generatorConfig.xml</configurationFile>
​
 <overwrite>true</overwrite>
​
 </configuration>
​
 <dependencies>
​
 <dependency>
​
 <groupId>org.mybatis.generator</groupId>
​
 <artifactId>mybatis-generator-core</artifactId>
​
 <version>1.3.5</version>
​
 </dependency>
​
 </dependencies>
​
 </plugin>
​
 </plugins>
​
 </build>

修改配置⽂件:

<?xml version="1.0" encoding="UTF-8"?>
​
<!DOCTYPE generatorConfiguration
​
 PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
​
 "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
​
<!-- 配置⽣成器 -->
​
<generatorConfiguration>
​
 <!--数据库驱动jar -->
​
 <classPathEntry
​
 location="F:\yhp\jar\mysql驱动\mysql-connector-java-5.0.8-bin.jar"
​
/>
​
 <context id="MyBatis" targetRuntime="MyBatis3">
​
 <!--去除注释 -->
​
 <commentGenerator>
​
 <property name="suppressAllComments" value="true" />
​
 </commentGenerator>
​
 <!--数据库连接 -->
​
 <jdbcConnection driverClass="com.mysql.jdbc.Driver"
​
 connectionURL="jdbc:mysql://localhost:3306/water?useUnicode=true&amp;characterEncoding=utf-8&amp;useSSL=true"
​
 userId="root"
​
 password="">
​
 </jdbcConnection>
​
 <!--⽣成实体类 指定包名 以及⽣成的地址 (可以⾃定义地址,但是路径不存在不会⾃动创建
​
 使⽤Maven⽣成在target⽬录下,会⾃动创建) -->
​
 <javaModelGenerator targetPackage="com.yhp.bean"
​
 
​
targetProject="F:\yhp\three\workspace\mybatis_001\src\main\java">
​
 <property name="trimStrings" value="true" />
​
 </javaModelGenerator>
​
 <!--⽣成SQLmapper⽂件 -->
​
 <sqlMapGenerator targetPackage="mapper"
​
 
​
targetProject="F:\yhp\three\workspace\mybatis_001\src\main\resources">
​
 </sqlMapGenerator>
​
 <!--⽣成Dao⽂件,⽣成接⼝ -->
​
 <javaClientGenerator type="XMLMAPPER"
​
 targetPackage="com.yhp.dao" 
​
 targetProject="F:\yhp\three\workspace\mybatis_001\src\main\java">
​
 </javaClientGenerator>
​
 <table tableName="student" enableCountByExample="false"
​
 enableUpdateByExample="false" enableDeleteByExample="false"
​
 enableSelectByExample="false" selectByExampleQueryId="false">
​
 </table>
​
 <table tableName="grade" enableCountByExample="false"
​
 enableUpdateByExample="false" enableDeleteByExample="false"
​
enableSelectByExample="false" selectByExampleQueryId="false">
​
 </table>
​
 <table tableName="subject" enableCountByExample="false"
​
 enableUpdateByExample="false" enableDeleteByExample="false"
​
 enableSelectByExample="false" selectByExampleQueryId="false">
​
 </table>
​
 </context>
​
</generatorConfiguration>

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

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

切记!切记!切记!

避坑指南

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

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

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

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值