Mybatis学习小结

1.什么是框架

Framework;
	一个框架包含多个可重用的组件;
	使用框架的最大好处就是可以提高开发效率;
框架本质就是一个软件的半成品;	
举例说明?
1.包饺子吃?
	饺子皮就是一个框架;
2.披萨
	

2.初识Mybatis

1.mybatis是一个应用最广泛的持久层框架
2.它是一个半自动化的框架(Hiberante),Mybatis主要写的就是SQL语句
3.它的前身是ibatis

3.开发步骤

1.导包(mybatis,mysql-connector)
2.定义实体类 (pojo)
3.定义核心配置文件 (相当于db.properites)  Configuration.xml
4.定义DAO接口,定义SQL映射(Mapper.xml)

4.开发详细步骤

  1. 导包

        <dependencies>
            <dependency>
                <groupId>org.mybatis</groupId>
                <artifactId>mybatis</artifactId>
                <version>3.5.10</version>
            </dependency>
    
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>5.1.49</version>
            </dependency>
    
    
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>4.10</version>
                <scope>test</scope>
            </dependency>
    
        </dependencies>
    
  2. 定义实体类(略)

    public class Book {
    
        private Integer bookNo;
        private String name;
        private String author;
        private Integer price;
        
        //getter and setter方法略
    }
    
  3. 定义核心配置文件(主要配置数据库连接的参及SQL映射文件的位置)

    此配置文件可在IDEA中使用模版自定义

    <?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/book"/>
                    <property name="username" value="root"/>
                    <property name="password" value="tiger"/>
                </dataSource>
            </environment>
        </environments>
        <mappers>
            <mapper resource="com/bao/BookMapper.xml"/>
        </mappers>
    </configuration>
    
  4. 定义DAO接口

    package com.bao.dao;
    
    import com.bao.entity.Book;
    
    import java.util.List;
    
    public interface BookDao {
        public List<Book> selectAll();
    
        public void insert(Book book);
    }
    
  5. 定义BookMapper映射文件,此映射文件与DAO接口对应;

    <?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">
    <mapper namespace="com.huayu.dao.BookDao">
    
        <select id="selectAll" resultType="com.bao.entity.Book">
            select * from tb_book
        </select>
    
    
        <insert id="insert" parameterType="com.bao.entity.Book">
            insert into tb_book values(null,#{name},#{author},#{price})
        </insert>
    
    </mapper>
    
  6. 使用Mybatis的API来进行操作

    public class TestBook {
    
    	//session工厂
        SqlSessionFactory sqlSessionFactory=null;
    
        @Before
        public void init(){
            //1.定义核心配置文件
            String resource = "Configuration.xml";
            InputStream inputStream = null;
            try {
                inputStream = Resources.getResourceAsStream(resource);
            } catch (IOException e) {
                e.printStackTrace();
            }
            //2.创建Session工厂
           sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        }
        
        
        @Test
        public void testSelect(){
            //3.获得session(会话),程序与Mybatis
            SqlSession session=sqlSessionFactory.openSession();
            //4.获得dao对象
            BookDao dao=session.getMapper(BookDao.class);
            List<Book> list=dao.selectAll();
    
            for(Book b:list){
                System.out.println(b);
            }
            session.close();
        }
    
    
        @Test
        public void insertTest(){
            SqlSession session=sqlSessionFactory.openSession();
            BookDao dao=session.getMapper(BookDao.class);
    
            Book b=new Book();
            b.setAuthor("刘润");
            b.setName("逻辑思维");
            b.setPrice(56);
            dao.insert(b);
            session.commit();
            session.close();
        }
    }
    

5.Mybatis的工作原理

6.映射器的方式

创建映射器有两种方式;
1.DAO接口+xml;
2.DAO接口+annotation

Dao+Annotation

  1. 定义Dao接口和Annoation

    @Select("select * from tb_book")
    public List<Book> selectAll();
    
    @Insert("insert into tb_book values(null,#{name},#{author},#{price})")
    public void insert(Book book);
    
  2. 在核心配置文件中加载映射

    <mappers>
         <package name="com.bao.dao"/>
    </mappers>
    

7.核心配置文件

在Mybatis中,通过核心配置文件,可以配置Mybatis中最常用的配置,哪数据源,别名,参数设置,加载映射文件等,主要的元素有,

configuration(配置)
	properties(属性)
	settings(设置)
	typeAliases(类型别名)
	typeHandlers(类型处理器)
	objectFactory(对象工厂)
	plugins(插件)
	environments(环境配置)
		environment(环境变量)
			transactionManager(事务管理器)
			dataSource(数据源)
	databaseIdProvider(数据库厂商标识)
	mappers(映射器)

1.settings

      <!-- https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-core -->
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-core</artifactId>
            <version>2.18.0</version>
        </dependency>
    <settings>
        <!--标准的日志实现-->
        <setting name="logImpl" value="LOG4J2"/>
    </settings>
<!--log4j2.xml-->

<?xml version="1.0" encoding="UTF-8"?>
<configuration status="DEBUG">
    <appenders>
        <Console name="Console" target="SYSTEM_OUT">
            <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
        </Console>
    </appenders>
    <loggers>
        <logger name="log4j.logger.noModule" level="fatal" additivity="false">
            <appender-ref ref="Console"/>
        </logger>
        <logger name="log4j.logger.org.mybatis.jpetstore" level="trace" additivity="false">
            <appender-ref ref="Console"/>
        </logger>
        <logger name="log4j.logger.com.opensymphony.xwork2" level="debug" additivity="false">
            <appender-ref ref="Console"/>
        </logger>
        <logger name="log4j.logger.com.ibatis" level="trace" additivity="false">
            <appender-ref ref="Console"/>
        </logger>
        <logger name="log4j.logger.com.ibatis.common.jdbc.SimpleDataSource" level="debug" additivity="false">
            <appender-ref ref="Console"/>
        </logger>
        <logger name="log4j.logger.com.ibatis.common.jdbc.ScriptRunner" level="debug" additivity="false">
            <appender-ref ref="Console"/>
        </logger>
        <logger name="log4j.logger.com.ibatis.sqlmap.engine.impl.SqlMapClientDelegate" level="debug" additivity="false">
            <appender-ref ref="Console"/>
        </logger>
        <logger name="log4j.logger.org.mybatis" level="debug" additivity="false">
            <appender-ref ref="Console"/>
        </logger>
        <logger name="log4j.logger.java.sql" level="debug" additivity="false">
            <appender-ref ref="Console"/>
        </logger>
        <logger name="log4j.logger.java.sql.Connection" level="debug" additivity="false">
            <appender-ref ref="Console"/>
        </logger>
        <logger name="log4j.logger.java.sql.Statement" level="debug" additivity="false">
            <appender-ref ref="Console"/>
        </logger>
        <logger name="log4j.logger.java.sql.PreparedStatement" level="debug" additivity="false">
            <appender-ref ref="Console"/>
        </logger>
        <logger name="log4j.logger.java.sql.ResultSet" level="debug" additivity="false">
            <appender-ref ref="Console"/>
        </logger>
        <root level="trace">
            <appender-ref ref="Console"/>
        </root>
    </loggers>
</configuration>


2设置别名

    <typeAliases>
<!--        <typeAlias type="com.huayu.entity.Book" alias="book"/>-->    
        <package name="com.huayu.entity"/>
    </typeAliases>

3.数据源

<environments default="produce">

        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="${driver}"/>
                <property name="url" value="jdbc:mysql://localhost:3306/book"/>
                <property name="username" value="${username}"/>
                <property name="password" value="${password}"/>
            </dataSource>
        </environment>


        <environment id="produce">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="${driver}"/>
                <property name="url" value="jdbc:mysql://localhost:3308/books"/>
                <property name="username" value="${username}"/>
                <property name="password" value="${password}"/>
            </dataSource>
        </environment>
    </environments>

4映射器

    <mappers>
<!--        <package name="com.huayu.dao"/>-->
        <mapper resource="com/bao/BookMapper.xml"/>
    </mappers>

注意:如果使用的是mapper方式,需要在resources中创建两个文件夹,com/bao,不能直接创建com.bao

8.XML映射文件 (SQL映射)

主要标记

insert – 映射插入语句。
update – 映射更新语句。
delete – 映射删除语句。
select – 映射查询语句。

sql – 可被其它语句引用的可重用语句块。
cache – 该命名空间的缓存配置。
cache-ref – 引用其它命名空间的缓存配置。
resultMap – 描述如何从数据库结果集中加载对象,是最复杂也是最强大的元素。

1示例

定义一个方法,用来获得某个作者的图书的数量,最高的价格,及总价格;
map->三个key;

    <select id="selectInfoByAuthor" resultType="map">
        select count(*) count,max(price) max,sum(price) sum from tb_book where
        author=#{author}
    </select>
    
      //通过一个方法返回图书

    public Map<String,Long> selectInfoByAuthor(String author);
#如果一个方法有两个参数应该好何处理呢?

select * from tb_book where name=? and price>?

1.使用pojo;
2.使用map
3.传递多个参数;使用@Param注解为参数命名
 
public List<Book> selectByCondition(@Param("name") String name, @Param("price") Integer price);
   <select id="selectByCondition" resultType="book">
        select * from tb_book where
        author=#{name} and price>#{price}
    </select>

2标记的属性小结

id:标记的唯一标识,不能重复,映射的是DAO中的方法名
parameterType:参数类型,可以省略
resultType:返回值的类型  vo,map,基本类型均可
resultMap:自定义的结构映射;
statementType:执行SQL语句的底层Statement类型,有三种:Statement,PreparedStatment,CallableStatment

OGNL表达式;

3.关于insert中生成主键的处理

<!--利用数据库的自增长功能   useGeneratedKeys代表是否使用数据库生成的主键,keyProperty:表示将生成的主键赋给哪个属性-->
    <insert id="insert" parameterType="order" useGeneratedKeys="true" keyProperty="orderId">
        insert into biz_order values(null,#{orderCode},#{orderDate},#{orderFlag})
    </insert>

#如果数据库不支持自增长怎么办?

    <insert id="insert" parameterType="order">
        <selectKey keyProperty="orderId" order="BEFORE" resultType="int">
            select max(orderId)+10 from biz_order
        </selectKey>
        insert into biz_order values(#{orderId},#{orderCode},#{orderDate},#{orderFlag})
    </insert>

4.update与delete

    <update id="update" parameterType="order">
        update biz_order set orderFlag=#{orderFlag} where orderId=#{orderId}
    </update>


    <delete id="delete" parameterType="int">
        delete from biz_order where orderId=#{orderId}
    </delete>

5.sql

sql标记可以定义一段可重复使用的SQL片段,然后通过include标记进行引用

    <sql id="column">
        orderid,ordercode,orderDate,orderflag
    </sql>

    <select id="selectAll" resultType="order">
    select <include refid="column"></include>  from biz_order
</select>

6字符串的拼接

#{}:语法是使用点位符进行参数的替换
${}:就是完成字符串的拼接

通过${}可以解决按字段排序的问题;
同样${}会产生SQL注入的问题;


 <select id="selectOrder" resultType="order">
        select * from biz_order order by ${name}
  </select>

9高级映射 ResultMap

为什么要用ResultMap
1.当字段与Pojo的属性不一致时,可以使用ResultMap自定义映射规则
2.当需要完成复杂映射时,例如(1对1,1对多)时,必须使用ResultMap;
<resultMap id="映射的唯一标识" type="java的Pojo类">

	constructor,id,result子标记都是设置字段与属性的映射规则
	association:一对一
	collections:一对多

示例

1.定义两个表,sys_emp,sys_dept;一个部门对应多个员工
2.定义两个实体类;
		Emp
			id
			name
			sex
			Dept dept
			hiredate
			
			association
		Dept
			deptno
			dname
			List<Emp> emps;
			collection

1.多对一的映射

    <!--自定义映射规则-->
    <resultMap id="empResultMap" type="com.bao.entity.Emp" >
        <id property="id" column="id"></id>
        <result property="sex" column="sex"></result>
        <result property="name" column="name"></result>
        <result property="hiredate" column="hiredate"></result>
        
        <association property="dept" javaType="com.bao.entity.Dept"  >
            <id column="deptno" property="deptno"></id>
            <result column="dname" property="dname"/>
        </association>
    </resultMap>

    <select id="select" resultMap="empResultMap" >
       select id,name,sex,hiredate,sys_dept.deptno deptno,dname  from sys_emp,sys_dept
       where sys_emp.deptno=sys_dept.deptno
    </select>

2.自动映射

注意:如果字段与属性名完全相同,则可以使用自动映射

    <!--自定义映射规则-->
    <resultMap id="empResultMap" type="com.bao.entity.Emp"  autoMapping="true">
        <association property="dept" javaType="com.bao.entity.Dept"  autoMapping="true">
        </association>
    </resultMap>

3.查询语句映射

多对一关联时,如果想查到关联的数据,可能通过两种方法
1.表连接(查询一次)
2.先查员工,再根据员工ID查询所对应的部门(n+1)
    <!--自定义映射规则-->
    <resultMap id="empResultMap" type="com.bao.entity.Emp"  autoMapping="true">

        <association property="dept" javaType="com.bao.entity.Dept" column="deptno" select="getDeptByNo">
        </association>
    </resultMap>


    <select id="getDeptByNo" resultType="dept">
        select * from sys_dept where deptno=#{deptno}
    </select>

4.一对多的映射

<!--通过Collections标记;(元素)
	注意:id是判断是否重复的标准;
-->
    <resultMap id="myDeptMapper" type="com.bao.entity.Dept" >
        <id column="deptno" property="deptno"/>
        <result column="dname" property="dname"/>

        <collection property="emps" ofType="com.bao.entity.Emp" resultMap="myEmp">

        </collection>
    </resultMap>
    ·········································································································
       <select id="select" resultMap="myDeptMapper">
        select id,name,sex,hiredate,d.deptno deptno,dname
        from sys_dept d left join sys_emp e on d.deptno=e.deptno
        order by deptno
    </select>

   <!--n+1的方式-->
   <resultMap id="myDeptMapper" type="com.bao.entity.Dept" >
        <id column="deptno" property="deptno"/>
        <result column="dname" property="dname"/>

        <collection property="emps" ofType="com.bao.entity.Emp" column="deptno" select="selectEmpsByDeptno">

        </collection>
    </resultMap>

    <resultMap id="myEmp" type="com.bao.entity.Emp" autoMapping="true">

    </resultMap>


    <select id="selectEmpsByDeptno" resultType="emp">
        select * from sys_emp where deptno=#{deptno}
    </select>

5.在Mapper中引用另一个Mapper中的resultMap或方法

1.通过全路径+方法名(或resultMap的id)例如
	select="com.bao.dao.DeptMapper.getDeptByNo">
2.有个前提要求
	接口名与Sql映射文件的文件名及路径完全相同。

6.鉴别器

	商品
		id;
		名称
		品牌
		价格
		类型:1,2,3
		
	鞋:
		号码
	丝巾:
		颜色
		材质
	帽子:
		颜色
		尺寸

10. 动态SQL语句

动态SQL是Mybatis是强大的功能之一。它通过一些标记来实现动态SQL,常用的标记有 if choose where foreach set等;

if标记

语法 
<if test="">
	语句
</if>
如果条件成立,就生成语句,否则无此内容;
  <if test="deptNo != null">
         and deptno=#{deptNo}
  </if>

where标记

where:如果where标记中没有内容,则去除where,否成生成where,并且去除where中第一个and或or;

      <where>
            <if test="name !=null">
                or name=#{name}
             </if>
            <if test="sex != null">
                and sex=#{sex}
            </if>
            <if test="deptNo != null">
                and deptno=#{deptNo}
            </if>
        </where>

choose 多分支


[收入] 【= >】[1000]

<choose>
	<when test="operation =='eq'">
			sal = #{sal}
	</when>
	<otherwise>
		sal > #{sal}
	</otherwise>

</choose>

            <if test="deptNo != null">
                <choose>
                    <when test="operation =='eq'">
                        and deptno=#{deptNo}
                    </when>
                    <otherwise>
                        and deptno>#{deptNo}
                    </otherwise>
                </choose>
            </if>

Trim :自定义增加或去除的前缀及后缀

<trim prefix="where" prefixOverrides="and|or">
            <if test="name !=null">
                or name=#{name}
             </if>
            <if test="sex != null">
                and sex=#{sex}
            </if>
            <if test="deptNo != null">
                <choose>
                    <when test="operation =='eq'">
                        and deptno=#{deptNo} 
                    </when>
                    <otherwise>
                        and deptno>#{deptNo} 
                    </otherwise>
                </choose>
            </if>

        </trim>

set

    <update id="update">
        update sys_emp
        <set>
            <if test="name!=null">
                name=#{name},
            </if>
            <if test="sex!=null">
                sex=#{sex},
            </if>
            <if test="deptNo!=null">
                deptno=#{deptNo}
            </if>
        </set>
        where id=#{id}
    </update>

foreach

遍历

    <select id="selectIn" resultType="emp">     
        select * from sys_emp
        <where>

            <foreach collection="array" item="id" open="id in (" close=")" separator=",">
                #{id}
            </foreach>
        </where>
    </select>

关于参数的传递

mybatis内部使用的是Ognl表达式,这个表达式与EL的很相似;
	对象图导航语言;Object Graph Navigation Language

本质是将数据存到map结构中,然后再通过OGNL表达式来获取;
(@Param("name") String userName)  ===>  map.put("name",userName)
(int[] ids)                       ===>  map.put("array",ids)
(@Param("param") int[] ids)       ====>  map.put("param",ids)

#{name}   #{array}

Bind

bind 元素允许你在 OGNL 表达式以外创建一个变量,并将其绑定到当前的上下文。比如:

<select id="selectBlogsLike" resultType="Blog">
  <bind name="pattern" value="'%' + _parameter.getTitle() + '%'" />
  SELECT * FROM BLOG
  WHERE title LIKE #{pattern}
</select>

11.延迟加载

延迟加载也叫按需加载;在很多的技术点中都有延迟加载;
	单例;
	servlet:

mybatis的延迟加载指的是:先查询主信息,从信息在需要时才加载;

mybatis的延迟加载在哪里可以使用:association,collection

	Dept->List<Emp> emps
		get.getEmps();
		
		getDname();

可以通过两种方式配置是否加载加载 
1.在Configuration.xml中
	<setting name="lazyLoadingEnabled" value="true"/>
2.在SQL映射文件中,使用fetchType="lazy"来设置
	<association property="dept" javaType="com.huayu.entity.Dept" fetchType="eager" column="deptno" select="com.huayu.dao.DeptMapper.getDeptByNo">

如果同时通过两种方式设置,那么SQL映射的fetchTpye的优先级更高;

12.缓存

Mybatis的缓存分为两种,一级缓存和二级缓存;
一级缓存:Session级别的,默认是打开的;
二级缓存:SessionFactory级别,可以设置;

为什么要使用缓存;
	减少对数据的访问次数(查询);从而提高性能;
	

一级缓存

一级缓存是Session级别的,不需要配置;
当执行insert,update,delete时,将会清空缓存;

 EmpDao dao=session.getMapper(EmpDao.class);
 System.out.println(dao.selectEmpById(1));
 System.out.println(dao.selectEmpById(1));

二级缓存

二级缓存是SqlSessionFactory级别的,只有一个,被所有的session共享,可以手动配置

操作步骤

  1. 打开二级缓存 的开关

     <setting name="cacheEnabled" value="true"/>
    
  2. 在Mapper文件中加入cache标记

    <cache></cache>
    
     <cache
                eviction="LRU"
                flushInterval="60000"
                size="512"
                readOnly="false"/>
    
    size:最多缓存多少条查询
    flushIntervale:多久刷新一次;
    evication:驱逐策略,FIFO,LRU
    readOnly(只读:属性可以被设置为 true 或 false。只读的缓存会给所有调用者返回缓存对象的相同实例。 因此这些对象不能被修改。这就提供了可观的性能提升。而可读写的缓存会(通过序列化)返回缓存对象的拷贝。 速度上会慢一些,但是更安全,因此默认值是 false。
    	
    selectId(1);   张三 ,18;   Emp(1,张三,19)
    
  3. 实现序列化接口

  4. 示例

        @Test
        public void testCache() throws InterruptedException {
            EmpDao dao=session.getMapper(EmpDao.class);
            System.out.println(dao.selectEmpById(1));
            session.commit();
            System.out.println(dao.selectEmpById(2));
            session.commit();
            System.out.println(dao.selectEmpById(1));
            session.commit();
            System.out.println(dao.selectEmpById(3));
    //        Emp e=new Emp();
    //        e.setId(2);
    //        e.setName("张三丰");
    //        dao.update(e);
              session.close();
    
    
            //创建第二个session
            SqlSession session1=sqlSessionFactory.openSession();
            EmpDao dao1=session1.getMapper(EmpDao.class);
    //        for(int i=0;i<100;i++){
                dao1.selectEmpById(1);
            }
    
            System.out.println("==============================");
            System.out.println(dao1.selectEmpById(1));
            System.out.println(dao1.selectEmpById(2));
            System.out.println(dao1.selectEmpById(3));
        }
    

13.逆向工程

逆向工程的作用;生成mybatis代码?

能生成什么?
	1.实体类
	2.Mapper接口
	3.Mapper映射文件
逆向工程的步骤
1.导包 mybatis-generator-core
2.增加 mybatis-generator插件
3.定义数据源(根据表生成代码)
4.创建generatorConfig配置文件,此配置文件定义了生成代码的规则
5.运行maven mybatisgenerator插件

1.导包及增加插件(pom.xml)

    <dependencies>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.49</version>
        </dependency>

        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.11</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.10</version>
        </dependency>

        <dependency>
            <groupId>org.mybatis.generator</groupId>
            <artifactId>mybatis-generator-core</artifactId>
            <version>1.4.1</version>
        </dependency>
    </dependencies>

    <build>
        <finalName>zsxt</finalName>
        <!--执行逆向工程代码的插件-->
        <plugins>
            <plugin>
                <groupId>org.mybatis.generator</groupId>
                <artifactId>mybatis-generator-maven-plugin</artifactId>
                <version>1.4.1</version>
                <configuration>
                    <verbose>true</verbose>
                    <overwrite>true</overwrite>
                </configuration>
            </plugin>
        </plugins>
    </build>

2.定义数据源,generator.properties

jdbc.driverLocation=D:....(自己文件位置).../mysql-connector-java-5.1.49.jar
jdbc.driverClass=com.mysql.jdbc.Driver
jdbc.connectionURL=jdbc:mysql://localhost:3306/cmp?useSSL=false
jdbc.userId=root
jdbc.password=tiger

3.定义generatorConfig配置文件

<?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>
    <!--导入属性配置-->
    <properties resource="generator.properties"></properties>

    <!--指定特定数据库的jdbc驱动jar包的位置-->
    <classPathEntry location="${jdbc.driverLocation}"/>

    <context id="default" targetRuntime="MyBatis3">

        <!-- optional,旨在创建class时,对注释进行控制 -->
        <commentGenerator>
            <property name="suppressDate" value="true"/>
            <property name="suppressAllComments" value="true"/>
        </commentGenerator>

        <!--jdbc的数据库连接 -->
        <jdbcConnection
                driverClass="${jdbc.driverClass}"
                connectionURL="${jdbc.connectionURL}"
                userId="${jdbc.userId}"
                password="${jdbc.password}">
            <!--MySQL 不支持 schema 或者 catalog 所以需要添加这个-->
            <!-- 不然会出现生成器把其他数据库的同名表生成下来的问题 -->
            <!-- 现象就是某个类中出现了数据库表里面没有的字段 -->
            <property name="nullCatalogMeansCurrent" value="true"/>
        </jdbcConnection>


        <!-- 非必需,类型处理器,在数据库类型和java类型之间的转换控制-->
        <javaTypeResolver>
            <property name="forceBigDecimals" value="false"/>
        </javaTypeResolver>


        <!-- Model模型生成器,用来生成含有主键key的类,记录类 以及查询Example类
            targetPackage     指定生成的model生成所在的包名
            targetProject     指定在该项目下所在的路径
        -->
        <javaModelGenerator targetPackage="com.huayu.entity"
                            targetProject="src/main/java">

            <!-- 是否允许子包,即targetPackage.schemaName.tableName -->
            <property name="enableSubPackages" value="false"/>
            <!-- 是否对model添加 构造函数 -->
            <property name="constructorBased" value="true"/>
            <!-- 是否对类CHAR类型的列的数据进行trim操作 -->
            <property name="trimStrings" value="true"/>
            <!-- 建立的Model对象是否 不可改变  即生成的Model对象不会有 setter方法,只有构造方法 -->
            <property name="immutable" value="false"/>

        </javaModelGenerator>

        <!--Mapper映射文件生成所在的目录 为每一个数据库的表生成对应的SqlMap文件 -->
        <sqlMapGenerator targetPackage="com.huayu.mapper"
                         targetProject="src/main/resources">
            <property name="enableSubPackages" value="false"/>
        </sqlMapGenerator>

        <!-- 客户端代码,生成易于使用的针对Model对象和XML配置文件 的代码
                type="ANNOTATEDMAPPER",生成Java Model 和基于注解的Mapper对象
                type="MIXEDMAPPER",生成基于注解的Java Model 和相应的Mapper对象
                type="XMLMAPPER",生成SQLMap XML文件和独立的Mapper接口
        -->
        <javaClientGenerator targetPackage="com.huayu.mapper"
                             targetProject="src/main/java" type="XMLMAPPER">
            <property name="enableSubPackages" value="true"/>
        </javaClientGenerator>

        <!--要执行逆向工程所用到的表-->
        <table tableName="sys_dept" domainObjectName="Dept">
        <property name="useActualColumnNames" value="false"/>
    </table>
        <table tableName="sys_emp" domainObjectName="Emp">
            <property name="useActualColumnNames" value="false"/>
        </table>

        <!--        <table tableName="category" />-->
    </context>
</generatorConfiguration>

4.执行插件

5.测试

import com.huayu.entity.Emp;
import com.huayu.entity.EmpExample;
import com.huayu.mapper.DeptMapper;
import com.huayu.mapper.EmpMapper;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Before;
import org.junit.Test;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;

public class TestGenerator {


    SqlSessionFactory sqlSessionFactory=null;
    SqlSession session=null;

    @Before
    public void init() throws IOException {
        String resource = "Configuration.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

        session=sqlSessionFactory.openSession();
    }

    @Test
    public void test(){
        DeptMapper mapper=session.getMapper(DeptMapper.class);

        System.out.println(mapper.selectByPrimaryKey(2));

        EmpMapper mapper1=session.getMapper(EmpMapper.class);

        EmpExample example=new EmpExample();

        example.createCriteria().andSexEqualTo("男").andNameLike("%白%");

        List<Emp> list=mapper1.selectByExample(example);

        list.stream().forEach(System.out::println);
    }
}


~~~java

ession.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Before;
import org.junit.Test;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;

public class TestGenerator {


    SqlSessionFactory sqlSessionFactory=null;
    SqlSession session=null;

    @Before
    public void init() throws IOException {
        String resource = "Configuration.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

        session=sqlSessionFactory.openSession();
    }

    @Test
    public void test(){
        DeptMapper mapper=session.getMapper(DeptMapper.class);

        System.out.println(mapper.selectByPrimaryKey(2));

        EmpMapper mapper1=session.getMapper(EmpMapper.class);

        EmpExample example=new EmpExample();

        example.createCriteria().andSexEqualTo("男").andNameLike("%白%");

        List<Emp> list=mapper1.selectByExample(example);

        list.stream().forEach(System.out::println);
    }
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: MyBatis 是一个开源的持久层框架,可以方便地将 SQL 语句和 Java 对象进行映射。如果您想要学习 MyBatis 源码,可以按照以下步骤进行: 1. 了解 MyBatis 的架构和设计原理。可以阅读官方文档和相关书籍,例如《MyBatis 技术内幕》。 2. 下载 MyBatis 的源代码,并导入到 IDE 中。MyBatis 使用 Maven 进行构建,您可以使用 IDE 的 Maven 插件来下载依赖项。 3. 查看 MyBatis 的源代码结构。MyBatis 的主要代码在 `mybatis-3` 模块中,包括 `src/main/java` 和 `src/main/resources` 目录。其中,`src/main/java` 目录包含了 MyBatis 的核心代码,例如 `org.apache.ibatis.session.SqlSession` 类;`src/main/resources` 目录包含了 MyBatis 的配置文件和映射文件。 4. 阅读 MyBatis 的源代码。可以从 MyBatis 的入口处 `org.apache.ibatis.session.SqlSessionFactoryBuilder` 开始,深入了解 MyBatis 的初始化流程、SQL 语句的执行流程、映射文件的解析和缓存等。 5. 调试 MyBatis 的源代码。可以使用 IDE 的调试功能,对 MyBatis 进行单步调试,观察代码的执行流程,加深对 MyBatis 的理解。 6. 学习 MyBatis 的单元测试。MyBatis 的单元测试位于 `src/test/java` 目录中,可以通过单元测试来了解 MyBatis 的各个功能点的使用方法和测试用例。 7. 参与 MyBatis 的开发。如果您对 MyBatis 源码有深入的了解,并希望为 MyBatis 做出贡献,可以参与 MyBatis 的开发,贡献代码和文档,提交 issue 和 PR。MyBatis 的开发社区非常活跃,可以在官方网站和 GitHub 上找到相关信息。 希望这些步骤对您学习 MyBatis 源码有所帮助。 ### 回答2: MyBatis是一个开源的Java持久层框架,通过操作对象与数据库关系映射来提供数据持久化的功能。了解MyBatis源码是学习和使用该框架的重要一步。 首先,MyBatis的源码结构比较清晰,主要分为核心模块和附属模块。核心模块包括XML配置解析、SQL语句解析、参数处理、数据库连接管理等功能的实现,是实现MyBatis基本功能的核心部分。附属模块包括缓存、事务、插件等额外功能的实现,可以根据需要进行扩展和配置。 学习MyBatis源码可以从以下几个方面入手: 1. 配置文件解析:MyBatis通过XML配置文件来进行相关的配置,了解配置文件的解析过程可以帮助理解MyBatis的初始化过程和各项配置的作用。 2. SQL语句解析与执行:MyBatis将SQL语句封装成MappedStatement对象进行管理,了解MappedStatement的生成过程,以及SQL语句的解析、参数处理和执行过程,可以深入了解MyBatis的SQL执行原理。 3. 会话管理和事务处理:MyBatis采用SqlSessionFactory和SqlSession来管理数据库连接和事务,在MyBatis源码中可以学习到如何管理数据库连接池、事务的提交和回滚等核心功能的实现。 4. 缓存机制:MyBatis提供了一级缓存和二级缓存的功能,了解缓存的生成和更新过程,以及缓存的命中和失效原理,可以提高数据库查询性能。 总之,通过学习MyBatis源码,可以加深对该框架的理解,掌握其内部实现原理,有助于在使用时更加灵活和高效地进行开发。同时,也为以后解决一些特殊问题提供了更多的思路和方法。 ### 回答3: MyBatis是一个优秀的持久层框架,学习其源码有助于理解其底层原理和设计思想。 首先,可以从MyBatis的入口开始学习,即SqlSessionFactoryBuilder类。该类负责解析配置文件、创建Configuration对象,并通过Configuration对象创建SqlSessionFactory实例。 接下来,可以学习Configuration类,该类负责管理整个MyBatis的配置信息。其中包括了数据库连接信息、映射文件信息、缓存信息等。在该类内部,会调用XMLMapperBuilder类解析映射文件,在解析映射文件过程中,会创建MappedStatement对象,该对象表示一条SQL语句的映射信息。 学习MappedStatement对象可以了解MyBatis的SQL语句解析过程。该对象包含了SQL语句的相关信息,包括参数映射关系、返回结果映射关系等。在执行SQL语句时,会使用ParameterHandler类处理参数,通过ResultSetHandler类处理查询结果。 同时,学习到Executor接口及其实现类,可以了解MyBatis的执行过程。Executor负责执行SQL语句,其中包括了写操作的update方法和读操作的query方法。在执行过程中,会通过StatementHandler类创建PreparedStatement对象,并通过ResultSetHandler类处理执行结果。 最后,还可以学习MyBatis的事务处理和缓存机制。Transaction接口及其实现类负责事务管理,通过JDBC的事务机制实现了事务的提交和回滚。而Cache接口及其实现类负责缓存查询结果,在查询时会先从缓存中查找结果。 总结来说,通过学习MyBatis的源码可以深入理解其底层原理和设计思想。从SqlSessionFactory的创建开始,到Configuration的配置解析、MappedStatement的创建,再到Executor的执行过程和Transaction的事务管理,以及Cache的缓存机制,逐步掌握MyBatis的各个组件和它们之间的交互关系。这对于我们使用MyBatis开发项目,解决问题和优化性能都具有积极的意义。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值