SSM学习(一)Mybatis

Mybatis Notes

Mybatis First

创建Maven项目

配置依赖

<dependencies>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>RELEASE</version>
    </dependency>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis</artifactId>
        <version>RELEASE</version>
    </dependency>
    <dependency>
        <groupId>log4j</groupId>
        <artifactId>log4j</artifactId>
        <version>RELEASE</version>
    </dependency>
</dependencies>

log4j配置

src\main\resources\log4j.properties

log4j.rootLogger=DEBUG
log4j.appender.console=org.apache.log4j.ConsoleAppender
log4j.appender.console.Target=System.out
log4j.appender.console.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern = [%-5p] %m%n
log4j.logger.test=debug,console

jdbc配置文件

src\main\resources\jdbc.properties

jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/test?serverTimezone=GMT%2B8
jdbc.name=root
jdbc.password=123456

主配置文件

src\main\resources\mybatis-config.xml

<?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>
    <!--导入jdbc配置文件-->
    <properties resource="jdbc.properties" />
    <!--别名-->
    <typeAliases>
        <!--两种方式-->
        <!--<typeAlias type="com.hex.model.Student" alias="xxx" />-->
        <package name="com.hex.model" />
    </typeAliases>
    <!--配置数据库环境-->
    <environments default="mysql_env">
        <environment id="mysql_env">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="${jdbc.driver}"/>
                <property name="url" value="${jdbc.url}"/>
                <property name="username" value="${jdbc.name}"/>
                <property name="password" value="${jdbc.password}"/>
            </dataSource>
        </environment>
    </environments>
    <!--导入sql映射文件-->
    <mappers>
        <mapper resource="mapper.xml"/>
    </mappers>
</configuration>

mapper映射文件

src\main\resources\mapper.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">
<mapper namespace="com.hex.model.Student">
    <!--values里面填的是属性(setget方法名去掉setget首字母小写)-->
    <insert id="insertStudent" parameterType="Student">
        insert into student(name,age,score) values (#{name},#{age},#{score})
    </insert>
    <delete id="deleteStudentById" parameterType="int">
        DELETE FROM student WHERE id=#{id}
    </delete>
    <delete id="deleteStudentByName" parameterType="string">
        DELETE FROM student WHERE NAME=#{name}
    </delete>
    <select id="searchStudentById" parameterType="int" resultType="Student">
        SELECT * FROM student WHERE id=#{id}
    </select>
    <select id="searchStudentByName" parameterType="string" resultType="Student">
        SELECT * FROM student WHERE NAME=#{name}
    </select>
    <select id="modifyStudent" parameterType="Student">
        UPDATE student SET NAME=#{name},age=#{age},score=#{score} where id=#{id}
    </select>
    <select id="fuzzyQueryByName" parameterType="string" resultType="Student">
        SELECT * FROM student WHERE NAME LIKE '%${value}%'
    </select>
</mapper>

实体类

com.hex.model.Student

public class Student {
    private Integer id;
    private String name;
    private int age;
    private double score;
    public Student() {}
    public Student(String name, int age, double score) {
        this.name = name;
        this.age = age;
        this.score = score;
    }
    /* 省略set、get方法 */
}

dao层

com.hex.dao.StudentDao

package com.hex.dao;
import com.hex.model.Student;
import com.hex.utils.MybatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;
import javax.sound.midi.SoundbankResource;
import java.util.ArrayList;
import java.util.List;
public class StudentDao {
    private SqlSession sqlSession;
    public void insertStudent(Student student){
        try{
            sqlSession = MybatisUtils.sqlSessionFactory();
            sqlSession.insert("insertStudent",student);
            sqlSession.commit();
        }finally {
            sqlSession.close();
        }
    }
    public void deleteStudentById(int id){
        try{
            sqlSession = MybatisUtils.sqlSessionFactory();
            sqlSession.delete("deleteStudentById",id);
            sqlSession.commit();
        }finally {
            sqlSession.close();
        }
    }
    public void deleteStudentByName(String name){
        try{
            sqlSession = MybatisUtils.sqlSessionFactory();
            sqlSession.delete("deleteStudentByName",name);
            sqlSession.commit();
        }finally {
            sqlSession.close();
        }
    }
    public List<Student> searchStudentById(int id){
        List<Student> studentList  = new ArrayList<Student>();
        try{
            sqlSession = MybatisUtils.sqlSessionFactory();
            studentList = sqlSession.selectList("searchStudentById",id);
        }finally {
            sqlSession.close();
            return studentList;
        }
    }
    public List<Student> searchStudentByName(String name){
        List<Student> studentList  = new ArrayList<Student>();
        try{
            sqlSession = MybatisUtils.sqlSessionFactory();
            studentList = sqlSession.selectList("searchStudentByName",name);
        }finally {
            sqlSession.close();
            return studentList;
        }
    }
    public void modifyStudent(Student student){
        try{
            sqlSession = MybatisUtils.sqlSessionFactory();
            sqlSession.update("modifyStudent",student);
            sqlSession.commit();
        }finally {
            sqlSession.close();
        }
    }
    public List<Student> fuzzyQueryByName(String word){
        List<Student> studentList  = new ArrayList<Student>();
        try{
            sqlSession = MybatisUtils.sqlSessionFactory();
            studentList = sqlSession.selectList("fuzzyQueryByName",word);
        }finally {
            sqlSession.close();
            return studentList;
        }
    }
}

工具类

com.hex.utils.MybatisUtils

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 java.io.IOException;
import java.io.InputStream;
public class MybatisUtils {
    private static SqlSessionFactory sqlSessionFactory;
    /**
     * 读取主配置文件,创建SqlSession,如果SqlSession已经存在则直接返回
     * @return
     */
    public static SqlSession sqlSessionFactory() {
        try {
            InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
            if (sqlSessionFactory == null) {
                sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
            }
            return sqlSessionFactory.openSession();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }
}

测试类

com.hex.test.MyTest

import com.hex.dao.StudentDao;
import com.hex.model.Student;
import org.junit.Test;
import java.io.IOException;
public class MyTest {
    private StudentDao dao = new StudentDao();
    @Test
    public void test() throws IOException {
        Student student = new Student("hex",23,98.5);
        dao.insertStudent(student);
    }
    /*省略其他测试方法*/
}

单表的CURD操作

sql语句拼接

<select id="fuzzyQueryByName" parameterType="string" resultType="Student">
    SELECT * FROM student WHERE NAME like '%' #{word} '%'
</select>
<select id="fuzzyQueryByName" parameterType="string" resultType="Student">
    SELECT * FROM student WHERE NAME like concat('%',#{word},'%')
</select>
<!--第3中方法难以避免sql注入问题-->
<select id="fuzzyQueryByName" parameterType="string" resultType="Student">
    SELECT * FROM student WHERE NAME LIKE '%${value}%'
</select>

resultMap

<resultMap id="studentMapper" type="Student">
    <id column="tid" property="id" />
    <result column="tname" property="name" />
</resultMap>
<select id="searchStudentById" resultMap="studentMapper">
    SELECT tid,tname,tage,score FROM student WHERE id=#{id}
</select>

数据库字段名和实体类属性名不一致:将数据库的tid、tname、tage、score封装到Student(id,name,age,score)对象中

mapper动态代理

一般流程
dao对象调用dao层接口的实现类 -> sqlSession.insert(映射器id,映射器需要的参数) -> mapper中对应id的sql语句
mapper的动态代理
new sqlSession -> dao = sqlSession.getMapper(dao层接口.class) -> dao调用接口

通常dao层接口的实现类里面定义了sqlSession去指定mapper.xml映射文件中的哪一个映射方法。然后mapper的动态代理要设置mapper的命名空间,sqlSession.getMapper(dao层接口.class)就相当于指定要找该指定命名空间的映射器。可是映射文件里面定义了那么多select、insert等查询语句,怎么调用我要的呢?这个时候就可以直接用dao对象调用接口,因为接口名和sql语句名是相同的,就可以定位到相应的sql语句。看上去好像是dao直接执行sql语句一样。

两个关键:mapper的命名空间是接口类的全限定类名。接口的方法名和mapper中定义的查询语句的id要保持一致。

@Test
public void mapperDynamicProxy(){
        SqlSession sqlSession = MybatisUtils.sqlSessionFactory();
        StudentDao dao = sqlSession.getMapper(StudentDao.class);
        Student student = dao.selectStudentById(1);
        System.out.println(student.getName());
}

多条件查询

  • 把查询条件封装成实体类的对象
  • 把查询条件封装成Map
  • 索引
#{}中可以放什么内容:
1.参数对象的属性
2.随意内容,此时的#{}是个占位符
3.参数为Map时的key
4.参数为Map时key所对应的value为对象,则可将该对象的属性放入
5.参数的索引号

动态SQL

原符号 < <= > >= & ' "
替换符号 &lt; &lt;= &gt; &gt;= &amp; &apos; &quot;
  • if

    <select id="selectStudentByCondition" resultType="Student">
      select * form student
      <where>
          <if test="name != null and name != ''">
              and name like '%' #{name} '%'
          </if>
          <if test="age &gt; 0">
              and age > #{age}
          </if>
      </where>
    </select>
  • choose, when, otherwise

    <select id="selectStudentByCondition" resultType="Student">
        select * form student
        <where>
            <choose>
                <when test="name != null and name != ''">
                    and name like '%' #{name} '%'
                </when>
                <when test="age &gt; 0">
                    and age > #{age}
                </when>
                <otherwise>
                    1 = 2
                </otherwise>
            </choose>
        </where>
    </select>
  • trim, where, set

  • foreach

    <!--遍历数组-->
    <select id="selectStudentByCondition" resultType="Student">
        select * form student
        <if test="array.length > 0">
            where id in
            <foreach collection="array" item="myid" open="(" close=")" separator=",">
                #{myid}
            </foreach>
        </if>
    </select>
    <!--遍历list-->
    <select id="selectStudentByCondition" resultType="Student">
        select * form student
        <if test="list.size > 0">
            where id in
            <foreach collection="list" item="myid" open="(" close=")" separator=",">
                #{myid}
            </foreach>
        </if>
    </select>
  • bind

sql片段

<sql id="selectColumns">id,name,age,score</sql>
<select id="selectStudentByCondition" resultType="Student">
    select <include refid="selectColumns" /> form student
</select>

关联关系查询

一对多

创建数据表和实体类

country minister
结构 cid、cname mid、mname、countryid
关系

mapper映射文件

<mapper namespace="com.one2many.dao.CountryDao">
    <resultMap id="countryMapper" type="Country">
        <id column="cid" property="cid" />
        <result column="cname" property="cname"/>
        <collection property="ministers" ofType="Minister">
            <id column="mid" property="mid"/>
            <result column="mname" property="mname" />
        </collection>
    </resultMap>
    <select id="selectCountryById" resultMap="countryMapper" parameterType="int">
        SELECT cid,cname,mid,mname FROM country,minister WHERE cid = countryid and cid = #{id}
    </select>
</mapper>

测试类

@Test
public void test01(){
    SqlSession sqlSession = MybatisUtils.sqlSessionFactory();
    CountryDao dao = sqlSession.getMapper(CountryDao.class);
    Country country = dao.selectCountryById(1);
    System.out.println(country.toString());
}

mapper还可以这样写,一个集合的值是从另外一个select语句的结果得到的

<mapper namespace="com.one2many.dao.CountryDao">
    <select id="selectMinisterByCountry" resultType="Minister">
        select mid,mname from minister where countryid = #{xxx}
    </select>
    <resultMap id="countryMapper" type="Country">
        <id column="cid" property="cid" />
        <result column="cname" property="cname"/>
        <collection property="ministers"
                    ofType="Minister"
                    select="selectMinisterByCountry"
                    column="cid"/>
    </resultMap>
    <select id="selectCountryById" resultMap="countryMapper" parameterType="int">
        SELECT cid,cname,mid,mname FROM country,minister WHERE cid = countryid and cid = #{id}
    </select>
</mapper>

多对一

创建数据表和实体类

country minister
结构 cid、cname mid、mname、country
关系

mapper映射文件

<mapper namespace="com.many2one.dao.MinisterDao">
    <resultMap id="ministerMapper" type="Minister">
        <id column="mid" property="mid" />
        <result column="mname" property="mname" />
        <association property="country" javaType="Country">
            <!--property映射成javaType-->
            <id column="cid" property="cid" />
            <result column="cname" property="cname" />
        </association>
    </resultMap>
    <select id="selectMinisterById" resultMap="ministerMapper">
        SELECT MID,mname,cid,cname FROM minister,country
        WHERE countryid = cid AND MID = #{xxx}
    </select>
</mapper>

测试类

@Test
public void test01(){
    SqlSession sqlSession = MybatisUtils.sqlSessionFactory();
    MinisterDao dao = sqlSession.getMapper(MinisterDao.class);
    Minister minister = dao.selectMinisterById(2);
    System.out.println(minister.toString());
}

mapper还可以这样写,一个关联的值是从另外一个select语句的结果得到的

<mapper namespace="com.many2one.dao.MinisterDao">
    <select id="selectCountryById" resultType="Country">
        select cid,cname FROM country where cid=#{xxx}
    </select>
    <resultMap id="ministerMapper" type="Minister">
        <id column="mid" property="mid" />
        <result column="mname" property="mname" />
        <association property="country"
                     javaType="Country"
                     select="selectCountryById" column="countryid">
        </association>
    </resultMap>
    <select id="selectMinisterById" resultMap="ministerMapper">
        SELECT MID,mname,countryid FROM minister WHERE MID = #{xxx}
    </select>
</mapper>

自关联

NewsLabel模型

public class NewsLabel {
    private int id;
    private String name;
    private Set<NewsLabel> children;
    /*省略set、get、toString方法*/
}
<mapper namespace="com.hex.dao.NewsLabelDao">
    <resultMap id="newslabelMapper" type="NewsLabel">
        <id column="id" property="id" />
        <result column="name" property="name"/>
        <collection property="children"
                    ofType="NewsLabel"
                    select="selectChildrenByParent"
                    column="id" />
    </resultMap>
    <select id="selectChildrenByParent" resultMap="newslabelMapper">
        select id,name FROM newslabel where pid=#{xxx}
    </select>
</mapper>
@Test
public void test01(){
    SqlSession sqlSession = MybatisUtils.sqlSessionFactory();
    NewsLabelDao dao = sqlSession.getMapper(NewsLabelDao.class);
    List<NewsLabel> list = dao.selectChildrenByParent(2);
    for (NewsLabel li:list) {
        System.out.println(li.toString());
    }
}

多对多

延迟加载

<settings>
    <setting name="lazyLoadingEnable" value="false" />
    <setting name="aggressiveLazyLoading" value="false" />
</settings>

查询缓存

一级缓存、二级缓存

ehcache

  • 导包

    <dependency>
        <groupId>net.sf.ehcache</groupId>
        <artifactId>ehcache</artifactId>
        <version>2.8.3</version>
    </dependency>
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis-ehcache</artifactId>
        <version>1.0.0</version>
    </dependency>
  • 引入ehcache类
    xml <mapper> <cache type="org.mybatis.caches.ehcache.EhcacheCache" /> </mapper>

  • 导入配置文件

    把ehcache-core里面的配置文件导入项目

Mybatis注解式开发(dao层接口)

  • @Insert(value="")
  • @Delete(value="")
  • @Update(value="")
  • @Select(value="")
<mapper>
    <!--映射文件所在的包-->
    <package name="com.hex.dao" /> 
</mapper>

猜你喜欢

转载自www.cnblogs.com/hextech/p/10657533.html