三:Mybatis
三.MyBatis
主流的ORM 支持java .NET Ruby三种语言,MyBatis是对JDBC的封装
ORM框架Hibernate
区别:
1)sql 优化方面
- Hibernate 使用 HQL(Hibernate Query Language)语句,独立于数据库。不需要编写大量的 SQL,就可以完全映射,但会多消耗性能,且开发人员不能自主的进行 SQL 性能优化。提供了日志、缓存、级联(级联比 MyBatis 强大)等特性。
- MyBatis 需要手动编写 SQL,所以灵活多变。支持动态 SQL、处理列表、动态生成表名、支持存储过程。工作量相对较大。
2)开发方面
MyBatis 是一个半自动映射的框架,因为 MyBatis 需要手动匹配 POJO 和 SQL 的映射关系。
Hibernate 是一个全表映射的框架,只需提供 POJO 和映射关系即可。
3)缓存机制比较
Hibernate 的二级缓存配置在 SessionFactory 生成的配置文件中进行详细配置,然后再在具体的表-对象映射中配置缓存。
MyBatis 的二级缓存配置在每个具体的表-对象映射中进行详细配置,这样针对不同的表可以自定义不同的缓存机制。并且 Mybatis 可以在命名空间中共享相同的缓存配置和实例,通过 Cache-ref 来实现。
Hibernate 对查询对象有着良好的管理机制,用户无需关心 SQL。所以在使用二级缓存时如果出现脏数据,系统会报出错误并提示。
而 MyBatis 在这一方面,使用二级缓存时需要特别小心。如果不能完全确定数据更新操作的波及范围,避免 Cache 的盲目使用。否则脏数据的出现会给系统的正常运行带来很大的隐患。
4)Hibernate 优势
Hibernate 的 DAO 层开发比 MyBatis 简单,Mybatis 需要维护 SQL 和结果映射。
Hibernate 对对象的维护和缓存要比 MyBatis 好,对增删改查的对象的维护要方便。
Hibernate 数据库移植性很好,MyBatis 的数据库移植性不好,不同的数据库需要写不同 SQL。
Hibernate 有更好的二级缓存机制,可以使用第三方缓存。MyBatis 本身提供的缓存机制不佳。
5)Mybatis优势
- MyBatis 可以进行更为细致的 SQL 优化,可以减少查询字段。
- MyBatis 容易掌握,而 Hibernate 门槛较高。
6)应用场景
MyBatis 适合需求多变的互联网项目,例如电商项目、金融类型、旅游类、售票类项目等。
Hibernate 适合需求明确、业务固定的项目,例如 OA 项目、ERP 项目和 CRM 项目等。
总结:
总的来说,MyBatis 是一个小巧、方便、高效、简单、直接、半自动化的持久层框架,Hibernate 是一个强大、方便、高效、复杂、间接、全自动化的持久层框架。
开发
1.配置pom.xml
<dependencies>
<!-- mybatis-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.5</version>
</dependency>
<!-- mysql驱动-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.19</version>
</dependency>
<!-- lombok-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.10</version>
</dependency>
</dependencies>
<build>
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
</resource>
</resources>
</build>
2.实体类:
package com.shouthwind.entity;
import lombok.Data;
@Data
public class People {
private Integer Sno;
private String Sname;
private String Ssex;
private Integer Sage;
private String Sdept;
}
3.配置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>
<!-- 配置mybatis运行环境 -->
<environments default="development">
<environment id="development">
<!-- 使用JDBC的事务管理 -->
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<!-- MySQL数据库驱动 -->
<property value="com.mysql.cj.jdbc.Driver" name="driver"/>
<!-- 连接数据库的URL -->
<property value="jdbc:mysql://localhost:3306/text?serverTimezone=UTC&useUnicode=true&characterEncoding=utf8" name="url"/>
<property value="root" name="username"/>
<property value="123456" name="password"/>
</dataSource>
</environment>
</environments>
<!-- 将mapper文件加入到配置文件中 -->
<mappers>
<mapper resource="com/shouthwind/Mapper/PeopleMapper.xml"/>
</mappers>
</configuration>
4.Mabytatis开发:
原生接口
Mapper代理实现自定义接口
一:原生接口开发:
1.Mapper文件
<?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.shouthwind.Mapper.PeopleMapper">
<select id="finBySno" parameterType="java.lang.Integer" resultType="com.shouthwind.entity.People">
select *from student where Sno=#{Sno}
</select>
</mapper>2.config.xml注册
-<mappers>
<mapper resource="com/shouthwind/Mapper/PeopleMapper.xml"/>
</mappers>3.测试类:
package com.shouthwind.Test;
import com.shouthwind.entity.People;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import java.io.InputStream;
public class Test {
public static void main(String[] args) {
//加载配置文件
InputStream inputStream =Test.class.getClassLoader().getResourceAsStream("config.xml");
SqlSessionFactoryBuilder sqlSessionFactoryBuilder =new SqlSessionFactoryBuilder();
SqlSessionFactory sqlSessionFactory= sqlSessionFactoryBuilder.build(inputStream);
//获得sqlSession对象
SqlSession sqlSession =sqlSessionFactory.openSession();
//调用mybatis的原生接口
String statement ="com.shouthwind.Mapper.PeopleMapper.finBySno";
People people =sqlSession.selectOne(statement,1);
System.out.println(people);
sqlSession.close();
}
}
二.Mapper自定义的代理接口
开发者只需要定义接口不需要实现,具体的实现由Mapper代理实现
1.自定义接口
package com.shouthwind.repository;
import com.shouthwind.entity.People;
import java.util.List;
public interface UserRepository {
public int save(People people);
public int deleteById(Integer Sno);
public int update(People people);
public People findById(Integer Sno);
public List<People> findAll();
}
2.创建peopleMappertaining.xml
更据规则:
- peopleMappertaining.xml中的namepsce为接口的全限定类目(带着包名的类名)
- peopleMappertaining.xml中的statement的id必须接口中的方法名一致
- peopleMappertaining.xml中的paramType和接口的对应方法的参数类型一致
- peopleMappertaining.xml中的resultType和接口中的对应方法的返回值一致
1.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.shouthwind.repository.UserRepository">
<insert id="save" parameterType="com.shouthwind.entity.People">
insert into people(name,money) values(#{name},#{money})
</insert>
<delete id="deleteById" parameterType="java.lang.Integer">
delete from people where id=#{id}
</delete>
<update id="update" parameterType="com.shouthwind.entity.People">
update people set name=#{name} ,money=#{money} where id=#{id}
</update>
<select id="findById" parameterType="java.lang.Integer" resultType="com.shouthwind.entity.People">
select *from people where id=#{id}
</select>
<select id="findAll" resultType="com.shouthwind.entity.People">
select *from people
</select>
</mapper>
2.接口:
package com.shouthwind.repository;
import com.shouthwind.entity.People;
import java.util.List;
public interface UserRepository {
public int save(People people);
public int deleteById(Integer id);
public int update(People people);
public People findById(Integer id);
public List<People> findAll();
}
3.测试类
package com.shouthwind.Test;
import com.shouthwind.entity.People;
import com.shouthwind.repository.UserRepository;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import java.io.InputStream;
public class Test2 {
public static void main(String[] args) {
InputStream inputStream =Test2.class.getClassLoader().getResourceAsStream("config.xml");
SqlSessionFactoryBuilder sqlSessionFactoryBuilder= new SqlSessionFactoryBuilder();
SqlSessionFactory sqlSessionFactory =sqlSessionFactoryBuilder.build(inputStream);
SqlSession sqlSession=sqlSessionFactory.openSession();
//获取实现了自定义代理接口的对象
UserRepository userRepository=sqlSession.getMapper(UserRepository.class);
// 添加、修改、删除、查询
People people =new People();
people.setId(1);
people.setName("小王");
people.setMoney(999);
// int row=userRepository.save(people);
int row =userRepository.update(people);
System.out.println(row);
// People people=userRepository.findById(1);
// System.out.println(people);
//提交事物
sqlSession.commit();
sqlSession.close();
}
}
Mapper.xml常用配置
全局配置文件(数据库,事物管理,Mapper的注册、打印文件SQL、慢性加载、二级缓存)
Mapper配置文件 (定义自定义接口的具体方案;SQL、数据库、数据库与POJO的映射)
多表关联查询:
一对一,一对多、多对多
单表查询:<select id="findById" parameterType="java.lang.Integer" resultType="com.shouthwind.entity.People">
select *from people where id=#{id}
</select>业务:通过id查询people对象
目标表:test/people
实体类:com.souththwind.entity.Peaple
Mapper.xml设置相关的配置,由Mybatis自动完成查询,生成POJO
statement标签的主要属性由:id、parameterType\resultType
id:对应接口的方法名;parameterType对应定义的参数类型;resultType定义查询的结果的数据类型(要一致)
parameterType
支持基本的数据类型、包装类、String、多参数、POJO
1.基本数据类型:
public People findById(int id);
<select id="findById2" parameterType="int" resultType="com.shouthwind.entity.People">
select *from people where id=#{id}
</select>
2.包装类:
public People findById(Integer id);
<select id="findById" parameterType="java.lang.Integer" resultType="com.shouthwind.entity.People">
select *from people where id=#{id}
</select>
3.String:
public People findByName(String name);
<select id="findByName" parameterType="java.lang.String" resultType="com.shouthwind.entity.People">
select *from people where name=#{name}
</select>
4.多参数:
public People findByIdAndName(Integer id,String name);
<select id="findByIdAndName" resultType="com.shouthwind.entity.People">
select * from people where id=#{param1} and name=#{param2}
</select>
5.POJO:
public int update(People people);
<update id="update" parameterType="com.shouthwind.entity.People">
update people set name=#{name} ,money=#{money} where id=#{id}
</update>
resultType
与parameterType基本一致:
1.基本数据类型
public int count();
<select id="count" resultType="int">
select count(*) from people
</select>
2.包装类
public Integer count();
<select id="count" resultType="java.lang.Integer">
select count(*) from people
</select>
3.String
public String findNameById(Integer id);
<select id="findNameById" parameterType="java.lang.Integer" resultType="java.lang.String">
select name from people where id=#{id}
</select>
4.POJO
public People findById(Integer id);
<select id="findById" parameterType="java.lang.Integer" resultType="com.shouthwind.entity.People">
select *from people where id=#{id}
</select>
多表关联查询
实际开发中最常用的一对多和多对多
一对多
1.建表
2.Sql数据库基础
3.创建实体类
package com.shouthwind.entity;
import lombok.Data;
import java.util.List;
@Data
public class Sc {
private Integer Sno;
private Integer Cno;
private Integer Grade;
private List<Student> students;
}
package com.shouthwind.entity;
import lombok.Data;
@Data
public class Student {
private Double Sno;
private String Sname;
private String Ssex;
private Integer Sage;
private String Sdept;
private Sc sc;
}
4.实际
package com.shouthwind.repository;
import com.shouthwind.entity.Student;
public interface StudentRepository {
public Student findById( Integer id);
}
resultType是直接将结果集与实体类映射的,名字一样就映射。
resultMap对结果集二次封装,根据需求来对结果集合分装。
<mapper namespace="com.shouthwind.repository.StudentRepository">
<resultMap id="studentMap" type="com.shouthwind.entity.Student">
<result column="sSno" property="Sno"></result>
<result column="sSname" property="Sname"></result>
<result column="sSsex" property="Ssex"></result>
<result column="sSage" property="Sage"></result>
<result column="sSdept" property="Sdept"></result>
<association property="sc" javaType="com.shouthwind.entity.Sc">
<result column="cSno" property= "Sno"></result>
<result column="cCno" property="Cno"></result>
<result column="cGrade" property="Grade"></result>
</association>
</resultMap>
<select id="findById" parameterType="java.lang.Integer" resultMap="studentMap">
select s.Sno sSno,s.Sname sSname,s.Ssex sSsex,s.Sage sSage,s.Sdept sSdept,c.Sno cSno,c.Cno cCno,c.Grade cGrade from student s,sc c where s.Sno=c.Sno and s.Sno=#{Sno}
</select>
</mapper>
Class:
package com.shouthwind.repository;
import com.shouthwind.entity.Sc;
public interface ClassRepository {
public Sc finById(Integer Cno);
}
<?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.shouthwind.repository.ClassRepository">
<resultMap id="classMapper" type="com.shouthwind.entity.Sc">
<id property="Cno" column="cCno"></id>
<result property="Sno" column="cSno"></result>
<result property="Grade" column="cGrade"></result>
<collection property="students" ofType="com.shouthwind.entity.Student">
<result column="sSno" property="Sno"></result>
<result column="sSname" property="Sname"></result>
<result column="sSsex" property="Ssex"></result>
<result column="sSage" property="Sage"></result>
<result column="sSdept" property="Sdept"></result>
</collection>
</resultMap>
<select id="finById" resultMap="classMapper">
select c.Sno cSno,c.Cno cCno,c.Grade cGrade,s.Sno sSno,s.Sname sSname,s.Ssex sSsex,s.Sage sSage,s.Sdept sSdept from sc c,student s where c.Cno=s.Cno and c.Cno=#{Cno}
</select>
</mapper>
注意:
1.association是封装成一个实体类:javaType设置数据类型
2.collection是封装成一个集合:ofType设置数据类型
多对多
多对多是一种双向的关系
1.建表
mysql> create table account_course(
-> id int(11) not null primary key auto_increment,
-> aid int(11) default null,
-> cid int(11) default null,
-> key aid(aid),
-> key cid(cid),
-> constraint account_course_ibfk_1 foreign key(aid) references account(id),
-> constraint account_course_ibfk_2 foreign key(aid) references t_course(id)
-> );
mysql> create table t_course(
-> id int(11) not null primary key auto_increment,
-> name varchar(11) default null
-> );
2.实体类
package com.shouthwind.entity;
import lombok.Data;
import java.util.List;
@Data
public class Account {
private Integer id;
private String name;
private List<Course> courses;
}
package com.shouthwind.entity;
import java.util.List;
public class Course {
private Integer id;
private String name;
private List<Student> students;
}
3.学生选课:
学生------》课
package com.shouthwind.repository;
import com.shouthwind.entity.Account;
public interface AccountRepository {
public Account findById(Integer id);
}
<?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.shouthwind.repository.AccountRepository">
<resultMap id="accoutMap" type="com.shouthwind.entity.Account">
<id column="aid" property="id"></id>
<result column="aname" property="name"></result>
<collection property="courses" ofType="com.shouthwind.entity.Course">
<id column="cid" property="id"></id>
<result column="cname" property="name"></result>
</collection>
</resultMap>
<select id="findById" parameterType="java.lang.Integer" resultMap="accoutMap">
select a.id aid,a.name aname,c.id cid,c.name cname from account a,t_course c,account_course ac where a.id=#{id} and a.id=ac.aid and c.id=ac.cid
</select>
</mapper>
课程-------》学生
package com.shouthwind.repository;
import com.shouthwind.entity.Course;
public interface CourseRepository {
public Course findById(Integer id);
}
<?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.shouthwind.repository.CourseRepository">
<resultMap id="courseMap" type="com.shouthwind.entity.Course">
<id column="cid" property="id"></id>
<result column="cname" property="name"></result>
<collection property="accounts" ofType="com.shouthwind.entity.Account">
<id column="aid" property="id"></id>
<result column="aname" property="name"></result>
</collection>
</resultMap>
<select id="findById" parameterType="java.lang.Integer" resultMap="courseMap">
select a.id aid,a.name aname,c.id cid,c.name cname from account a,t_course c,account_course ac where c.id=#{id} and a.id=ac.aid and c.id=ac.cid
</select>
</mapper>
Mybatis 的逆向工程
Mybatis是一个半自动化的ORM框架,SQL语句需要要开发者自己定义,SQL定义在Mapper.xml中,与对应的Mapper接口对应
实体类
接口
Mapper.xml
工作量较大不好开发。
可以根据表来生成你要的接口和类还有接口--------逆向工程
逆向工程是Mybatis提供的一项自动化方案,正对数据表自动的生成一些资源,但是逆向工程只正对单表,如果由级联关系无法自动生成。
使用逆向工程 Mabtis Generator (MBG) ,是专门为Mybits框架定制的代码自动生成解决问题的方案。
1.创建maven,pom.xml添加相关依赖:
<!-- mybatis-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.5</version>
</dependency>
<!-- mysql-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.19</version>
</dependency>
<!-- mbg-->
<dependency>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-core</artifactId>
<version>1.3.2</version>
</dependency>
<!-- lombox-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.10</version>
</dependency>
2.建表
3.配置mbg的配置文件
配置数据库的连接信息 jdbcConnection
配置javaBean的生成策略javaModelGenerator
配置SQL的也设文件的生成策略javaClientGenerator
配置需要逆向解析的数据表table( tableName:表名 domainObjectName:实体类名)
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN" "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<generatorConfiguration>
<context id="testTables" targetRuntime="Mybatis3">
<jdbcConnection
driverClass="com.mysql.cj.jdbc.Driver"
connectionURL="jdbc:mysql://localhost:3306/text?serverTimezone=UTC&useUnicode=true&characterEncoding=utf8"
userId="root"
password="123456"
></jdbcConnection>
<javaModelGenerator targetPackage="com.southwind.entity" targetProject="./src/main/java"></javaModelGenerator>
<sqlMapGenerator targetPackage="com.southwind.repository" targetProject="./src/main/java"></sqlMapGenerator>
<javaClientGenerator type="XMLMAPPER" targetPackage="com.southwind.repository" targetProject="./src/main/java"></javaClientGenerator>
<table tableName="people" domainObjectName="People"></table>
</context>
</generatorConfiguration>
4.创建GeneratorMain类启动逆向工程
Mybatis的延迟加载
1.配置:
<settings>
<!-- 打印SQL-->
<setting name="logImpl" value="STDOUT_LOGGING"/>
<!-- 延迟加载-->
<setting name="lazyLoadingEnabled" value="true"/>
</settings>
2.Mapper
<?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.shouthwind.repository.CourseRepository">
<!-- <resultMap id="courseMap" type="com.shouthwind.entity.Course">-->
<!-- <id column="cid" property="id"></id>-->
<!-- <result column="cname" property="name"></result>-->
<!-- <collection property="accounts" ofType="com.shouthwind.entity.Account">-->
<!-- <id column="aid" property="id"></id>-->
<!-- <result column="aname" property="name"></result>-->
<!-- </collection>-->
<!-- </resultMap>-->
<!-- <select id="findById" parameterType="java.lang.Integer" resultMap="courseMap">-->
<!-- select a.id aid,a.name aname,c.id cid,c.name cname from account a,t_course c,account_course ac where c.id=#{id} and a.id=ac.aid and c.id=ac.cid-->
<!-- </select>-->
<resultMap id="courseMap" type="com.shouthwind.entity.Course">
<id column="id" property="id"></id>
<result column="name" property="name"></result>
<association property="accounts"
javaType="com.shouthwind.entity.Account"
select="com.shouthwind.repository.AccountRepository.findById"
column="id"
></association>
</resultMap>
<select id="findById" parameterType="java.lang.Integer" resultMap="courseMap">
select * from t_course where id=#{id}
</select>
</mapper>
3.创建AccountRepository.findByid
<select id="findBuId" parameterType="java.lang.Integer" resultType="com.shouthwind.entity.Account">
select * from account where id=#{id}
</select>
public Account findById(Integer id);
4.测试
public class Test6 {
public static void main(String[] args) {
InputStream inputStream = Test5.class.getClassLoader().getResourceAsStream("config.xml");
SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(inputStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
//获取实现了自定义代理接口的对象
CourseRepository courseRepository=sqlSession.getMapper(CourseRepository.class);
Course course =courseRepository.findById(1);
System.out.println(course.getAccounts().getName());
}
}
延迟加加载是使用频率较高的应用,好的使用可以减少数据库的交互,可以提高程序运行效率的手段,一般用于d多表关联查询。
Mybatis的缓存
缓存也是为了减少java应用与数据库的交互次数,提升程序的效率
一级缓存
自带一级缓存,并且无法关闭,一直存在,存储在SqlSession中
使用同一个sqlsession进行查询操作一级缓存存在;如果有多个sqlsession那么一级缓存不存在
缓存一般争对查询,如果进行了增删改查操作,会自动的将缓存的数据清除,保证数据的一致性,一级缓存不需要设置,直接使用即可。
1.实体类
package com.shouthwind.entity;
import lombok.Data;
import java.util.List;
@Data
public class Account {
private Integer id;
private String name;
private List<Course> courses;
}
2.接口
package com.shouthwind.repository;
import com.shouthwind.entity.Account;
public interface AccountRepository {
public Account findById1(Integer id);
public Account findById(Integer id);
}
3.Mapper
<?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.shouthwind.repository.AccountRepository">
<resultMap id="accoutMap" type="com.shouthwind.entity.Account">
<id column="aid" property="id"></id>
<result column="aname" property="name"></result>
<collection property="courses" ofType="com.shouthwind.entity.Course">
<id column="cid" property="id"></id>
<result column="cname" property="name"></result>
</collection>
</resultMap>
<select id="findById1" parameterType="java.lang.Integer" resultMap="accoutMap">
select a.id aid,a.name aname,c.id cid,c.name cname from account a,t_course c,account_course ac where a.id=#{id} and a.id=ac.aid and c.id=ac.cid
</select>
<select id="findById" parameterType="java.lang.Integer" resultType="com.shouthwind.entity.Account">
select * from account where id=#{id}
</select>
</mapper>
4.测试
对一个SQL session一直使用查询的结果
二级缓存
它是Mapper级别的,无论使用多少个sqlsession都可以共享。
二级缓存默认是关闭的,二级缓存配置开启。
- 自带的二级缓存
- 第三方的ehcache二级缓存
自带的二级缓存
1.配置config.xml
<!-- 打印SQL-->
<setting name="logImpl" value="STDOUT_LOGGING"/>
<!-- 延迟加载-->
<setting name="lazyLoadingEnabled" value="true"/>
<!-- 开启二级缓存-->
<setting name="cacheEnabled" value="true"/>
</settings>
2.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.shouthwind.repository.StudentRepository">
<cache></cache>
<resultMap id="studentMap" type="com.shouthwind.entity.Student">
<id column="sSno" property="Sno"></id>
<result column="sSname" property="Sname"></result>
<result column="sSsex" property="Ssex"></result>
<result column="sSage" property="Sage"></result>
<result column="sSdept" property="Sdept"></result>
<association property="sc" javaType="com.shouthwind.entity.Sc">
<result column="cSno" property= "Sno"></result>
<result column="cCno" property="Cno"></result>
<result column="cGrade" property="Grade"></result>
</association>
</resultMap>
<select id="findById" parameterType="java.lang.Integer" resultMap="studentMap">
select s.Sno sSno,s.Sname sSname,s.Ssex sSsex,s.Sage sSage,s.Sdept sSdept,c.Sno cSno,c.Cno cCno,c.Grade cGrade from student s,sc c where s.Sno=c.Sno and s.Sno=#{Sno}
</select>
</mapper>
3.实体类实现Serializable接口
package com.shouthwind.entity;
import lombok.Data;
import java.io.Serializable;
@Data
public class Student implements Serializable {
private Integer Sno;
private String Sname;
private String Ssex;
private Integer Sage;
private String Sdept;
private Sc sc;
}
第三方的ehcache缓存
1.配置
<!-- ehcache-->
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache-core</artifactId>
<version>2.4.3</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-ehcache</artifactId>
<version>1.0.0</version>
</dependency>
2.在resource小创建ehcache创建配置
<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd">
<!-- 磁盘保存路径 -->
<diskStore path="D:\\ehcache" />
<defaultCache
maxElementsInMemory="10000"
maxElementsOnDisk="10000000"
eternal="false"
overflowToDisk="true"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
diskExpiryThreadIntervalSeconds="120"
memoryStoreEvictionPolicy="LRU">
</defaultCache>
</ehcache>
3.config.xml中配置二级缓存
<settings>
<!-- 打印SQL-->
<setting name="logImpl" value="STDOUT_LOGGING"/>
<!-- 延迟加载-->
<setting name="lazyLoadingEnabled" value="true"/>
<!-- 开启二级缓存-->
<setting name="cacheEnabled" value="true"/>
</settings>
4.Mapper.xml中配置二级缓存
<cache type="org.mybatis.caches.ehcache.EhcacheCache">
<!-- 缓存创建以后,最后一次访问的时间到失效时间-->
<property name="timeToIdleSeconds" value="3600"/>
<!-- 缓存自创建时间起自失效时间的间隔-->
<property name="timeToLiveSeconds" value="3600"/>
<!-- 缓存回收策略,LRU移除近期的最少使用的对象-->
<property name="memoryStoreEvictionPolicy" value="LRU"/>
</cache>
5.实体类不需要实现序列化接口
Mysql的动态SQL
Mybatis的动态SQL可以更据不同的信息来拼接不同的SQL、以适应不同的需求
1.创建实体类
package com.shouthwind.entity;
import lombok.Data;
@Data
public class People {
// private Integer Sno;
// private String Sname;
// private String Ssex;
// private Integer Sage;
// private String Sdept;
private Integer id;
private String name;
private Integer money;
}
2.创建Mapper接口和文件
package com.shouthwind.repository;
import com.shouthwind.entity.People;
import java.util.List;
public interface UserRepository {
// public int save(People people);
// public int deleteById(Integer id);
// public int update(People people);
// public People findById(Integer id);
// public List<People> findAll();
// public People findById2(int id);
// public People findByName(String name);
// public People findByIdAndName(Integer id,String name);
// public Integer count();
// public String findNameById(Integer id);
public People findByUser (People people);
}
<!-- 动态 sql-->
<select id="findByUser" parameterType="com.shouthwind.entity.People" resultType="com.shouthwind.entity.People">
select * from people
<where>
<if test="id!=null">
id=#{id}
</if>
<if test="name!=null">
and name={name}
</if>
<if test="money!=null">
and money=#{money}
</if>
</where>
</select>
4.测试
package com.shouthwind.Test;
import com.shouthwind.entity.People;
import com.shouthwind.repository.UserRepository;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import java.io.InputStream;
public class Test7 {
public static void main(String[] args) {
InputStream inputStream = Test7.class.getClassLoader().getResourceAsStream("config.xml");
SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(inputStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
//获取实现了自定义代理接口的对象
UserRepository userRepository=sqlSession.getMapper(UserRepository.class);
People people = new People();
people.setId(1);
People result =userRepository.findByUser(people);
System.out.println(result);
}
}
if
where
- choose、when
类似swich case
代码:
<!-- 动态 sql-->
<select id="findByUser" parameterType="com.shouthwind.entity.People" resultType="com.shouthwind.entity.People">
select * from people
<where>
<choose>
<when test="id!=null">
id=#{id}
</when>
<when test="name!=null">
and name={name}
</when>
<when test="money!=null">
and money=#{money}
</when>
</choose>
</where>
</select>
trim
设置predix和suffix参数来完成使用
xml</p></li>
</ul>
¨K60K
¨K94K
set用于update操作
package com.shouthwind.repository;
import com.shouthwind.entity.People;
import java.util.List;
public interface UserRepository {
// public int save(People people);
// public int deleteById(Integer id);
// public int update(People people);
// public People findById(Integer id);
// public List<People> findAll();
// public People findById2(int id);
// public People findByName(String name);
// public People findByIdAndName(Integer id,String name);
// public Integer count();
// public String findNameById(Integer id);
public People findByUser (People people);
public Integer update (People people);
}mapperi文件
<update id="update" parameterType="com.shouthwind.entity.People">
update people
<set>
<if test="name!=null">
name=#{name},
</if>
<if test="money!=null">
money=#{money}
</if>
</set>
where id=#{id}
</update>
测试类:
package com.shouthwind.Test;
import com.shouthwind.entity.People;
import com.shouthwind.repository.UserRepository;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import java.io.InputStream;
public class Test7 {
public static void main(String[] args) {
InputStream inputStream = Test7.class.getClassLoader().getResourceAsStream("config.xml");
SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(inputStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
//获取实现了自定义代理接口的对象
UserRepository userRepository=sqlSession.getMapper(UserRepository.class);
People people = new People();
people.setId(1);
people.setName("郝momo");
people.setMoney(55);
userRepository.update(people);
sqlSession.commit();
// People result =userRepository.findByUser(people);
// System.out.println(result);
sqlSession.close();
}
}
三:Mybatis的更多相关文章
- 三 mybatis typeAlias(别名)使用和resultMap使用
1.MyBatis提供的typeAlias
- Spring+SpringMVC+MyBatis深入学习及搭建(三)——MyBatis全局配置文件解析
转载请注明出处:http://www.cnblogs.com/Joanna-Yan/p/6874672.html 前面有写到Spring+SpringMVC+MyBatis深入学习及搭建(二)——My ...
- MyBatis学习(三)---MyBatis和Spring整合
想要了解MyBatis基础的朋友可以通过传送门: MyBatis学习(一)---配置文件,Mapper接口和动态SQL http://www.cnblogs.com/ghq120/p/8322302. ...
- mybatis入门(三):mybatis的基础特性
mybatis的知识点: 1.mybatis和hibernate本质区别和应用场景 hibernate:是一个标准的ORM框架(Ojbect relation mapper对象关系映射).入门门槛较高 ...
- mybatis深入理解(三)-----MyBatis事务管理机制
MyBatis作为Java语言的数据库框架,对数据库的事务管理是其非常重要的一个方面.本文将讲述MyBatis的事务管理的实现机制.首先介绍MyBatis的事务Transaction的接口设计以及其不 ...
- 三 MyBatis配置文件SqlMapCofing.xml(属性加载&类型别名配置&映射文件加载)
SqlMapCofing:dtd,属性加载有固定的顺序Content Model properties:加载属性文件 typeAliases:别名配置 1 定义单个别名:不区分大小写 核心配置: 映射 ...
- MyBatis学习总结(三)——MyBatis配置文件配置的优化
一.连接数据库的配置单独放在一个properties文件中 上文 连接数据库的配置写在 mybatisConf.xml中,本文直接放在 db.properties 中, 在mybatisConf.xm ...
- SSM(三)Mybatis动态SQL
1.查询语句,where: <resultMap id="xxx" type="xx..Student" autoMapping="false& ...
- Mybatis(三)Mybatis映射开发
4.1 一对一 4.1.1 表对应关系, 一个订单对应一个用户 4.1.2 实体对应关系 public class Order { private int id; private Date order ...
- mybatis详解(三)
一,动态sql,where,trim,set和foreach parameterType的属性可以不用写 xml文件sql的书写 <select id="queryByParams&q ...
随机推荐
- 【DL论文精读笔记】 深度压缩
深度压缩 DEEP COMPRESSION: COMPRESSING DEEP NEURAL NETWORKS WITH PRUNING, TRAINED QUANTIZATION AND HUFFM ...
- Vue使用axios请求接口返回成功200但是进入到catch中
发生这个问题时查阅了许多资料,没有一个是对得上的.最后发现原来是在请求拦截器中的错误 错误代码如下 // 添加响应拦截器 axios.interceptors.response.use(functio ...
- 数电第三周周结_by_yc
主要内容:Modelsim和Quartus的使用坑点 Modelsim: 新建Project: 在每新建一个verilog文件时,均需要添加一project的独立路径,否则不同文件之间会相互影响! ...
- 搭建漏洞环境及实战——在Linux系统中安装LANMP
LANMP是Linux下Apache.Nginx.mysql和php的应用环境 演示的是WDLinux 命令:wget http://dl.wdlinux.cn/files/lamp_v3.tar.g ...
- 使用WPF或AspNetCore创建简易版ChatGPT客户端,让ChatGPT成为你的私人助理
前言:前一天写的一个ChatGPT服务端,貌似大家用起来还不是那么方便,所以我顺便用WPF和AspNetCore的webapi程序做个客户端吧,通过客户端来快速访问chatgpt模型生成对话. 1 ...
- 解决MVVMLight导航VM不重置问题
问题阐述:使用MVVMLight导航发现导航后VM里面的数据并未进行重置,需要界面跳转后,历史VM也进行销毁重置,并释放 解决办法: 方法一:在当前界面进行Unloaded进行VM注销并进行重新注入代 ...
- 6、SQL模糊查询LIKE concat用法
concat用来拼接查询的字符串: SELECT * FROM `page_demo` WHERE name LIKE concat('%',#{name},'%') 模糊查询: 1.%代表零个或多个 ...
- 学习ASP.NET Core Blazor编程系列十八——文件上传(中)
学习ASP.NET Core Blazor编程系列文章之目录 学习ASP.NET Core Blazor编程系列一--综述 学习ASP.NET Core Blazor编程系列二--第一个Blazor应 ...
- angular在服务中调用组件的某个方法,并传参给组件,(反向调用),变量改变后,强制更新视图
需要被调用方法的组件文件 import { Component, ChangeDetectionStrategy, ChangeDetectorRef } from '@angular/core'; ...
- ua5.4源码剖析:三. C++与Lua相互调用
概述 从本质上来看,其实说是不存在所谓的C++与lua的相互调用.lua是运行在C上的,简单来说lua的代码会被编译成字节码在被C语言的语法运行.在C++调用lua时,其实是解释运行lua文件编译出来 ...