使用SpringBoot和MyBatis,对Oracle数据的增、删、改、查、批处理、及调用存储过程,都做了示例代码及SQL的配置示例,对于各种参数传递方法,出入参类型等,也都做了示例或备注。
本Demo使用数据库为Scott/Tiger用户自带的EMP员工表,进行操作,所以数据库建表等SQL不再贴出,只给出了分页查询的存储过程SQL。
项目结构截图如下:
呃,好吧,现在发现没什么可以讲解了。
好歹自己也是搞了近一个星期,配置SQL时候也是遇到各种问题,现在竟然发现也没什么难点、注意点需要着重讲解了。可能是已经把关键点都添加了注释吧。
先查一下,工号大于7788的员工,一共7条数据。
插入工号为7979的员工信息,JOB取值为JOB(批插会更新),COMM取值为235.65(更新操作会更新)。插入后,查询出工号大于7788的员工,一共8条数据。
更新后查询
更新工号为7979的员工奖金数为555.25,之后查询,除了奖金数其他未变动。
查询部门号为20和30的员工信息。得到12条数据。
批量插入3条数据,其中工号7979的员工信息为更新操作,其他插入的数据为新增操作。即新增了12+2条数据。
删除7979号员工信息,再查工号大于7788的员工信息,得到9条,即原8+7980号和7981号员工的条数据,已经删除的数据没有查到。
批量查询得到12条数据(包括新增的7979),删掉7979后,再批删掉7980和7981后,得到11条,没错。
每页5条,查询第3页的数据。得到一共14条数据,分了3页,并返回了第3页的数据,4条,没错。
两个存储过程结果一致。
先奉上项目源码下载地址:请点击我~~~然后每个文件代码贴一下。
package com.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
//Spring Boot 应用的标识
@ComponentScan(basePackages = {"com.demo"})
@SpringBootApplication
public class Application {
public static void main(String[] args) {
// 启动嵌入式的 Tomcat 并初始化 Spring 环境及其各 Spring 组件
SpringApplication.run(Application.class, args);
}
}
package com.demo;
import java.util.List;
import java.util.Map;
import org.apache.ibatis.annotations.Param;
//映射Sql,定义接口
public interface DataMapper {
//查询。@Param对应参数属性注解,There is no getter for property named 'xx' in 'class java.lang.Integer
List test_query(@Param("EMPNO")Integer EMPNO);
//插入
void test_insert(Employee employee);
//更新
void test_update(@Param("EMPNO")Integer EMPNO, @Param("COMM")double COMM);
//删除
void test_delete(Integer EMPNO);
//批量插入
void test_multi_insert(List results);
//批量查询
List test_multi_query(int[] DEPTNOArr);
//批量删除
void test_multi_delete(List EMPNOList);
//存储过程
void test_exe_procedure1(Map params);
void test_exe_procedure2(Map params);
}
package com.demo;
import javax.sql.DataSource;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.jdbc.DataSourceBuilder;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
@Configuration
//指定扫描的mapper接口所在的包
@MapperScan(basePackages = "com.demo", sqlSessionFactoryRef = "DBDataSqlSessionFactory")
public class DataSourceConfig {
@Bean(name = "DBDataSource")
@ConfigurationProperties(prefix="spring.datasource") //告诉自动加载配置的属性
public DataSource dataSource() {
return DataSourceBuilder.create().build();
}
@Bean(name = "DBDataSqlSessionFactory")
public SqlSessionFactory sqlSessionFactory(@Qualifier("DBDataSource") DataSource dataSource)
throws Exception {
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(dataSource);
bean.setMapperLocations(
new PathMatchingResourcePatternResolver().getResources("classpath:mybatis/dbMapper.xml"));
return bean.getObject();
}
@Bean(name = "DBDataTransactionManager")
public DataSourceTransactionManager transactionManager(@Qualifier("DBDataSource") DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
@Bean(name = "DBDataSqlSessionTemplate")
public SqlSessionTemplate sqlSessionTemplate(
@Qualifier("DBDataSqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
return new SqlSessionTemplate(sqlSessionFactory);
}
}
package com.demo;
import java.util.Date;
import java.util.List;
//使用数据库系统自带的数据表,对应scott.emp表
public class Employee {
private Integer EMPNO; //员工号
private String ENAME; //员工名
private String JOB; //工种
private Integer MGR; //上级
private Date HIREDATE;//入职日期
private double SAL; //工资
private double COMM; //奖金
private Integer DEPTNO; //部门号
public String toString()
{
String info = String.format("EMPNO[%d], ENAME[%s], JOB[%s], MGR[%d], HIREDATE[%tF], SAL[%.2f], COMM[%.2f], DEPTNO[%d]", EMPNO, ENAME,JOB,MGR,HIREDATE,SAL,COMM,DEPTNO);
return info;
}
public static void Print(List empList)
{
int count = empList.size();
String format = String.format("Employee[%%%dd]: %%s", String.valueOf(count).length());
String info = String.format("%5s, %7s, %10s, %4s, %10s, %7s, %7s, %s","EMPNO", "ENAME","JOB","MGR","HIREDATE","SAL","COMM","DEPTNO");
System.out.println(String.format(format, count,info));
for(int i=0;i
package com.demo;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.demo.DataMapper;
@Component
public class SQLTest {
@Autowired
DataMapper dataMapper;
//自动载入,程序启动时候就运行啦。。。。
@Autowired
public void run() {
test_query();
test_insert();
test_query();
test_update();
test_query();
test_multi_query();
test_multi_insert();
test_multi_query();
test_delete();
test_query();
test_multi_delete();
test_multi_query();
test_exe_procedure(true);
test_exe_procedure(false);
}
private void test_query()
{
System.out.println("test_query...");
Integer EMPNO =7788;
List empList =dataMapper.test_query(EMPNO);
Employee.Print(empList);
return;
}
private void test_insert()
{
System.out.println("test_insert...");
Employee emp = new Employee();
emp.setEMPNO(7979);
emp.setENAME("ENAME");
emp.setJOB("JOB");
emp.setMGR(7566);
emp.setHIREDATE(new Date());
emp.setSAL(8799.76);
emp.setCOMM(235.65);
emp.setDEPTNO(20);
dataMapper.test_insert(emp);
}
private void test_update()
{
System.out.println("test_update...");
dataMapper.test_update(7979, 555.25);
}
private void test_delete()
{
System.out.println("test_delete...");
dataMapper.test_delete(7979);
}
private void test_multi_insert()
{
System.out.println("test_multi_insert...");
Employee emp1 = new Employee();
emp1.setEMPNO(7980);
emp1.setENAME("ENAME1");
emp1.setJOB("JOB1");
emp1.setMGR(7566);
emp1.setHIREDATE(new Date());
emp1.setSAL(8799.76);
emp1.setCOMM(235.65);
emp1.setDEPTNO(30);
Employee emp2 = new Employee();
emp2.setEMPNO(7981);
emp2.setENAME("ENAME2");
emp2.setJOB("JOB2");
emp2.setMGR(7566);
emp2.setHIREDATE(new Date());
emp2.setSAL(8799.76);
emp2.setCOMM(235.65);
emp2.setDEPTNO(30);
Employee emp3 = new Employee();
emp3.setEMPNO(7979);
emp3.setENAME("ENAME");
emp3.setJOB("JOB2");
emp3.setMGR(7566);
emp3.setHIREDATE(new Date());
emp3.setSAL(8799.76);
emp3.setCOMM(235.65);
emp3.setDEPTNO(20);
List empList = new ArrayList();
empList.add(emp1);
empList.add(emp2);
empList.add(emp3);
dataMapper.test_multi_insert(empList);
}
private void test_multi_query()
{
System.out.println("test_multi_query...");
int[] DEPTNOArr = { 20, 30 };
List empList = dataMapper.test_multi_query(DEPTNOArr);
Employee.Print(empList);
return;
}
private void test_multi_delete()
{
System.out.println("test_multi_delete...");
List EMPNOList = new ArrayList();
EMPNOList.add(7980);
EMPNOList.add(7981);
dataMapper.test_multi_delete(EMPNOList);
return;
}
private void test_exe_procedure(boolean bTestProcedure1)
{
int in_PAGE = 3;
int in_ROWS =5;
int inout_TOTAL_RECORDS=0;
int inout_TOTAL_PAGES = 0;
HashMap mm=new HashMap();
mm.put("in_PAGE", in_PAGE);
mm.put("in_ROWS", in_ROWS);
mm.put("inout_TOTAL_RECORDS", inout_TOTAL_RECORDS);
mm.put("inout_TOTAL_PAGES", inout_TOTAL_PAGES);
mm.put("out_SYSCURSOR", new ArrayList());
if(bTestProcedure1)
{
System.out.println("test_exe_procedure1...");
dataMapper.test_exe_procedure1(mm);
}
else
{
System.out.println("test_exe_procedure2...");
mm.put("in_SQL", "select t.EMPNO, t.ENAME, t.JOB, t.MGR, t.HIREDATE, t.SAL, t.COMM, t.DEPTNO from scott.emp t");
dataMapper.test_exe_procedure2(mm);
}
System.out.println("Get in_PAGE: "+ mm.get("in_PAGE"));
System.out.println("Get in_ROWS: "+ mm.get("in_ROWS"));
System.out.println("Get inout_TOTAL_RECORDS: "+ mm.get("inout_TOTAL_RECORDS"));
System.out.println("Get inout_TOTAL_PAGES: "+ mm.get("inout_TOTAL_PAGES"));
List empList = (List)mm.get("out_SYSCURSOR");
Employee.Print(empList);
return;
}
}
CREATE OR REPLACE procedure P_TEST_PAGING_QUERY
(
p_pagesql in varchar2, --sql
p_curPage in out Number , --当前页
p_pageSize in out Number , --每页显示记录的条数
p_totalRecords out Number, --总记录数
p_totalPages out Number , -- 总页数
pageResultSet out SYS_REFCURSOR -- 输出结果集游标
)
as
v_sql varchar2(2000):=''; --sql语句
v_startRecord Number; --开始显示的记录数
v_endRecord Number; --结束显示的记录条数
begin
--记录总记录条数
v_sql:='select count(*) FROM (' || p_pagesql || ')';
execute IMMEDIATE v_sql INTO p_totalRecords;
IF MOD(p_totalRecords,p_pageSize)=0 THEN
--得到整数则直接取得到的页码数否在原来的基础上增加一个页码
p_totalPages:=p_totalRecords/p_pageSize;
ELSE
p_totalPages:=p_totalRecords/p_pageSize+1;
END IF;
--验证页号
IF p_curPage<1 THEN
p_curPage:=1;
END IF;
--如果取的当前页大于总页数则取最大页数的数据
IF p_curPage>p_totalPages THEN
p_curPage:=p_totalPages;
END IF;
--实现分页查询
v_startRecord :=(p_curPage - 1) * p_pageSize + 1;
v_endRecord :=p_curPage * p_pageSize;
v_sql := 'select * from (SELECT t.*, ROWNUM RN from (' || p_pagesql || ') t where rownum<=' || v_endRecord || ' ) where RN>=' ||v_startRecord;
p_totalPages:=floor(p_totalPages); --去整数总页
OPEN pageResultSet FOR v_sql;
exception
when others then
CLOSE pageResultSet;
end P_TEST_PAGING_QUERY;
/
insert into scott.emp (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO)
values (#{EMPNO}, #{ENAME}, #{JOB}, #{MGR}, #{HIREDATE}, #{SAL}, #{COMM}, #{DEPTNO})
UPDATE scott.emp SET COMM = #{COMM}
WHERE EMPNO = #{EMPNO}
DELETE FROM scott.emp t WHERE t.EMPNO =#{EMPNO}
merge into scott.emp r
using(
select
#{item.EMPNO,jdbcType=INTEGER} as EMPNO,
#{item.ENAME,jdbcType=VARCHAR} as ENAME,
#{item.JOB,jdbcType=VARCHAR} as JOB,
#{item.MGR,jdbcType=INTEGER} as MGR,
#{item.HIREDATE,jdbcType=DATE} as HIREDATE,
#{item.SAL,jdbcType=DOUBLE} as SAL,
#{item.COMM,jdbcType=DOUBLE} as COMM,
#{item.DEPTNO,jdbcType=INTEGER} as DEPTNO
from dual
) tmp
on ( tmp.EMPNO = r.EMPNO)
when matched THEN
update set
r.ENAME = tmp.ENAME,
r.JOB = tmp.JOB,
r.MGR = tmp.MGR,
r.HIREDATE = tmp.HIREDATE,
r.SAL = tmp.SAL,
r.COMM = tmp.COMM,
r.DEPTNO = tmp.DEPTNO
when not matched THEN
insert
EMPNO,
ENAME,
JOB,
MGR,
HIREDATE,
SAL,
COMM,
DEPTNO
tmp.EMPNO,
tmp.ENAME,
tmp.JOB,
tmp.MGR,
tmp.HIREDATE,
tmp.SAL,
tmp.COMM,
tmp.DEPTNO
delete from scott.emp t where t.empno in
#{item}
server.port=18077
server.address=127.0.0.1
server.contextPath=/
spring.datasource.url=jdbc:oracle:thin:@127.0.0.1:1521:dev2018
spring.datasource.username=system
spring.datasource.password=oracle
spring.datasource.driver-class-name=oracle.jdbc.OracleDriver
4.0.0
come.demo.SpringBootMyBatis
SpringBootMyBatis
1.0.0
jar
SpringBootMyBatis
SpringBootMyBatis
org.springframework.boot
spring-boot-starter-parent
1.5.9.RELEASE
org.springframework.boot
spring-boot-starter-aop
org.mybatis.spring.boot
mybatis-spring-boot-starter
1.3.1
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-starter-test
test
com.oracle.ojdbc6
ojdbc6
11.2.0.3
runtime
org.springframework.boot
spring-boot-maven-plugin
com.demo.Application
repackage
org.apache.maven.plugins
maven-surefire-plugin
true
org.apache.maven.plugins
maven-compiler-plugin
3.1
true
true
${JAVA8_HOME}/bin/javac
compile