Mybatis总结

Posted psxfd4

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Mybatis总结相关的知识,希望对你有一定的参考价值。

支持定制化 SQL、存储过程以及高级映射的优秀的数据库框架。

一、使用前准备

  1.加入相关的jar包。这里使用mybatis-3.2.2.jar包,数据库使用mysql 5.5版本

  2.创建mybatis的配置文件

  这里创建一个demo,数据库名huayu,表有student,class,adviser,course,sc,teacher其结构分别为

SET FOREIGN_KEY_CHECKS=0;

-- ----------------------------
-- Table structure for adviser
-- ----------------------------
DROP TABLE IF EXISTS `adviser`;
CREATE TABLE `adviser` (
  `aid` int(11) NOT NULL,
  `adviserName` varchar(10) DEFAULT NULL,
  PRIMARY KEY (`aid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- ----------------------------
-- Table structure for class
-- ----------------------------
DROP TABLE IF EXISTS `class`;
CREATE TABLE `class` (
  `cid` int(11) NOT NULL,
  `method` varchar(20) DEFAULT NULL,
  `aid` int(11) DEFAULT NULL,
  PRIMARY KEY (`cid`),
  KEY `c_aid` (`aid`),
  CONSTRAINT `c_aid` FOREIGN KEY (`aid`) REFERENCES `adviser` (`aid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- ----------------------------
-- Table structure for course
-- ----------------------------
DROP TABLE IF EXISTS `course`;
CREATE TABLE `course` (
  `cid` varchar(10) NOT NULL DEFAULT ‘‘,
  `cname` varchar(40) DEFAULT NULL,
  `coursehour` int(11) DEFAULT NULL,
  PRIMARY KEY (`cid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- ----------------------------
-- Table structure for sc
-- ----------------------------
DROP TABLE IF EXISTS `sc`;
CREATE TABLE `sc` (
  `sid` int(11) NOT NULL DEFAULT 0,
  `cid` varchar(10) NOT NULL DEFAULT ‘‘,
  `score` int(11) DEFAULT NULL,
  `tid` int(11) DEFAULT NULL,
  PRIMARY KEY (`sid`,`cid`),
  KEY `t_tid` (`tid`),
  KEY `c_cid` (`cid`),
  CONSTRAINT `c_cid` FOREIGN KEY (`cid`) REFERENCES `course` (`cid`),
  CONSTRAINT `s_sid` FOREIGN KEY (`sid`) REFERENCES `student` (`sid`),
  CONSTRAINT `t_tid` FOREIGN KEY (`tid`) REFERENCES `teacher` (`tid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- ----------------------------
-- Table structure for student
-- ----------------------------
DROP TABLE IF EXISTS `student`;
CREATE TABLE `student` (
  `sid` int(11) NOT NULL,
  `sname` varchar(10) DEFAULT NULL,
  `age` int(11) DEFAULT NULL,
  `qualification` varchar(10) DEFAULT NULL,
  `cid` int(11) DEFAULT NULL,
  PRIMARY KEY (`sid`),
  KEY `s_cid` (`cid`),
  CONSTRAINT `s_cid` FOREIGN KEY (`cid`) REFERENCES `class` (`cid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- ----------------------------
-- Table structure for teacher
-- ----------------------------
DROP TABLE IF EXISTS `teacher`;
CREATE TABLE `teacher` (
  `tid` int(11) NOT NULL,
  `tname` varchar(10) DEFAULT NULL,
  PRIMARY KEY (`tid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

结构模型图技术图片

配置文件,Mybatis优化:使用属性文件;

driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/huayu
username=root
password=root

  

<?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" />
  <!--此处为配置分页查询PageHelper的代码 -->
<plugins> <plugin interceptor="com.github.pagehelper.PageInterceptor"> <!-- config params as the following --> <property name="param1" value="value1" /> </plugin> </plugins> <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> </mappers> </configuration>

   3.创建映射文件,映射文件相当于dao接口的实现类,首先创建StudentMapper,写一个方法queryByCidAndQua,根据班级号和学历查询

<?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.zhiyou100.cyf.dao.StudentMapper">
    <sql id="all_cols">
        sid,sname,age,qualification,cid
    </sql>
    <select id="queryByCidAndQua" resultType="com.zhiyou100.cyf.bean.Student">
        select <include refid="all_cols"></include> from student
        where cid=#cid and qualification=#qua
    </select>
</mapper>

优化:要传递的参数为两个以上时,框架会默认将其放进一个map内,key值分别为0,1或param1,param2,value为参数值,在接口的方法设置注解改变默认key

List<Student> queryByCidAndQua(@Param("qua")String qua,@Param("cid")String cid);

 

 

   4.映射文件要引入到配置文件内

在configuration标签内添加

<mappers>
    <mapper resource="com/zhiyou100/cyf/mapper/StudentMapper.xml" />
</mappers>

  5.加入日志:引入log4j-1.2.17.jar包,创建日志文件log4j.properties

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

 

二、创建关系表和对应的实体类、操作接口和实现的映射文件

  1.dao接口结合对应的映射文件

  映射文件的namespace属性应为该接口的位置,接口的方法名与映射文件中相应的id属性值相同,再建一个ClassMapper映射,将列名改动一下method -> c_method,在问题sql字段与java属性不匹配里解决。

List<Class> selectAll();//接口中暂加一个方法

三、测试

  

class StudentMapperTest 

    static SqlSession session=null;
    static StudentMapper sm=null;
    @BeforeAll
    static void setUpBeforeClass() throws Exception 
        Reader reader=Resources.getResourceAsReader("conf.xml");
        SqlSessionFactory sessionFactory=new SqlSessionFactoryBuilder().build(reader);
        session=sessionFactory.openSession();
        sm=session.getMapper(StudentMapper.class);
    

    @AfterAll
    static void tearDownAfterClass() throws Exception 
        session.commit();
    

    @Test
    void testQueryByCidAndQua() 
        List<Student> list=sm.queryByCidAndQua("本科", "20100101");//两个参数。可以用map传,不过这样写框架会默认创建map
        System.out.println(list);
    

 

四、一些问题

  1.sql字段与java属性不匹配 

       一种方案是给查询字段起别名,使其与java属性一致

另一种是使用resultMap标签来定义实体类与字段之间的对应关系

  

<mapper namespace="com.zhiyou100.cyf.dao.ClassMapper">
    <sql id="all_cols">
        cid,c_method,aid
    </sql>
    <select id="selectAll" resultMap="classMap">
        select <include refid="all_cols"/> from class
    </select>
    <resultMap type="com.zhiyou100.cyf.bean.Class" id="classMap">
        <result column="c_method" property="method"/>
    </resultMap>
</mapper>

 

  2.连表查询

一对一或多对一:一个班有一个老师,根据班级id查询所关联的老师信息,或根据班级内的学生查询所关联的老师信息

在班级类中增加一个老师的属性

<resultMap type="com.zhiyou100.xz.bean.Clazz" id="clazzMapper">
        <!-- id:标签标识表中的主键与实体类的值属性对应关系 -->
        <id column="c_id" property="cid"/>
        <result column="c_name" property="cname"/>
        <result column="teacher_id" property="tid"/>
        <!-- 该类中引入的一的一方的属性
            property:属性名
            javaType:该属性的Java类型
         -->
        <association property="teacher" javaType="com.zhiyou100.cyf.bean.Teacher">
                <id column="t_id" property="tid"/>
                <result column="t_name" property="tname"/>
        </association>

select中语句为连接查询语句。如果用嵌套查询,则需要另外创建并实现TeacherDao的queryById方法

<association property="teacher" javaType="com.zhiyou100.xz.bean.Teacher"
            column="teacher_id" select="com.zhiyou100.cyf.dao.TeacherDao.queryById">
        </association>

 一对多:如查询在一个班的所有学生

在班级类内创建students属性,类型为List<Student>

</association>
        <!-- ofType:集合中泛型的类型 -->
        <collection property="students" ofType="com.zhiyou100.cyf.bean.Student">
                <id property="sid" column="s_id"/>
                <result property="sname" column="s_name"/>
        </collection>

在resultMap中添加collection标签,mybatis会自动给若干个student装进一个集合。同样,如果用嵌套查询,要在StudentDao中创建并实现返回list的queryByCId方法

<collection property="students" ofType="com.zhiyou100.cyf.bean.Student" column="c_id" select="com.zhiyou100.cyf.dao.StudentDao.queryByCId"></collection>

  3.sql语句中$与#区别:

    $: 解析时不会为内容添加””,他是sql语句的拼接存在sql注入的危害。传入的为表结构,order by排序等不需要字符串的情况下使用它。

    #: 解析时会为内容添加””,它的sql时采用占位符,防止sql注入,尽量使用。

  4.添加对象时如何把生产的id返回

 

<insert parameterType="com.zhiyou100.cyf.bean.User" userGenerateKeys="true" keyProperty="id">insert user(name,age) values(#name,#age)</insert>
userGenerateKeys,keyProperty两个属性必须同时使用,id返回到调用者的参数user对象的id属性上
  5.测试类中update类操作的事务性
 @AfterAll
    static void tearDownAfterClass() throws Exception 
        session.commit();//在代码执行完后,才使数据库执行增删改操作
    

为了保证安全和严谨,此处模拟了事务操作,一系列操作要么都执行,要么都不执行

以上是关于Mybatis总结的主要内容,如果未能解决你的问题,请参考以下文章

转MyBatis学习总结——Mybatis缓存

MyBatis学习总结——MyBatis快速入门

MyBatis学习总结——MyBatis快速入门

MyBatis学习总结——MyBatis快速入门(转载)

MyBatis学习总结——MyBatis快速入门

MyBatis学习总结——MyBatis快速入门