继上篇mybatis基础
https://blog.csdn.net/weixin_45262118/article/details/108482350
<environments default="development">//dafault 默认使用的数据库id
<environment id="development">//数据库id
<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>
设置别名(大小写不能变)
<databaseIdProvider type="DB_VENDOR">
<property name="MySQL" value="mysql"/>//mysql为别名
<property name="Oracle" value="oracle"/>
databaseIdProvider>
z哎mapper.xml中写不同的数据库的SQL语句,并表明要使用的数据库别名
<select id="queryStudentById" resultType="student" parameterType="int" databaseId="mysql">//通过databaseId 调用数据库别名
select * from student where stuNo = #{id}
select>
如果既有不带databaseId的标签和带databaseId的标签,则数据库会优先使用带databaseId的标签
@Select("select * from student where stuNo=#{stuNo}")
Student queryStudentById(int stuNo);
注解/xml都支持批量引入
<mappers>
<package name="com.xiaoming.mapper"/>//写这句话就够了
mappers>
返回值可以是void/Integer/Long/Boolean:只需要在接口中将返回值改变
SqlSession sqlSession = sqlSessionFactory.openSession();
sqlSession.commit();//手动提交 进行增删改(dml)就要手动提交
SqlSession sqlSession = sqlSessionFactory.openSession(true);//自动提交 不需要commit
<insert id="addStudent" parameterType="student"
useGeneratedKeys="true" keyProperty="stuNo">//加入这两个属性即可
insert into student values(#{stuNo},#{stuName},#{stuAge},#{graName} )
insert>
Oracle不支持自增: 通过序列模拟实现 序列自带两个属性:
nextval:序列中下一个值
currval:当前值
创建一个序列
create sequence myseq increment by 1 start with 1;
方式一:Befor(推荐) 创建SQL语句
<insert id="addStudent" parameterType="student" databaseId="oracle">
<selectKey keyProperty="stuNo" resultType="Integer" order="BEFORE">
select myseq.nextval from dual //dual 虚拟表
</selectKey>
insert into student values(#{stuNo},#{stuName},#{stuAge},#{graName} )
</insert>
方式二:After
<insert id="addStudent" parameterType="student" databaseId="oracle">
<selectKey keyProperty="stuNo" resultType="Integer" order="AFTER">
select myseq.currval from dual
</selectKey>
insert into student values(myseq.next ,#{stuName},#{stuAge},#{graName} )
</insert>
oracle: 如果插入的字段时Null.提示错误: other 而不是 null;
mysql:如果插入的字段时Null 可以执行(没有约束)
<insert id="addStudent" parameterType="student" databaseId="oracle">
insert into student values(myseq.next ,#{stuName,jdbcType=NULL},#{stuAge},#{graName} )
insert>
#{stuName,jdbcType=NULL},stuName既可以输入NULL,也可以不为NULL.
<settings>
<setting name="jdbcTypeForNull" value="NULL"/>
settings>//推荐 在conf.xml中配置
相当于if判断 在SQL语句里面进行判断
<resultMap id="discriminator" type="com.xiaoming.entity.Student">
<discriminator javaType="string" column="graName">
<case value="G1" resultType="com.xiaoming.entity.Student">
<result column="stuName" property="stuName1">result>
case>//如果graName=“G1” 则将stuName的值赋给stuName1
<case value="G2" resultType="com.xiaoming.entity.Student">
<result column="stuName" property="stuName2">result>
case>//如果graName=“G2” 则将stuName的值赋给stuName2
discriminator>
resultMap>
只能处理【开头】第一个and
可以处理【开头或结尾】第一个and
开头:
select stuNo,stuName,stuAge from student
<trim prefix="where" prefixOverrides="and">
<if test="stuAge != null and stuAge != 0 ">
and stuAge=#{stuAge}
if>
<if test="stuName != null and stuName != ''">
and stuName=#{stuName}
if>
trim>
prefix=“where” 给拼接的SQL语句加where
prefixOverrides=“and” 处理拼接的第一个and
后面的拼接:
select stuNo,stuName,stuAge from student
<if test="stuAge != null and stuAge != 0 ">
stuAge=#{stuAge} and
if>
<if test="stuName != null and stuName != ''">
stuName=#{stuName} and
if>
trim>
_parameter:代表mybatis的输入参数
<select id="queryStuByLike" parameterType="student" resultType="student">
select * from student
<trim prefix="where" suffixOverrides="and">
<if test="_parameter.stuName != null and _parameter.stuName != ''">
stuName like '%${_parameter.stuName}%' and
if>
<if test="graName != null and graName !=''">
graName like '%${graName}%' and
if>
<if test="stuAge != null and stuAge != ''">
stuAge like '%${stuAge}'
if>
trim>
_databaseId:代表当前使用数据库的名
将传入的值放置在stuName 进行字符串拼接 --> ‘%s%’ 再将**’%s%‘赋值给_queryName ** 以后用**’%s%'就可以使用_queryName **
<dependencies>
<dependency>
<groupId>com.baomidougroupId>
<artifactId>mybatis-plusartifactId>
<version>3.3.1version>
dependency>
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
<version>5.1.47version>
dependency>
<dependency>
<groupId>log4jgroupId>
<artifactId>log4jartifactId>
<version>1.2.17version>
dependency>
<dependency>
<groupId>com.mchangegroupId>
<artifactId>c3p0artifactId>
<version>0.9.5.2version>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-contextartifactId>
<version>5.2.4.RELEASEversion>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-ormartifactId>
<version>5.2.4.RELEASEversion>
dependency>
dependencies>
数据表 类
MyBatis 配置文件 mybatis.xml
<settings>
<setting name="logImpl" value="LOG4J"/>
settings>
日志log4j信息
# Global logging configuration 开发时候建议使用 debug
log4j.rootLogger=DEBUG, stdout
# Console output...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n
数据库连接信息 db.properties
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mybatisplus
jdbc.username=root
jdbc.password=123456
spring 配置信息 applicationContext.properties
TMapper extends BaseMapper<T>
//Mapper 继承该接口后,无需编写 mapper.xml 文件,即可获得CRUD功能
<p>这个 Mapper 支持 id 泛型</p>
public interface StudentMapper extends BaseMapper<Student> {
}
建议表里属性写_形式 例如 stu_no stu_name 表里ID值勾选自动递增
相应的类与之对应
@TableName("tb_student") //类名与表名不对应的时候
public class Student {
@TableId(value="stuno",type = IdType.AUTO)//不插入ID值让其自增 在数据库里要勾选自增
private int stuNo;
@TableField(value = "stuname")//MyBatis Plus 将stuName这种形式自动转化成stu_name
private String stuName;
@TableField(value = "stuage")
private int stuAge;
方法:
public static void testInsert() {
ClassPathXmlApplicationContext context =
new ClassPathXmlApplicationContext("applicationContext.xml");
StudentMapper studentMapper = context.getBean("studentMapper", StudentMapper.class);//StudentMapper.class 将Object 类型转换成 StudentMapper相当于强转
Student student = new Student("zs",12);
int count = studentMapper.insert(student);//
System.out.println(count);
}
在MyBatis.xml中配置 关闭下划线和骆驼峰之间的自动转换关闭
<setting name="mapUnderscoreToCamelCase" value="false"/>
出现 stu_no自动转stuNo 的情况导致查询结果为null wapper相当于where语句
public static void testQuery() {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
StudentMapper studentMapper = context.getBean("studentMapper", StudentMapper.class);
//select ... from ... where ... stu_no between 3 and 5 and stu_age>20
QueryWrapper<Student> wrapper = new QueryWrapper<>();
wrapper.between("stu_age", 2, 20).ge("stu_no",2);
List<Student> students = studentMapper.selectList(wrapper);
// Student student = studentMapper.selectById(2);
System.out.println(students);
}
wapper 相当于where
查询 QueryWapper
QueryWrapper<Student> wrapper = new QueryWrapper<>();
wrapper.between("stu_age", 12, 20).or(i->i.ge("stu_no",4).le("stu_no",6));
//SELECT stu_no,stu_name,stu_age FROM student WHERE (stu_age BETWEEN ? AND ? OR stu_no >= ?)
wrapper.between(“stu_age”, 12, 20).ge(“stu_no”,4) 默认用and连接 如果要用或的关系
wrapper.between(“stu_age”, 12, 20).or().ge(“stu_no”,4) or里面有多个语句
wrapper.between(“stu_age”, 12, 20).or(i->i.ge(“stu_no”,4).le(“stu_no”,6));
预加载:MP启动时,会指定加载所有常见的CRUD语句(来自于MP提供的BaseMapper接口)并将这些够封装到了MapperStatement对象中。
形式 直接通过实行了进行增删改查(不需要借助Mapper对象)
实体类继承Model类
public class Student extends Model<Student> {
方法
new ClassPathXmlApplicationContext("ApplicationContext.xml");//里面配置了数据库信息必须打开IOC容器才能进行操作
Student student = new Student("张三",23);
student.insert();
MP将主键设置成了Serializable类型 目的:可以接受常见的类型:8个基本类型+String 他们的父类都是Serializable
面向对象 lambda 查询的对象是"类的属性"
wapper.lambda().like(Student::getStuName,“a”);
面向SQL 查询的是表的字段
wapper.like(“stu_name”,“a”);
https://mp.baomidou.com/
在ApplicationContext.xml中的MyBatis Plus 的配置MybatisSqlSessionFactoryBean中配置
<property name="plugins" >
<list>
<bean class="com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor">
bean>
list>
property>
public static void testPage(){
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
StudentMapper studentMapper = context.getBean("studentMapper", StudentMapper.class);
//select * from student limit 2,2
Page<Student> page = studentMapper.selectPage(new Page<>(2, 2), null);
System.out.println("当前页的数据:"+page.getRecords());
System.out.println("当前页页码:"+page.getCurrent());
System.out.println("总数据量:"+ page.getTotal());
System.out.println("每页数据量:"+ page.getSize());
}
阻断器: 防止恶意删除或修改全表数据
<list>
<bean class="com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor">
<property name="sqlParserList" >
<list>
<bean class="com.baomidou.mybatisplus.extension.parsers.BlockAttackSqlParser">bean>
list>
property>
bean>
list>
乐观锁:CAS算法 总以为不会冲突 在修改的瞬间 检验一下
悲观锁 总以为会冲突 并发–> 串行 (影响效率)
在 com.xm.injector.methods 包中写自己的方法 extends AbstractMethod 可以模仿例句修改
public class MyDelete extends AbstractMethod {
@Override
public MappedStatement injectMappedStatement(Class<?> mapperClass, Class<?> modelClass, TableInfo tableInfo) {
String sql;
sql = "delete from student where stu_no>6";
SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, modelClass);
return this.addDeleteMappedStatement(mapperClass, "deleteAll", sqlSource);
}
}
在接口 StudentMapper中写自己的方法-->**void deleteAll();**
在injector包下创建 MyInjector 类 com.xm.injector.MyInjector
extends AbstractSqlInjector
将17个默认的方法和自定义的方法加入
public class MyInjector extends AbstractSqlInjector {
@Override
public List<AbstractMethod> getMethodList(Class<?> mapperClass) {
return Stream.of(
new Insert(),
new Delete(),
new DeleteByMap(),
new DeleteById(),
new DeleteBatchByIds(),
new Update(),
new UpdateById(),
new SelectById(),
new SelectBatchByIds(),
new SelectByMap(),
new SelectOne(),
new SelectCount(),
new SelectMaps(),
new SelectMapsPage(),
new SelectObjs(),
new SelectList(),
new SelectPage(),
new MyDelete() //自定义方法
).collect(toList());
}
}
或者直接将自定义类加入到默认的方法数组中 变成自定义的18个方法数组
public class MyInjector extends AbstractSqlInjector {
@Override
public List<AbstractMethod> getMethodList(Class<?> mapperClass) {
List<AbstractMethod> methodList = new DefaultSqlInjector().getMethodList(Student.class);
methodList.add(new MyDelete());
return methodList;
}
}
<bean id="globalConfig" class="com.baomidou.mybatisplus.core.config.GlobalConfig">
<property name="sqlInjector">
<bean class="com.xm.injector.MyInjector">bean>
property>
<bean id="sqlSessionFactory" class="com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean">
<property name="dataSource" ref="dataSource">property>
<property name="configLocation" value="classpath:mybatis.xml">property>
<property name="typeAliasesPackage" value="com.xm.entity">property>
<property name="globalConfig" ref="globalConfig">property>//要写在MyBatisPlus的bean之中