注:本文内容都来自互联网,通过自己整理用于学习,不作任何其他作用!
使用流程:
1.在maven中导入依赖
Mysql包,mybatis包,junit包
在pom.xml中>配置maven资源过滤文件
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>true</filtering>
</resource>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>true</filtering>
</resource>
</resources>
</build>
2.配置mybatis-config.xml(resources目录下)
<?xml version="1.0" encoding="GBK" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<environments default="default">
<environment id="default">
<transactionManager type="JDBC"></transactionManager>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/mybatis?useSSL=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</dataSource>
</environment>
</environments>
<!-- 每一个mapper.xml都需要先在mybatis-config中注册-->
<mappers>
<mapper resource="com/aruiea/dao/UserMapper.xml" />
</mappers>
</configuration>
3.配置数据库,设计数据库表,创建对应Pojo实体类
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Student {
private int id;
private String name;
private String age;
private String group;
}
4.编写MyBatisUtils类获得SqlSession对象。新建utils包,MyBatisUtils类
public class MyBatisUtils {
private static SqlSessionFactory sqlSessionFactory;
static {
try {
sqlSessionFactory = new SqlSessionFactoryBuilder().build(Resources.getResourceAsStream("mybatis-config.xml"));
} catch (IOException e) {
e.printStackTrace();
}
}
public static SqlSession getSqlSession(){
return sqlSessionFactory.openSession();
}
}
5.编写数据库dao层公用接口Dao以及DaoMapper.xml映射
注意:DaoMapper.xml要在mybatis-config.xml中进行配置!!!
public interface Dao {
// 增
// 删
// 改
// 查全部
// 查一个
List<Student> getAll();
}
特别注意:中文注释不能出现在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.aruiea.dao.Dao">
//namespace要和dao/mapper接口的包名一致,绑定一个对应dao/mapper接口
<select id="getAll" resultType="com.aruiea.pojo.Student">
//id是接口的方法名,resultType:返回结果。
select * from mybatis.student;
</select>
</mapper>
6.测试。在test下,创建DaoMapper.xml相同目录,创建DaoMapperTest
public class DaoMapperTest {
@Test
public void Test(){
SqlSession sqlSession = MyBatisUtils.getSqlSession();
Dao dao = sqlSession.getMapper(Dao.class);
List<Student> studentList = dao.getAll();
for (Student stu:studentList){
System.out.println(stu);
}
sqlSession.close();
}
}
其他功能:
1.通过id查询
<select id="getById" parameterType="int" resultType="com.aruiea.pojo.Student" >
select * from mybatis.student where id = #{id};
</select>
@Test
public void getById(){
SqlSession sqlSession = MyBatisUtils.getSqlSession();
Dao dao = sqlSession.getMapper(Dao.class);
Student student = dao.getById(1);
System.out.println(student);
sqlSession.close();
}
2.插入数据
<insert id="insertStudent" parameterType="com.aruiea.pojo.Student">
insert into mybatis.student values(#{id},#{name},#{age},#{group});
</insert>
注意:增删改一定要提交事务才生效!!!!
@Test
public void insertStudent(){
SqlSession sqlSession = MyBatisUtils.getSqlSession();
Dao dao = sqlSession.getMapper(Dao.class);
int result = dao.insertStudent(new Student(4,"Flower",200,"魔法学院"));
// 提交事务
sqlSession.commit();
if(result > 0 ){
System.out.println("插入成功");
}
sqlSession.close();
}
3.更新数据
<update id="updateStudent" parameterType="com.aruiea.pojo.Student" >
UPDATE student SET name=#{name},age=#{age},`group`=#{group} WHERE id=#{id};
</update>
@Test
public void updateStudent(){
SqlSession sqlSession = MyBatisUtils.getSqlSession();
Dao dao = sqlSession.getMapper(Dao.class);
int result = dao.updateStudent(new Student(4,"Flow",100,"wtf"));
// 提交事务
sqlSession.commit();
if(result > 0 ){
System.out.println("成功!!!");
}
sqlSession.close();
}
4.删除数据
<delete id="deleteStudent" parameterType="int">
delete from mybatis.student where id=#{id};
</delete>
@Test
public void updateStudent(){
SqlSession sqlSession = MyBatisUtils.getSqlSession();
Dao dao = sqlSession.getMapper(Dao.class);
int result = dao.deleteStudent(2);
// 提交事务
sqlSession.commit();
if(result > 0 ){
System.out.println("成功!!!");
}
sqlSession.close();
}
使用Map传参:(一般用于表字段多的时候,或者名字不确定的时候)
<select id="getStudent" parameterType="map" resultType="com.aruiea.pojo.Student">
select * from mybatis.student where id=#{id} and name=#{name}
</select>
// 通过多个参数调用方法
List<Student> getStudent(Map<String,Object> map);
@Test
public void getStudent(){
SqlSession sqlSession = MyBatisUtils.getSqlSession();
Dao dao = sqlSession.getMapper(Dao.class);
Map<String,Object> map = new HashMap<String,Object>();
map.put("id",1);
map.put("name","Aruiea");
List<Student> list = dao.getStudent(map);
for (Student stu:list){
System.out.println(stu);
}
sqlSession.close();
}
模糊查询:
直接在java传参时加入通配符%value%
// 模糊查询
List<Student> getStudentLike(String name);
<select id="getStudentLike" parameterType="String" resultType="com.aruiea.pojo.Student">
select * from mybatis.student where name like #{name}
</select>
@Test
public void getStudentLike(){
SqlSession sqlSession = MyBatisUtils.getSqlSession();
Dao dao = sqlSession.getMapper(Dao.class);
List<Student> list = dao.getStudentLike("%o%");
for (Student stu:list){
System.out.println(stu);
}
sqlSession.close();
}
MyBatis配置
使用properties配置数据库连接
//在resources中新建db.properties。 String=value
driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/mybatis?useSSL=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC
username=root
password=123456
<!-- 引入外部文件,用${String}引入值-->
<properties resource="db.properties"/>
<environments default="default">
<environment id="default">
<transactionManager type="JDBC"></transactionManager>
<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>
给一个类设置别名:
<!-- xml配置中,每个标签都有顺序-->
<typeAliases>
<typeAlias type="com.aruiea.pojo.Student" alias="stu"></typeAlias>
</typeAliases>
<select id="getAll" resultType="stu">
select * from mybatis.student;
</select>
指定一个包,扫描下面所有类名小写的名字,如果有注解,为注解名
<!-- xml配置中,每个标签都有顺序-->
<typeAliases>
<typeAlias type="com.aruiea.pojo.Student" alias="stu"></typeAlias>
//配置包名,扫描包下所有的bean,默认小写名称对应
<package name="com.aruiea.pojo"/>
</typeAliases>
<select id="getById" parameterType="int" resultType="student" >
select * from mybatis.student where id = #{id};
</select>
注解:
@Alias("al")
public class Student {
<select id="getAll" resultType="al">
select * from mybatis.student;
</select>
拷贝过来的项目,实体类和数据库字段不一致,取不出数据的问题
//数据库中的字段
public class Student {
private int id;
private String name;
private int age;
private String group;
}
//拷贝过来的pojo
public class Student {
private int id;
private String name;
private int age;
private String banji;
}
//查询到的代码
Student(id=1, name=Aruiea, age=27, banji=null)
Student(id=3, name=Loader, age=40, banji=null)
Student(id=4, name=Flow, age=100, banji=null)
类型处理器把pojo实体类映射处理成这样:
select id,name,age,banji from student;
所以出错,查不到banji,所以都为Null
解决办法:起别名
<select id="getAll" resultType="al">
select id,name,age,`group` as banji from mybatis.student;
</select>
解决方法:resultMap结果集映射
<!-- 结果集映射 id:标识名 type:映射到的类类型-->
<resultMap id="resMap" type="com.aruiea.pojo.Student">
<!-- column:数据库列名 property:实体类属性名-->
<result column="id" property="id"></result>
<result column="name" property="name"></result>
<result column="age" property="age"></result>
<result column="group" property="banji"></result>
</resultMap>
<!-- 返回结果resultMap="标识名"-->
<select id="getAll" resultMap="resMap">
select * from mybatis.student;
</select>
Mybatis中数据库操作出现异常:日志!
//在pom.xml导入依赖
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
//在resource目录下新建log4j.properties.并写上一下内容
#将等级为DEBUG的日志信息输出到console和file这两个目的地,console 和file的定义在下面的代码
log4j.rootLogger=DEBUG, console, file
log4j.rootLogger=INFO,CONSOLE
log4j.addivity.org.apache=true
# console
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.Threshold=INFO
log4j.appender.CONSOLE.Target=System.out
log4j.appender.CONSOLE.Encoding=UTF-8
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=[demo] %-5p %d{yyyy-MM-dd HH\:mm\:ss} - %C.%M(%L)[%t] - %m%n
# all
log4j.logger.com.demo=INFO, DEMO
log4j.appender.DEMO=org.apache.log4j.RollingFileAppender
log4j.appender.DEMO.File=${catalina.base}/logs/demo.log
log4j.appender.DEMO.MaxFileSize=50MB
log4j.appender.DEMO.MaxBackupIndex=3
log4j.appender.DEMO.Encoding=UTF-8
log4j.appender.DEMO.layout=org.apache.log4j.PatternLayout
//在mybatis-config.xml中配置日志实现
<settings>
<!-- <setting name="logImpl" value="STDOUT_LOGGING"/>-->
<setting name="logImpl" value="LOG4J"/>
</settings>
//简单使用:
@Test
public void Test(){
// 使用
logger.info("info:进入了Test方法");
logger.debug("debug:进入了Test方法");
logger.error("error:进入了Test方法");
SqlSession sqlSession = MyBatisUtils.getSqlSession();
Dao dao = sqlSession.getMapper(Dao.class);
List<Student> studentList = dao.getAll();
for (Student stu:studentList){
System.out.println(stu);
}
sqlSession.close();
}
输出结果:
"D:\Program Files\Java\jdk1.8\bin\java.exe" -ea -Didea.test.cyclic.buffer.size=1048576 "-javaagent:D:\Program Files\JetBrains\IntelliJ IDEA 2019.3.5\lib\idea_rt.jar=64486:D:\Program Files\JetBrains\IntelliJ IDEA 2019.3.5\bin" -Dfile.encoding=UTF-8 -classpath "D:\Program Files\JetBrains\IntelliJ IDEA 2019.3.5\lib\idea_rt.jar;D:\Program Files\JetBrains\IntelliJ IDEA 2019.3.5\plugins\junit\lib\junit5-rt.jar;D:\Program Files\JetBrains\IntelliJ IDEA 2019.3.5\plugins\junit\lib\junit-rt.jar;D:\Program Files\Java\jdk1.8\jre\lib\charsets.jar;D:\Program Files\Java\jdk1.8\jre\lib\deploy.jar;D:\Program Files\Java\jdk1.8\jre\lib\ext\access-bridge-64.jar;D:\Program Files\Java\jdk1.8\jre\lib\ext\cldrdata.jar;D:\Program Files\Java\jdk1.8\jre\lib\ext\dnsns.jar;D:\Program Files\Java\jdk1.8\jre\lib\ext\jaccess.jar;D:\Program Files\Java\jdk1.8\jre\lib\ext\jfxrt.jar;D:\Program Files\Java\jdk1.8\jre\lib\ext\localedata.jar;D:\Program Files\Java\jdk1.8\jre\lib\ext\nashorn.jar;D:\Program Files\Java\jdk1.8\jre\lib\ext\sunec.jar;D:\Program Files\Java\jdk1.8\jre\lib\ext\sunjce_provider.jar;D:\Program Files\Java\jdk1.8\jre\lib\ext\sunmscapi.jar;D:\Program Files\Java\jdk1.8\jre\lib\ext\sunpkcs11.jar;D:\Program Files\Java\jdk1.8\jre\lib\ext\zipfs.jar;D:\Program Files\Java\jdk1.8\jre\lib\javaws.jar;D:\Program Files\Java\jdk1.8\jre\lib\jce.jar;D:\Program Files\Java\jdk1.8\jre\lib\jfr.jar;D:\Program Files\Java\jdk1.8\jre\lib\jfxswt.jar;D:\Program Files\Java\jdk1.8\jre\lib\jsse.jar;D:\Program Files\Java\jdk1.8\jre\lib\management-agent.jar;D:\Program Files\Java\jdk1.8\jre\lib\plugin.jar;D:\Program Files\Java\jdk1.8\jre\lib\resources.jar;D:\Program Files\Java\jdk1.8\jre\lib\rt.jar;D:\Program Files\JetBrains\MyBatisProject\MyBatisPractice2\target\test-classes;D:\Program Files\JetBrains\MyBatisProject\MyBatisPractice2\target\classes;D:\Programe\apache-maven-3.6.0\maven-repo\mysql\mysql-connector-java\8.0.19\mysql-connector-java-8.0.19.jar;D:\Programe\apache-maven-3.6.0\maven-repo\com\google\protobuf\protobuf-java\3.6.1\protobuf-java-3.6.1.jar;D:\Programe\apache-maven-3.6.0\maven-repo\org\mybatis\mybatis\3.5.4\mybatis-3.5.4.jar;D:\Programe\apache-maven-3.6.0\maven-repo\log4j\log4j\1.2.17\log4j-1.2.17.jar;D:\Programe\apache-maven-3.6.0\maven-repo\org\projectlombok\lombok\1.18.12\lombok-1.18.12.jar;D:\Programe\apache-maven-3.6.0\maven-repo\junit\junit\4.13\junit-4.13.jar;D:\Programe\apache-maven-3.6.0\maven-repo\org\hamcrest\hamcrest-core\1.3\hamcrest-core-1.3.jar" com.intellij.rt.junit.JUnitStarter -ideVersion5 -junit4 com.aruiea.dao.DaoMapperTest,Test
[demo] INFO 2020-06-06 22:11:24 - com.aruiea.dao.DaoMapperTest.Test(30)[main] - info:进入了Test方法
[demo] ERROR 2020-06-06 22:11:24 - com.aruiea.dao.DaoMapperTest.Test(32)[main] - error:进入了Test方法
Student(id=1, name=Aruiea, age=27, banji=三年二班)
Student(id=3, name=Loader, age=40, banji=教导处)
Student(id=4, name=Flow, age=100, banji=wtf)
分页查询实现
1.Dao.class中增加方法getStudentLimit();
// 分页查询
List<Student> getStudentLimit(Map map);
2.DaoMapper.xml中配置文件
<!-- 分页查询-->
<select id="getStudentLimit" parameterType="Map" resultType="com.aruiea.pojo.Student">
select * from mybatis.student limit #{startIndex},#{pageSize};
</select>
3.使用sqlSession测试。
@Test
public void getStduentLimit(){
SqlSession sqlSession =MyBatisUtils.getSqlSession();
Dao dao = sqlSession.getMapper(Dao.class);
HashMap<String,Object> map = new HashMap<String,Object>();
map.put("startIndex",0);
map.put("pageSize",5);
List<Student> studentLimit = dao.getStudentLimit(map);
for (Student student : studentLimit) {
System.out.println(student);
}
sqlSession.close();
}
使用注解开发
1.在接口上加注解
// 查全部
@Select("select * from mybatis.student;")
List<Student> getAll();
// 通过id查询,有参数要加上@Param
@Select("select * from mybatis.student where id=#{id}")
Student getById(@Param("id") int id);
2.在mybatis中注册类
<!-- 注解开发接口需要先在mybatis-config中注册-->
<mappers>
<mapper class="com.aruiea.dao.Dao" />
</mappers>
3.测试
@Test
public void Test(){
SqlSession sqlSession = MyBatisUtils.getSqlSession();
Dao dao = sqlSession.getMapper(Dao.class);
List<Student> studentList = dao.getAll();
for (Student stu:studentList){
System.out.println(stu);
}
sqlSession.close();
}
增删改/注解
1.创建sqlSession的时候设置自动提交。
public static SqlSession getSqlSession(){
return sqlSessionFactory.openSession(true);
}
2.在接口上添加注解
// 增
@Insert("insert into student values(#{id},#{name},#{age},#{banji})")
int insertStudent(Student student);
// 删
@Delete("delete from student where id=#{id}")
int deleteStudent(int id);
// 改
@Update("update student set name=#{name},age=#{age},`group`=#{banji} where id=#{id}")
int updateStudent(Student student);
3.测试。
@Test
public void delTest(){
SqlSession sqlSession= MyBatisUtils.getSqlSession();
Dao mapper = sqlSession.getMapper(Dao.class);
mapper.getAll();
mapper.getById(2);
mapper.deleteStudent(19);
sqlSession.close();
}
MyBatis执行流程
1.Resources:获取加载全局配置
2.创建SqlSessionFactoryBuilder().build(Resources.getResourceAsStream(MyBatis.xml));
3.解析文件流XMLconfigBuilder,Configuration所有的配置信息。
4.实例化SqlSessionFactory
5.executor执行器执行
6.创建SqlSession
7.实现CRUD,transcation事务管理
多对一处理
使用子查询
1.搭建数据库表
USE mybatis
;
CREATE TABLE `teacher`(
`id` INT(10) NOT NULL,
`name` VARCHAR(30) DEFAULT NULL,
PRIMARY KEY(`id`)
)ENGINE=INNODB DEFAULT CHARSET=utf8
INSERT INTO teacher(`id`,`name`) VALUES(1,'Aruiea');
INSERT INTO teacher(`id`,`name`) VALUES(2,'Gaoslin');
DROP TABLE student
CREATE TABLE `student2`(
`id` INT(10) NOT NULL,
`name` VARCHAR(30) DEFAULT NULL,
`tid` INT(10) DEFAULT NULL,
PRIMARY KEY(`id`),
KEY `fktid` (`tid`),
CONSTRAINT `fktid` FOREIGN KEY (`tid`) REFERENCES `teacher`(`id`)
)ENGINE=INNODB DEFAULT CHARSET=utf8
INSERT INTO `student2` VALUES(1,'小红',1),(2,'小明',1);
INSERT INTO `student2` VALUES(3,'小黑',1),(4,'小刚',1),(5,'小紫',1),(6,'小绿',1);
INSERT INTO `student2` VALUES(7,'小黑',2),(8,'小刚',2),(9,'小紫',2),(10,'小绿',2);
2.编写代码
准备工作:
1.pojo学生Student2和Teacher类
2.dao层Student2Mapper和TeacherMapper接口
3.resources目录下Student2Mapper.xml和TeacherMapper.xml
4.在mybatis-config中配置
注:纯注解开发不需要xml,配置时直接指定class
public class Student2 {
private int id;
private String name;
private Teacher teacher;
}
public class Teacher {
private int id;
private String name;
}
<?xml version="1.0" encoding="GBK" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.aruiea.dao.TeacherMapper">
</mapper>
<!-- 每一个mapper.xml都需要先在mybatis-config中注册-->
<mappers>
<mapper class="com.aruiea.dao.TeacherMapper"/>
<mapper class="com.aruiea.dao.Student2Mapper"/>
</mappers>
查询Student2的所有数据(外键tid=teacher.id)多对一
1.写接口
// 查询所有学生以及对应老师的信息
List<Student2> getList();
// 得到老师的信息
Teacher getTeacher(int id);
2.配置Mapper.xml
<mapper namespace="com.aruiea.dao.Student2Mapper">
<select id="getList" resultMap="Student2Teacher">
select * from student2;
</select>
<!--用结果集映射,对student2的结果进行映射-->
<resultMap id="Student2Teacher" type="com.aruiea.pojo.Student2">
<result property="id" column="id" />
<result property="name" column="name" />
<!-- 单独处理复杂属性,把student属性teacher对应到数据库tid列。-->
<!-- 声明java类型Teacher,结果为getTeacher方法返回的类型Teacher-->
<association property="teacher" column="tid" javaType="Teacher" select="getTeacher" />
</resultMap>
<select id="getTeacher" resultType="com.aruiea.pojo.Teacher">
select * from teacher where id=#{id};
</select>
</mapper>
4.测试,输出结果正确!
联表查询
<!-- 联表查询-->
<select id="getList" resultMap="Student2Teacher">
select s2.id s2id,s2.name s2name,t.name tname,s2.tid s2tid
from student2 s2,teacher t
where s2.tid=t.id;
</select>
<resultMap id="Student2Teacher" type="com.aruiea.pojo.Student2">
<result property="id" column="s2id" />
<result property="name" column="s2name" />
<!-- 以下映射的column都是Student2中查询出来的数据,没查出来则没有-->
<association property="teacher" javaType="com.aruiea.pojo.Teacher">
<result property="id" column="s2tid" />
<result property="name" column="tname" />
</association>
</resultMap>
一对多
子查询方式代码
1.写Mapper接口
// 获得所有老师对象
List<Teacher> getTeacher(int id);
// 获得指定学生对象
Student2 getStudentById(int id);
2.编写Mapper.xml
注:没有解决子查询时,传参的问题。
<!-- 直接查询处所有的Teacher-->
<select id="getTeacher" resultMap="TeacherStudent2">
select * from teacher where id = #{tid};
</select>
<!-- 在结果集映射中进行子查询-->
<resultMap id="TeacherStudent2" type="Teacher">
<!-- 把teacher中的属性students映射到student2类上(ofType)-->
<!-- 调用select方法,用column传参-->
<collection property="students" javaType="ArrayList" ofType="student2" select="getStudentById" column="id"/>
</resultMap>
<!-- 要查询的student2方法-->
<select id="getStudentById" resultType="student2">
select * from student2 where tid=#{tid};
</select>
3.测试。id传参有误,其他正常!
联表查询代码示范
1.写Mapper接口
// 获得所有老师对象
List<Teacher> getTeacher(int id);
2.编写Mapper.xml
<mapper namespace="com.aruiea.dao.TeacherMapper">
<!-- 所有要显示的数据都要先查询-->
<select id="getTeacher" resultMap="TeacherStudent2">
select s.id sid,s.name sname,t.name tname,t.id tid
from student2 s,teacher t
where s.tid=t.id and t.id=#{tid}
</select>
<resultMap id="TeacherStudent2" type="com.aruiea.pojo.Teacher">
<result property="id" column="tid"/>
<result property="name" column="tname"/>
<!-- association是对应一个对象(多对一),collection对应一个集合(一对多)-->
<!-- ofType表明students属性归属的类,属于java代码-->
<collection property="students" ofType="Student2">
<!-- 这底下都是Student2类属性对应的数据库列,可以随便写-->
<result property="id" column="sid"/>
<result property="name" column="sname"/>
<result property="tid" column="tid"/>
</collection>
</resultMap>
</mapper>
3.测试,成功。
@Test
public void getTeacher(){
SqlSession sqlSession = MyBatisUtils.getSqlSession();
TeacherMapper mapper = sqlSession.getMapper(TeacherMapper.class);
List<Teacher> teacher = mapper.getTeacher(1);
for (Teacher teacher1 : teacher) {
System.out.println(teacher1);
}
sqlSession.close();
}
动态SQL
1.准备工作:创建MyBatis类,创建pojo类,dao层接口和xml,工具类MyBatis和UUID(返回随机网络标识符)配置mybatis,把xml配置到mybatis中。
<?xml version="1.0" encoding="GBK" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!-- 引入外部文件-->
<properties resource="db.properties"/>
<settings>
<!--<!– <setting name="logImpl" value="STDOUT_LOGGING"/>–>-->
<!-- <setting name="logImpl" value="LOG4J"/>-->
<!-- 开启驼峰命名自动转换,把类似createtime映射到数据库create_time-->
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
<typeAliases>
<package name="com.aruiea.pojo"/>
</typeAliases>
<environments default="default">
<environment id="default">
<transactionManager type="JDBC"></transactionManager>
<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>
<!-- 每一个mapper.xml都需要先在mybatis-config中注册-->
<mappers>
<mapper class="com.aruiea.dao.BlogMapper"/>
</mappers>
</configuration>
public class MyBatisUtils {
private static SqlSessionFactory sqlSessionFactory;
static {
try {
sqlSessionFactory = new SqlSessionFactoryBuilder().build(Resources.getResourceAsStream("mybatis-config.xml"));
} catch (IOException e) {
e.printStackTrace();
}
}
public static SqlSession getSqlSession(){
return sqlSessionFactory.openSession(true);
}
}
public class Blog {
private String id;
private String title;
private String author;
private Date create_time;
private int views;
}
public interface BlogMapper {
// 插入数据
int addBlog(Blog blog);
}
<?xml version="1.0" encoding="GBK" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.aruiea.dao.BlogMapper">
<insert id="addBlog" parameterType="blog">
insert into mybatis.blog values(#{id},#{title},#{author},#{create_time},#{views});
</insert>
</mapper>
public class IDUtils {
public static String getId(){
// 利用UUID工具类创建随机UID,把里面所有的-删除掉
return UUID.randomUUID().toString().replaceAll("-","");
}
}
2.测试insert方法,成功。
@Test
public void aTest(){
SqlSession sqlSession = MyBatisUtils.getSqlSession();
BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);
Blog blog = new Blog();
blog.setId(IDUtils.getId());
blog.setTitle("极寒之地");
blog.setAuthor("Aruiea");
blog.setCreate_time(new Date());
blog.setViews(999);
sqlSession.commit();
mapper.addBlog(blog);
sqlSession.close();
}
}
动态SQL:IF,trim(where,set) choose(when,otherwise) foreach
动态sql之IF
接口中增加方法。
// 查询博客
List<Blog> queryBlogIF(Map map);
Mapper.xml中配置IF
<!-- 动态sql的if语句-->
<select id="queryBlogIF" parameterType="Map" resultType="blog">
select * from blog where 1=1
-- test中写表达式:如果title属性不为空,把语句拼接到select后面
<if test="title!=null">
and title=#{title}
</if>
<if test="author">
and author=#{author}
</if>
</select>
或者这么写:
<!-- 动态sql的if语句-->
<select id="queryBlogIF" parameterType="Map" resultType="blog">
select * from blog
-- test中写表达式:如果title属性不为空,把语句拼接到select后面
<!-- where元素只有在有SQL子句的情况下才生效,并且只能去掉前面的and或者or-->
<where>
<if test="title!=null">
and title=#{title}
</if>
<if test="author">
and author=#{author}
</if>
</where>
</select>
测试。
@Test
public void a2Test(){
SqlSession sqlSession = MyBatisUtils.getSqlSession();
BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);
HashMap<String,Object> map = new HashMap<String,Object>();
// map.put("title","极寒之地");
// map.put("author","Aruiea");
List<Blog> blogs = mapper.queryBlogIF(map);
System.out.println(blogs);
sqlSession.commit();
sqlSession.close();
}
动态SQL之Choose
// 查询博客,通过选择choose(类似java的switch)
List<Blog> queryBlogChoose(Map map);
<!-- where元素只有在有SQL子句的情况下才生效,并且只能去掉前面的and或者or-->
<select id="queryBlogChoose" parameterType="Map" resultType="blog">
select * from blog
<where>
-- 此处运行时需要删除!!!类似于java的switch,从下面选一个,otherwise是默认的
<choose>
<when test="title!=null">title=#{title}</when>
<when test="author!=null">and author=#{author}</when>
<otherwise>
and views=#{views}
</otherwise>
</choose>
</where>
</select>
测试。
@Test
public void a3Test(){
SqlSession sqlSession = MyBatisUtils.getSqlSession();
BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);
HashMap<String,Object> map = new HashMap<String,Object>();
// map.put("title","极寒之地");
// map.put("author","Aruiea");
map.put("views",999);
List<Blog> blogs = mapper.queryBlogChoose(map);
System.out.println(blogs);
sqlSession.commit();
sqlSession.close();
}
动态SQL之set
接口方法
// 更新博客
int updateBlog(Map map);
xml配置文件
<!-- 使用update/set更新-->
<update id="updateBlog" parameterType="Map">
update mybatis.blog
<set>
<if test="title != null">
title=#{title},
</if>
<if test="author != null">
author=#{author}
</if>
</set>
where id=#{id}
</update>
动态SQL之SQL片段
xml中定义公用SQL,INCLUDE引用,所有地方都能用
<sql id="commonSql">
<if test="title!=null">
and title=#{title}
</if>
<if test="author">
and author=#{author}
</if>
</sql>
<!-- 动态sql的if语句-->
<select id="queryBlogIF" parameterType="Map" resultType="blog">
select * from blog
<!--运行时需要删除此行!!! test中写表达式:如果title属性不为空,把语句拼接到select后面-->
<!-- where元素只有在有SQL子句的情况下才生效,并且只能去掉前面的and或者or-->
<where>
<!--运行时需要删除此行!!! 用include引入公用的sql语句-->
<include refid="commonSql"></include>
</where>
</select>
动态SQL之FOREACH
对一个集合进行操作,通常在用IN的时候
xml代码
<!-- 用Foreach实现select * from blog where 1=1 and (id=1 or id=2 or id=3);-->
<select id="queryBlogForeach" parameterType="Map" resultType="blog">
select * from blog
<where>
-- 注意拼接时的空格,否则会语法错误
<foreach collection="ids" item="id" open=" and (" close=" )" separator=" or ">
id=#{id}
</foreach>
</where>
</select>
测试
@Test
public void a5Test(){
SqlSession sqlSession = MyBatisUtils.getSqlSession();
BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);
HashMap<String,Object> map = new HashMap<String,Object>();
ArrayList<Integer> ids = new ArrayList<Integer>();
ids.add(1);
ids.add(2);
map.put("ids",ids);
List<Blog> blogs = mapper.queryBlogForeach(map);
for (Blog blog : blogs) {
System.out.println(blog);
}
sqlSession.close();
}
MyBatis缓存
二级缓存:也叫全局缓存,一级缓存作用域太低,所以诞生了二级缓存。
基于一个namespace的缓存,一个命名空间,对应一个二级缓存。
*一个会话查询一条数据,这个数据会被放在当前对象的一级缓存中。
*会话关闭sqlsession关闭,对应的一级缓存就没有了。这时候需要二级缓存。
二级缓存的使用:
1.mybtis-config.xml中开启
<settings>
<!-- 显示开启全局缓存-->
<setting name="cacheEnabled" value="true"/>
</settings>
2.在当前xml使用二级缓存
<!--在当前mapper中开启二级缓存 eviction:收回 最多512个缓存 刷新时间60s-->
<cache eviction="FIFO"
flushInterval="60000"
size="512"
readOnly="true"
/>
<select id="getAll" resultType="blog" useCache="true">
select * from blog;
</select>
*只要开启了二级缓存,在同一个Mapper下就有效
*所有数据都会先放在一级缓存中
*只有当会话提交/关闭的时候,才会提交到二级缓存中。