SSM学习Mybatis
Posted hextech
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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配置
srcmain esourceslog4j.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配置文件
srcmain esourcesjdbc.properties
jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/test?serverTimezone=GMT%2B8
jdbc.name=root
jdbc.password=123456
主配置文件
srcmain esourcesmybatis-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映射文件
srcmain esourcesmapper.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
原符号 | < | <= | > | >= | & | ‘ | " |
---|---|---|---|---|---|---|---|
替换符号 | < |
<= |
> |
>= |
& |
' |
" |
if
<select id="selectStudentByCondition" resultType="Student"> select * form student <where> <if test="name != null and name != ''"> and name like '%' #{name} '%' </if> <if test="age > 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 > 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>
以上是关于SSM学习Mybatis的主要内容,如果未能解决你的问题,请参考以下文章
SSM(Spring+SpringMVC+Mybatis)框架搭建详细教程附源代码Demo
SSM(Spring,SpringMVC,Mybatis)学习路线(从0开始,仅仅是路线)