文章目录
Mybatis基础(六)
数据库多环境切换
-
切换 environment (指定实际使用的数据库)
-
db.properties
#oracle oracle.driver=oracle.jdbc.OracleDriver oracle.url=jdbc:oracle:thin:@127.0.0.1:1521:ORCL oracle.username=scott oracle.password=tiger #mysql mysql.driver=com.mysql.jdbc.Driver mysql.url=jdbc:mysql://localhost:3306/mydb?allowMultiQueries=true mysql.username=root mysql.password=root
-
conf.xml
<configuration> <!-- 引用db.properties配置文件 --> <properties resource="db.properties"/> <!--default指定环境 --> <environments default="devOracle"> <!--oracle --> <environment id="devOracle"> <transactionManager type="JDBC" /> <!-- 配置数据库连接信息 --> <dataSource type="POOLED"> <property name="driver" value="${oracle.driver}" /> <property name="url" value="${oracle.url}" /> <property name="username" value="${oracle.username}" /> <property name="password" value="${oracle.password}" /> </dataSource> </environment> <!--mysql --> <environment id="devMysql"> <transactionManager type="JDBC" /> <!-- 配置数据库连接信息 --> <dataSource type="POOLED"> <property name="driver" value="${mysql.driver}" /> <property name="url" value="${mysql.url}" /> <property name="username" value="${mysql.username}" /> <property name="password" value="${mysql.password}" /> </dataSource> </environment> </environments> </configuration>
-
注意事项
-
如果mapper.xml的 sql标签 仅有 一个 不带databaseId的标签,则改标签 会自动适应当前数据库。
如果 既有不带databaseId的标签,又有带databaseId的标签,则程序会优先使用带databaseId的标签。
~~~ -
-
配置 Provider别名(数据库环境的别名)
-
在
conf.xml
中配置<configuration> <!-- 配置数据库支持类 --> <databaseIdProvider type="DB_VENDOR"> <property name="MySQL" value="mysql" /> <property name="Oracle" value="oracle" /> </databaseIdProvider> </configuration>
-
-
在
studentMapper.xml
写不同数据库的SQL语句<!--mysql --> <select id="queryStudentByNo" resultType="com.yanqun.entity.Student" parameterType="int" databaseId="mysql"> select * from student where stuNo=#{stuNo} </select> <!--oracle --> <select id="queryStudentByNo" resultType="com.yanqun.entity.Student" parameterType="int" databaseId="oracle"> select * from student where stuNo=#{stuNo} </select> <!-- 不指定databaseId,就是当前默认指定的环境(和 default 指定的环境一致) --> <select id="queryStudentByNo" resultType="com.yanqun.entity.Student" parameterType="int"> select * from student where stuNo=#{stuNo} </select>
-
在xxxMappe.xml增删改标签中配置databaseId = “Provider别名”,来进行使用(如上所示)
注解方式的增删改查
-
适用场景
注解方式只适用于简单的增删改查,复杂的增删改查,还是得使用配置文件的方式。
-
本质
注解的核心是反射机制,底层通过动态代理的方式,根据注解来找到对应的东西(类或SQL等), 把一些配置信息、属性注入到对应的对象中。
-
注解开发的优点和缺点
-
优点
方便、快捷,提高开发效率。
-
缺点
可读性低,不利于后期维护; 不适合做复杂的增删改查(复杂的表和类的映射关系等)。
-
增加数据
-
将sql语句写在接口的方法上
@Insert("")
;public interface StudentMapper { @Insert("insert into student(stuNo,sname,sage) values(1,'zs',18) where stuNo = #{stuNo}") Student queryStudentByNo (int stuNo); }
-
将接口的全类名写入
conf.xml
核心配置文件的标签中,让MyBatis知道sql语句此时是存储在接口中<configuration> <!-- 在配置文件(conf.xml)中注册SQL映射文件(studentMapper接口)--> <mappers> <mapper class="com.yanqun.mapper.StudentMapper"/> </mappers> </configuration>
删除数据
- 将sql语句写在接口的方法上
@Delete("")
; - 将接口的全类名写入
conf.xml
核心配置文件的标签中,让MyBatis知道sql语句此时是存储在接口中
修改数据
- 将sql语句写在接口的方法上
@Update("")
; - 将接口的全类名写入
conf.xml
核心配置文件的标签中,让MyBatis知道sql语句此时是存储在接口中
查询数据
-
将sql语句写在接口的方法上
@Select("")
;public interface StudentMapper { @Select("select * from student where stuNo = #{stuNo}") Student queryStudentByNo (int stuNo); }
-
将接口的全类名写入
conf.xml
核心配置文件的标签中,让MyBatis知道sql语句此时是存储在接口中<configuration> <!-- 在配置文件(conf.xml)中注册SQL映射文件(studentMapper接口)--> <mappers> <!-- <mapper resource="com/yanqun/mapper/studentMapper.xml" />--> <mapper class="com.yanqun.mapper.StudentMapper" /> <!-- 批量注册 <package name="com.yanqun.mapper"/> --> </mappers> </configuration>
增删改的返回值问题
-
返回值可以是
void
、Integer
、Long
、Boolean
。 -
如何操作:只需在接口中,修改方法的返回值即可。
Integer addStudent (Student students);
事务的提交方式
手动提交
sessionFactory.openSession();
session.commit(); //手动提交
自动提交(慎用)
//自动提交:每个DML(增删改)语句,事务自动提交
sessionFactory.openSession(true);
不同数据库的自增问题
MySQL(支持自增)
-
只需要配置两个属性即可:useGeneratedKeys=“true” keyProperty=“stuNo”
<insert id="addStudent" parameterType="com.yanqun.entity.Student" databaseId="mysql" useGeneratedKeys="true" keyProperty="stuNo"> insert into student(stuName,stuAge,graName) values(#{stuName},#{stuAge},#{graName}) </insert>
-
小结
keyProperty对应的是Java对象的属性名, useGeneratedKeys(主键生成策略)的作用是允许 JDBC 支持自动生成主键,需要驱动支持。 useGeneratedKeys如果设置为 true 则这个设置强制使用自动生成主键, 尽管一些驱动不能支持但仍可正常工作(比如 Derby)。
Oracle(不支持自增)
oracle不支持自增 :通过序列模拟实现
-
方式一:before(推荐)
-
在数据库中创建一个用于模拟自增的序列
create sequence myseq increment by 1 -- 步长为 1 start with 1; -- 从 1 开始自增
-
通过
<insert>
的子标签<selectKey>
实现<!-- 增加一个学生 oracle --> <insert id="addStudent" parameterType="com.yanqun.entity.Student" databaseId="oracle"> <!-- keyProperty对应的是Java对象的属性名 --> <selectKey keyProperty="stuNo" resultType="Integer" order="BEFORE"> <!-- myseq 为 数据库中模拟自增的序列;dual为 Oracle 的一个临时表,里面存放的是序列 --> select myseq.nextval from dual </selectKey> insert into student(stuno,stuName,stuAge,graName) values(#{stuNo} , #{stuName},#{stuAge},#{graName}) </insert>
-
在执行SQL语句之前,先在
<selectKey>
中查询下一个序列(自增后的值), -
然后再将此值传入
keyProperty="stuNo"
属性(对象的属性,也就是将数据回写到对象的属性中),最后在真正执行时 使用该属性值。
-
-
方式二:after
-
在数据库中创建一个用于模拟自增的序列(若已创建,则无需再建)
create sequence myseq increment by 1 -- 步长为 1 start with 1; -- 从 1 开始自增
-
通过
<insert>
的字标签<selectKey>
和序列自带的两个属性:nextval:序列中下一个值
currval: 当前值实现<insert id="addStudent" parameterType="com.yanqun.entity.Student" databaseId="oracle"> <selectKey keyProperty="stuNo" resultType="Integer" order="AFTER"> select myseq.currval from dual </selectKey> insert into student(stuno,stuName,stuAge,graName) values(myseq.nextval , #{stuName},#{stuAge},#{graName}) </insert>
-
先执行插入的SQL语句,自增的值从
nextval
(下一个序列、自增后的值)中去取, -
然后在
<selectKey>
中查询数据库中当前的序列值,再将此值传入keyProperty="stuNo"
属性,将数据回写到对象的属性中。
-
多个输入参数的问题
输入参数为多个时,不用写 parameterType
-
处理方式一:将多个参数封装为一个对象(前面基础部分知识点)
-
处理方式二:在xxxMapper.xml的SQL中,用 [ arg0, arg1, arg2, arg3 或 param1, param2, param3, param4 ]
<!-- 输入参数为多个时,不用写 parameterType --> <insert id="addStudent" databaseId="mysql"> insert into student(stuno,stuName,stuAge,graName) values(#{arg0},#{arg1},#{arg2},#{arg3}) </insert>
-
处理方式三:在变量前面使用@Param(“SQL中参数的名字”) 指定sql中参数的名字(推荐,也叫命名参数)
- 接口方法
//接口 //可以在接口中通过@Param("sNo") 指定sql中参数的名字 public abstract Integer addStudent(@Param("sNo") Integer stuNo, @Param("sName")String stuName, @Param("sAge")Integer stuAge, @Param("gName")String graName);
- xxxMapper.xml
<insert...> insert into student(stuno,...) values(#{sNo}, ...) </insert>
输入参数为多个且有对象和基本类型(常用于修改)
-
接口方法
//输入参数为多个,既有简单类型,又有复杂类型(对象) Integer addStudent(@Param("sNo")Integer stuNo, @Param("stu")Student student);
-
xxxMapper.xml
<insert id="addStudent" databaseId="oracle"> insert into student(stuno,stuName,stuAge,graName) values(#{sNo}, #{stu.stuName}, #{stu.stuAge}, #{stu.graName}) </insert>
-
小结
用 @Param("SQL中参数的名字") 来指定SQL中参数的名字, 即:SQL中参数的名字要和 @Param("xxx") 中的名字保持一致。 一般建议所有参数都加上这个。
-