MyBatis的使用

一、MyBatis

1.导jar包

  mybatis-3.5.4.jar 

 mysql-connector-java-5.1.47.jar

2.配置mybatis

conf.xml:配置数据库信息 和 需要加载的映射文件



<configuration>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
dataSource>
environment>
environments>
<mappers>
<mapper resource="org/mybatis/example/BlogMapper.xml"/>
mappers>
configuration>

注意事项:

<typeAliases>
	
    <typeAlias type="com.xiaoming.entity.Student" alias="student">typeAlias>

    <package name="com.xiaoming.entity"/>
typeAliases>

3.表 - 类
4.映射文件
xxMapper.xml : 增删改查标签



<mapper namespace="org.mybatis.example.BlogMapper">
<select id="selectBlog" resultType="Blog">
select * from Blog where id = #{id}
select>
mapper>

5.测试类Test:
session.seleceOne(“需要查询的SQL的namespace.id”,“SQL的参数值”);
a.需要获取conf.xml配置文件

//conf.xml ->reader
Reader reader = Resources.getResourceAsReader("conf.xml");
//reader -> sqlsession
SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(reader);
SqlSession session = sessionFactory.openSession();
String statement = "namespace.id";
Studentinfo studentinfo = session.selectOne(statement,SQL的参数值);
(session.commit;)//需要修改数据库的则要这条 增删改需要
session.close;

约定优于配置

二、进阶版(省掉statement)

前四步不变,加入一个新的接口
接口规范:

  1. namespace = 接口的全名
    2.方法名 = 所要调用的id名
    3.返回类型,参数都需要一样

测试类Test:

Reader reader = Resources.getResourceAsReader("conf.xml");
SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(reader);
SqlSession session = sessionFactory.openSession();

StudentMapper studentMapper = session.getMapper(StudentMapper.class);
studentMapper.需要调用的方法();

session.close();

三、类型处理器(类型转换器)

1.MyBatis自带一些常见的类型处理器
int - number
2.自定义MyBatis类型处理器
java - 数据库(jdbc类型)
实例:
实体类Stu’dent : boolean stuSex true: 男
false:女
表student: number stuSex 1:男
0:女
自定义类型转换器(boolean - number)步骤:

a.创建转换器:需要实现TypeHandler接口
i.实现TypeHandler接口
ii.继承BaseTypeHandler
set: java —>数据库 get: db—>java
b.配置conf.xml:

<typeHandlers>
        <typeHandler handler="com.xiaoming.converter.BooleanAndIntConverter" jdbcType="BOOLEAN" javaType="INTEGER"/>
    typeHandlers>

c.StudentMapper.xml
使用了类型转换器
i.表中属性和类中字段能自动匹配(String+varchar int+number)则用resultType,不一样(boolean-int)则用resultMap
ii.表中属性名和类中字段名能够合理识别(stuNo-stuno)则用resultType,不一样(id-stuNo)则用resultMap

<resultMap id="studentResult" type="student">
        
        <id property="stuNo" column="stuNo"/>
        <result property="stuName" column="stuName"/>
        <result property="stuAge" column="stuAge"/>
        <result property="graName" column="graName"/>
        <result property="stuSex" column="stuSex" javaType="BOOLEAN" jdbcType="INTEGER"/>
    resultMap>

注意:
a.mysql数据库boolean、int 要全部大写!
b.输入参数parameterType
i.类型为 简单类型(8个基本类型+String)
1.#{} ${}
#{任意值}
${value} 其中的value必须是value
2.
#{} 会自动给String类型加上’’(单引号) (自动类型转换)
${} 原样输出 适合于动态排序 sql语句中order by ${value} 排序
3.
#{} 防止SQL注入
${} 不防止

ii.对象类型
#{属性名}
${属性名}

四、MyBatis调用存储过程

???

create procedure deleteStu(in sno  int)
READS SQL DATA
begin
delete from student where stuno = sno;
end

CREATE  PROCEDURE  num_from_employee (IN emp_id INT, OUT count_num INT )  
          READS SQL DATA  
          BEGIN  
              SELECT  COUNT(*)  INTO  count_num  
              FROM  STUDENT 
              WHERE  d_id=emp_id ;  
          END

五、动态SQL语句

1.根据姓名和年龄查询学生(返回单个学生)
xxxMapper.xml中用where if 嵌套SQL语句

例:

select stuNo,stuName,stuAge from student
         <where>
            <if test="stuAge != null and stuAge != 0 ">
                 and stuAge=#{stuAge}
            if>
            <if test="stuName != null and stuName != ''">
                and stuName=#{stuName}
            if>
        where>

2.迭代
不使用foreach

select * from student
        <where>
            <if test="stuNos!=null and stuNos.size>0">
                and stuNo in (stuNos)
            if>
        where>

使用foreach

select * from student
        <where>
            <if test="stuNos!=null and stuNos.size>0">
            <foreach collection="stuNos" open="and stuNo in (" close=")" item="stuNo" separator=",">
                #{stuNo}
            foreach>
            if>
        where>

注意:collection=“stuNos” 集合 open=“and stuNo in (” open 就是集合左边的 close=")" 同理
item=“stuNo” 每个元素的名字 类似于 for 循环中的i separator=","每个元素之间的分隔符 #{stuNo}
and stuNo in (stuNos)

3.简单类型的数组:
将foreach中的if collection 的改为array

select * from student
        <where>
            <if test="array!=null and array.length>0">
                <foreach collection="array" open=" and stuNo in (" close=")" item="stuNo" separator=",">
                    #{stuNo}
                </foreach>
            </if>
        </where>

4.集合 集合用list

select * from student
        <where>
            <if test="list!=null and list.size>0">
                <foreach collection="list" open=" and stuNo in (" close=")" item="stuNo" separator=",">
                    #{stuNo}
                </foreach>
            </if>
        </where>

5.对象数组 parameterType =“Object[]” item ="数组的对象类型"其他与array一样

select * from student
        <where>
            <if test="array!=null and array.length>0">
                <foreach collection="array" open=" and stuNo in (" close=")" item="stuNo" separator=",">
                    #{对象类型.stuNo}
                </foreach>
            </if>
        </where>

6.将相同的SQL语句打包

相同的sql语句写在其中

到需要引用的地方

在不同的包下面需要写包路径.xxx

六、关联查询:(MyBatis中只有两种)

A.一对一:
a.业务扩展类
resultType=“StudentBusiness” 返回类型牵连两张表的时候需要业务扩展类 业务扩展类继承一张表(较多属性的)另 一张表的属性写在业务扩展类中(包括get and set)
注意:在接口中返回类型一定是业务扩展类的类型,用父类的类型不会报错(多态)

 <select id="queryStudentByNoWithOO" resultType="StudentBusiness" parameterType="int">
        select s.*,c.* from student s inner join studentcard c
        on s.cardid = c.cardid
        where s.stuNo = #{stuNo}
    select>

b.resultMap

返回类型改为resultMap id 为下列resultMap的id 其他的同上

<resultMap id="xxx" type="">

<id property="" column=""/>
<result property="" column=""/>
...

<association property="card" javaType="StudentCard">
        	    <id property="cardId" column="cardId">id>
                <result property="cardInfo" column="cardInfo">result>
    	association>
resultMap>

B.一对多:(MyBatis:多对一,多对多 本质是一对多)

 <resultMap id="student_class_map" type="StudentClass">
        
        <id property="classId" column="classId">id>
        <result property="className" column="className">result>
        
        <collection property="students" ofType="Student">
            <id property="stuNo" column="stuNo"/>
            <result property="stuName" column="stuName"/>
            <result property="stuAge" column="stuAge"/>
        collection>
    resultMap>

七、Log4j 日志信息

1.导入log4j.jar(在MyBatis)
2.配置conf.xml (在properties后面)

<settings>
        
        <setting name="logImpl" value="LOG4J"/>
    settings>

3.创建 log4j.properties(名字必须和conf.xml中的value一样)

log4j.rootLogger = debug

输出信息到控制台

# Global logging configuration 开发时候建议使用 debug
log4j.rootLogger=DEBUG, stdout
# Console output...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n

其中debug 有DEBUG\INFO\WARN\ERROR四种
< < <
一般在调试用DEBUG 运行用INFO

八、延迟加载

1.一对一
a.先在StudentMapper.xml配置

	
    <select id="queryStuByNoWithOOLazy" resultMap="student_card_lazy_map" >
        /*先查学生*/
        select * from student
    select>
    <resultMap id="student_card_lazy_map" type="student">
        <id property="stuNo" column="stuNo"/>
        <result property="stuName" column="stuName"/>
        <result property="stuAge" column="stuAge"/>
	
        <association property="card" javaType="StudentCard" select="com.xiaoming.mapper.StudentCardMapper.queryStuCard" column="cardId">
        association>
    resultMap>

b创建StudentCardMapper.xml

<select id="queryStuCard" resultType="studentCard" parameterType="int">
        select * from studentcard where cardid = #{cardId}
    select>

注意(******):StudentMapper.xml中再查学生卡中的 select 属性为StudentCardMapper.xml 的 namespace.id 且column 为 两个表的外键属性名

c.配置conf.xml

<settings>
        
        <setting name="logImpl" value="LOG4J"/>
        
        <setting name="lazyLoadingEnabled" value="true"/>
        
        <setting name="aggressiveLazyLoading" value="false"/>
    settings>

注意(***********):新建了xxxMapper.xml文件 一定一定要在conf.xml中配置

<mappers>
        <mapper resource="com/xiaoming/mapper/StudentMapper.xml"/>
        <mapper resource="com/xiaoming/mapper/StudentCardMapper.xml"/>
    mappers>

d.测试

2.一对多
a.判断先查询哪个?(例如:学生信息表与班级信息表 先查询班级信息表 则创建班级信息Mapper.xml 否则在学生信息表里配置)

<select id="queryClassAndStuByLazy" resultMap="student_class_lazy_map" parameterType="int">
       select * from studentclass
select>
<resultMap id="student_class_lazy_map" type="StudentClass">
        
        <id property="classId" column="classId">id>
        <result property="className" column="className">result>
        
        <collection property="students" ofType="Student" select="com.xiaoming.mapper.StudentMapper.queryStuInClass" column="classId">collection>
resultMap>

同一对一

注意(*******): namespace 一定一定要改!!!
b.如果是班级信息Mapper.xml则需要创建新的接口且接口名与namespace的名字相同(要与namespace对应起来)
c.然后在稍后查询的那张表的xml里配置(学生信息Mapper.xml)

<select id="queryStuInClass" parameterType="int" resultType="student">
        select  * from student where classid=#{classId}
</select>

d.测试

九、查询缓存

1、一级缓存
在sqlsession对象的有缓存 MyBatis默认开启一级缓存。
一级缓存:两次或两次以上查询相同的语句,不会再执行sql语句直接用sqlsession缓存的数据(省略了数据库的访问)
commit() 重新访问数据库 清空缓存
2、二级缓存

MyBatis自带二级缓存
a.在conf.xml中配置

b.在需要用二级缓存的XxxMapper.xml中开启 c.第一次查询后 用sqlsession.close(); 关闭将缓存存入 只要是同一个namespace 可以使用二级缓存

​ 禁用: 在XxxMapper.xml 中不用的加入

<select ......useCache="false">select>

​ 清理: commit();

​ 命中率: 1.zs 0%
​ 2. 50%
​ 3. 2/3

十、逆向工程

​ 表、类、接口、mapper.xml密切相关,当知道一个的时候其他三个可以自动生成

表—>其他三个

MyBatis Generator Core.jar、slf4j-log4j12-1.7.30.jar、mybatis-generator-core-1.3.5.jar、
mysql-connector-java-5.1.47.jar

写日志文件 log4j.properties↑
创建generator.xml



<generatorConfiguration>
    <context id="MybatisGenerator" targetRuntime="mybatis3">
        <commentGenerator>
            
            <property name="suppressAllComments" value="true"/>
        commentGenerator>

    <jdbcConnection driverClass="com.mysql.jdbc.Driver"
                    connectionURL="jdbc:mysql://localhost:3306/mybatis"
                    userId="root" password="123456">
    jdbcConnection>

    
    <javaTypeResolver>
        <property name="forceBigDecimals" value="false"/>
    javaTypeResolver>

    
    <javaModelGenerator targetPackage="com.xiaoMing.entity" targetProject="./src">
        
        <property name="enableSubPackages" value="true"/>
        
        <property name="trimStrings" value="true"/>
    javaModelGenerator>

    
    <sqlMapGenerator targetPackage="com.xiaoMing.mapper" targetProject="./src">
        <property name="enableSubPackages" value="false"/>
    sqlMapGenerator>

    
    <javaClientGenerator targetPackage="com.xiaoMing.mapper" type="XMLMAPPER" targetProject="./src">
        <property name="enableSubPackages" value="false"/>
    javaClientGenerator>

    
    <table tableName="Student"/>
    <table tableName="StudentCard"/>
    <table tableName="StudentClass"/>

context>
generatorConfiguration>

测试类写

List<String> warnings = new ArrayList<>();
        File file = new File("E:\\IDEA\\SecondMyBatis\\ThirdProject\\src\\generator.xml");
        ConfigurationParser cp = new ConfigurationParser(warnings);
        Configuration configuration = cp.parseConfiguration(file);
        DefaultShellCallback callback = new DefaultShellCallback(true);

 MyBatisGenerator generator = new MyBatisGenerator(configuration,callback,warnings);
  generator.generate(null);

你可能感兴趣的:(mybatis,数据库)