• Mybatis第二天


    一、可以优化的几个地方:

    1、将数据库连接的设置放在一个配置文件中

      db.properties

    jdbc.driverName=com.mysql.jdbc.Driver
    jdbc.url=jdbc:mysql:///test
    jdbc.username=root
    jdbc.password=root

      在mybatis配置文件中引用db.properties

    <?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>
    
    <!--    读取数据库配置文件-->
        <properties resource="db.properties"></properties>
    
    
        <environments default="development">
            <environment id="development">
                <transactionManager type="JDBC" />
                <dataSource type="POOLED">
                    <property name="driver" value="${jdbc.driverName}" />
                    <property name="url" value="${jdbc.url}" />
                    <property name="username" value="${jdbc.username}" />
                    <property name="password" value="${jdbc.password}" />
                </dataSource>
            </environment>
        </environments>
      
    </configuration>
    View Code

    2、给实体类起别名,简化映射文件中对实体类引用的写法

      别名在mybatis配置文件中设置

    <?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>
    
    <!--    给实体类起别名-->
        <typeAliases>
            <!--    1、单独给一个实体类起别名,该例的别名就是“s”-->
            <!--        <typeAlias type="com.fy.bbb.entity.SalGrade" alias="s"></typeAlias>-->
            <!--    2、给整个包起别名,类的别名就是类名    -->
           <package name="com.fy.bbb.entity"/>
        </typeAliases>
    
    
        <environments default="development">
            <environment id="development">
                <transactionManager type="JDBC" />
                <dataSource type="POOLED">
                    <property name="driver" value="${jdbc.driverName}" />
                    <property name="url" value="${jdbc.url}" />
                    <property name="username" value="${jdbc.username}" />
                    <property name="password" value="${jdbc.password}" />
                </dataSource>
            </environment>
        </environments>
    
        <mappers>
            <mapper resource="mapper/SalGradeMapper.xml"></mapper>
        </mappers>
    </configuration>
    View Code

      配置文件中对别名的使用

    <?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.fy.bbb.dao.SalGradeDao">
    
           <select id="getAll" resultType="s">
               select * from salgrade
           </select>
    
    </mapper>
    View Code

     3、解决实体类中的字段和数据表字段不对应的问题

      ①、给数据库查询语句起别名,别名和实体类字段名相同

    <?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.fy.bbb.dao.SalGradeDao">
        <!--    解决java实体类字段和数据库字段不相同的问题-->
        <!--    1、给sql语句中的字段起别名-->
        <select id="getAll" resultType="com.fy.bbb.entity.SalGrade">
              select grade as g from salgrade
           </select>
    </mapper>
    View Code

      ②、在配置文件中使用resultMap,将数据库表字段和实体类属性一 一对应。resultMap还是连表查询必须要用的

    <?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.fy.bbb.dao.SalGradeDao">
        <!--    解决java实体类字段和数据库字段不相同的问题-->
    
        <!--    2、使用resultMap-->
        <resultMap id="baseMap" type="com.fy.bbb.entity.SalGrade">
            <!--       id标签中映射主键列   column中写数据库字段    property中写java实体类的属性-->
            <id column="id" property="id"></id>
            <!--       result标签映射其他列-->
            <result column="grade" property="grade"></result>
            <result column="losal" property="losal"></result>
            <result column="hisal" property="hisal"></result>
        </resultMap>
    
        <select id="getAll" resultType="com.fy.bbb.entity.SalGrade">
               select * from salgrade
           </select>
    </mapper>
    View Code

    4、加入日志

     步骤:

      ①、导入jar包

    <dependency>
                <groupId>log4j</groupId>
                <artifactId>log4j</artifactId>
                <version>1.2.17</version>
    </dependency>
    View Code

      ②、写配置文件  log4j.properties

    log4j.rootLogger=DEBUG, Console
    #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
    View Code

    二、连表查询

      注:使用mybatis查询时,我们要指定resultMap或者resultType。连表查询时就不是一个单一的实体类就能接收数据了,所以要在实体类之间相互引用

      准备表数据:class表和teacher表

    CREATE TABLE teacher(
    t_id INT PRIMARY KEY AUTO_INCREMENT,
    t_name VARCHAR(20)
    );
    CREATE TABLE class(
    c_id INT PRIMARY KEY AUTO_INCREMENT,
    c_name VARCHAR(20),
    teacher_id INT
    );
    ALTER TABLE class ADD CONSTRAINT fk_teacher_id FOREIGN KEY (teacher_id)
    REFERENCES teacher(t_id);
    INSERT INTO teacher(t_name) VALUES('LS1');
    INSERT INTO teacher(t_name) VALUES('LS2');
    INSERT INTO class(c_name, teacher_id) VALUES('bj_a', 1);
    INSERT INTO class(c_name, teacher_id) VALUES('bj_b', 2);
    View Code

      ①、多对一:多个职员对应一个级别,此时就要将级别表实体类引入到职员表的实体类中

      实体类:

        class:班级实体类 

    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    public class Clazz {  //
        private int cid;
        private String cname;
        private Teacher teacher;//该班级对应的老师信息
    }
    View Code

        teacher:老师实体类

    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    public class Teacher {
        private int tid;
        private String tname;
    }
    View Code

      映射文件:classMapper.xml

    <?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">
    <!--namespace必须和接口的全路径匹配-->
    <mapper namespace="com.ykq.dao.ClazzDao">
    
        <!--联表查询得到的结果-->
        <resultMap id="ClazzMap" type="com.ykq.entity.Clazz">
               <id column="c_id" property="cid"/>
               <result column="c_name" property="cname"/>
               <!--association多对一的映射
                         javaType:表示属性名对应的java实体类类型
               -->
               <association property="teacher" javaType="com.ykq.entity.Teacher">
                     <!--该属性的名称与字段的对应关系-->
                   <id column="t_id" property="tid"/>
                   <result column="t_name" property="tname"/>
               </association>
        </resultMap>
    
        <!--只要使用联表查询 必须使用resultMap-->
        <select id="findClassByid" resultMap="ClazzMap">
            select * from class c,teacher t where c.teacher_id=t.t_id
             and c.c_id=#{cid}
        </select>
    
    </mapper>
    View Code

      第二种写法,将sql语句分开写,改动仅是映射文件。

      先查询班级,再查班级中对应的老师,两次查询

    <?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">
    <!--namespace必须和接口的全路径匹配-->
    <mapper namespace="com.ykq.dao.ClazzDao">
    
        <!--两次查询得到结果-->
    
        <resultMap id="ClazzMap" type="com.ykq.entity.Clazz">
            <id column="c_id" property="cid"/>
            <result column="c_name" property="cname"/>
    
            <!--column:把第一次查询的某一列作为第二次查询的值,自动赋值
                 select:指定第二次要执行的sql
            -->
            <association property="teacher" javaType="com.ykq.entity.Teacher" column="teacher_id" select="findTeacherById">
                <id column="t_id" property="tid"/>
                <result column="t_name" property="tname"/>
            </association>
        </resultMap>
    
        <select id="findClassByid" resultMap="ClazzMap">
              select * from class where c_id=#{cid}
        </select>
    
        <select id="findTeacherById" resultType="com.ykq.entity.Teacher">
              select t_id tid,t_name tname from teacher where t_id=#{tid}
        </select>
    
    </mapper>
    View Code

      ②、一对多:一个班级对应多个学生,应为是多个学生,所以要把学生实体类引用班级实体类中时要用集合的方式

      创建学生表:  

    CREATE TABLE student(
    s_id INT PRIMARY KEY AUTO_INCREMENT,
    s_name VARCHAR(20),
    class_id INT
    );
    INSERT INTO student(s_name, class_id) VALUES('xs_A', 1);
    INSERT INTO student(s_name, class_id) VALUES('xs_B', 1);
    INSERT INTO student(s_name, class_id) VALUES('xs_C', 1);
    INSERT INTO student(s_name, class_id) VALUES('xs_D', 2);
    INSERT INTO student(s_name, class_id) VALUES('xs_E', 2);
    INSERT INTO student(s_name, class_id) VALUES('xs_F', 2);
    View Code

      Student:学生实体类

    @AllArgsConstructor
    @NoArgsConstructor
    @Data
    public class Student {
        private int sId;
        private String sname;
    }
    View Code

      class:班级实体类

    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    public class Clazz {  //
        private int cid;
        private String cname;
        private Teacher teacher;//该班级对应的老师信息
    
        //表示该班级下所有的学生信息
        private List<Student> students;
    }
    View Code

       教师表不动。

      映射文件:classMapper.xml

    <?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">
    <!--namespace必须和接口的全路径匹配-->
    <mapper namespace="com.ykq.dao.ClazzDao">
    
    
    
        <!--联表查询得到的结果-->
        <resultMap id="ClazzMap" type="com.ykq.entity.Clazz">
               <id column="c_id" property="cid"/>
               <result column="c_name" property="cname"/>
               <!--association多对一的映射
                         javaType:表示属性名对应的java实体类类型
               -->
               <association property="teacher" javaType="com.ykq.entity.Teacher">
                     <!--该属性的名称与字段的对应关系-->
                   <id column="t_id" property="tid"/>
                   <result column="t_name" property="tname"/>
               </association>
    
                <!--ofType:表示集合的泛型-->
               <!--collection:一对多的配置使用collection-->
               <collection property="students" ofType="com.ykq.entity.Student">
                    <id column="s_id" property="sId"/>
                   <result column="s_name" property="sname"/>
               </collection>
    
        </resultMap>
        <!--只要使用联表查询 必须使用resultMap-->
        <select id="findClassByid" resultMap="ClazzMap">
            select * from class c,teacher t,student s where c.teacher_id=t.t_id
             and c.c_id=s.class_id
             and c.c_id=1  and c.c_id &lt;=1
        </select>
    
    </mapper>        
    View Code

    三、xml碰见特殊字符的处理

      例:再sql语句中使用小于“<”就会出问题

      解决方法:

      ①可以使用转义字符

        

      ②、使用CDATA

      

     <select id="findClassBetweenIds" resultMap="ClazzMap">
            <![CDATA[select * from class where c_id >=#{minId}  and c_id <=#{maxId}]]>
     </select>
  • 相关阅读:
    CF1450H2
    CF1379F2
    CF1217F
    CF1393E2
    CF1510H
    CF1514E
    CF1515G
    CF1516E
    在pycharm中导入PyMysql出错,解决方法
    搭建fastdfs文件服务器
  • 原文地址:https://www.cnblogs.com/fbbg/p/14564962.html
Copyright © 2020-2023  润新知