SpringJDBC是Spring对JDBC的封装,可以避免使用JDBC时的一些重复代码,如获取连接、关闭连接等操作。
spring-webmvc,spring-jdbc, ojdbc,dbcp,junit
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="ds"/>
bean>
通常将JdbcTemplate注入到DAO中,方便使用。
实现一个基于spring-jdbc的增删改查实例。
package com.nc.springJdbc.DAO;
import com.nc.springJdbc.entity.Emp;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Repository;
import javax.annotation.Resource;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
/**
* @ program: SpringJdbc
* @ description:
* @ create: 2020-08-20 14:37
**/
@Repository("empDAO")
public class EmpDAO {
@Resource(name = "jdbcTemplate")
private JdbcTemplate jdbcTemplate;
public void save(Emp emp){
String sql = "INSERT INTO emp VALUES(emp_seq.nextval,?,?)";
Object[] params = new Object[]{emp.getName(), emp.getAge()};
jdbcTemplate.update(sql, params);
}
//告诉jdbcTemplate如何将ResultSet中的一条记录转换成对应的Entity对象。
class EmpRowMapper implements RowMapper<Emp> {
@Override
public Emp mapRow(ResultSet resultSet, int i) throws SQLException {
/**
* @Author: NiuChen
* @Date: 2020/8/20 15:34
* @param resultSet: 要处理的结果集
* @param i: 当前正在处理的记录的下标
* @return: com.nc.springJdbc.entity.Emp
**/
Emp emp = new Emp();
emp.setId(resultSet.getInt("id"));
emp.setName(resultSet.getString("name"));
emp.setAge(resultSet.getInt("age"));
return emp;
}
}
public List<Emp> findAll(){
List<Emp> emps = new ArrayList<Emp>();
String sql = "SELECT * FROM emp";
EmpRowMapper rowMapper = new EmpRowMapper();
emps = jdbcTemplate.query(sql, rowMapper);
return emps;
}
public Emp findById(int id){
Emp emp = null;
String sql = "SELECT * FROM emp WHERE id=?";
Object[] args = new Object[]{id};
// emp = jdbcTemplate.queryForObject(sql, args, new EmpRowMapper());
List<Emp> emps = jdbcTemplate.query(sql, args, new EmpRowMapper());
if (emps != null && emps.size() > 0){
emp = emps.get(0);
}
return emp;
}
public void modify(Emp emp){
String sql = "UPDATE emp SET name=?,age=? WHERE id=?";
Object[] args = new Object[]{emp.getName(), emp.getAge(), emp.getId()};
jdbcTemplate.update(sql, args);
}
public void delete(int id){
String sql = "DELETE FROM emp WHERE id=?";
Object[] args = new Object[]{id};
jdbcTemplate.update(sql, args);
}
}
MyBatis是一款开源的持久层框架,底层仍然是JDBC,性能比JDBC较弱一些,但是相较于JDBC代码更简洁。
mybatis、ojdbc、junit
<dependencies>
<dependency>
<groupId>org.mybatisgroupId>
<artifactId>mybatisartifactId>
<version>3.2.8version>
dependency>
<dependency>
<groupId>junitgroupId>
<artifactId>junitartifactId>
<version>4.13version>
dependency>
<dependency>
<groupId>com.oracle.ojdbcgroupId>
<artifactId>ojdbc8artifactId>
<version>19.3.0.0version>
dependency>
dependencies>
<configuration>
<environments default="environment">
<environment id="environment">
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<property name="driver" value="oracle.jdbc.OracleDriver" />
<property name="url" value="jdbc:oracle:thin:@127.0.0.1:1521/orcl" />
<property name="username" value="nc" />
<property name="password" value="nc940306" />
dataSource>
environment>
environments>
configuration>
根据数据库字段构建自己的实体类,要求属性名和表字段名必须一致
public class Emp {
private Integer id;
private String name;
private Integer age;
@Override
public String toString() {
return "Emp{" +
"id=" + id +
", name='" + name + '\'' +
", age=" + age +
'}';
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
}
<mapper namespace="test">
<insert id="save" parameterType="com.niuchen.mybatis.entity.Emp">
INSERT INTO emp VALUES(emp_seq.nextval,#{name},#{age})
insert>
<select id="findAll" resultType="com.niuchen.mybatis.entity.Emp">
SELECT * FROM emp
select>
<select id="findById" parameterType="int" resultType="com.niuchen.mybatis.entity.Emp">
SELECT * FROM emp WHERE id=#{id}
select>
<update id="modify" parameterType="com.niuchen.mybatis.entity.Emp">
UPDATE emp SET name=#{name}, age=#{age} WHERE id=#{id}
update>
<delete id="delete" parameterType="int">
DELETE FROM emp WHERE id=#{id}
delete>
<select id="findById2" parameterType="int" resultType="map">
SELECT * FROM emp WHERE id=#{id}
select>
mapper>
完成后修改SqlMapConfig配置文件,指定映射文件的位置。
<mappers>
<mapper resource="EmpMapper.xml"/>
mappers>
import junit.framework.TestCase;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Before;
import org.junit.Test;
import java.util.List;
import java.util.Map;
public class testCase {
private SqlSession sqlSession;
@Before
public void init(){
SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
SqlSessionFactory sqlSessionFactory =
sqlSessionFactoryBuilder.build(TestCase.class
.getClassLoader().getResourceAsStream("SqlMapConfig.xml"));
sqlSession= sqlSessionFactory.openSession();
}
@Test
public void test1(){
Emp emp = new Emp();
emp.setName("Eric");
emp.setAge(18);
sqlSession.insert("test.save", emp);
// 提交事务
sqlSession.commit();
sqlSession.close();
}
@Test
public void test2(){
List<Emp> emps = sqlSession.selectList("test.findAll");
System.out.println(emps);
sqlSession.close();
}
@Test
public void test3(){
Emp emp = sqlSession.selectOne("test.findById", 21);
System.out.println(emp);
sqlSession.close();
}
@Test
public void test4(){
Emp emp = sqlSession.selectOne("test.findById", 21);
emp.setName("Moran");
emp.setAge(20);
sqlSession.update("test.modify", emp);
// 提交事务
sqlSession.commit();
sqlSession.close();
}
@Test
public void test5(){
sqlSession.delete("test.delete", 21);
// 提交事务
sqlSession.commit();
sqlSession.close();
}
}
通常,mybatis会将查询结果先封装到一个Map对象,然后将Map对象中的数据添加到实体对象中。
我们也可以获取到Map对象,下面是获取方式:
如果实体类属性名与数据库表中字段名不一致,可以使用ResultMap解决或在映射文件中的写SQL语句时可以用别名。
<select id="findById3" parameterType="int" resultMap="empMap">
SELECT * FROM emp WHERE id=#{id}
select>
<resultMap id="empMap" type="com.niuchen.mybatis.entity.Emp">
<result property="ename" column="name"/>
<result property="empNo" column="id"/>
resultMap>
获取Map类型数据
@Test
public void test6(){
Map data = sqlSession.selectOne("test.findById2", 22);
System.out.println(data);
System.out.println(data.get("NAME"));
sqlSession.close();
}
Mapper映射器
Mapper映射器是指符合映射文件要求的接口。
要求:
以下给出简单示例:
EmpDAO .java
public interface EmpDAO {
public void save(Emp emp);
public List<Emp> findAll();
}
EmpDAOMapper.xml
<mapper namespace="com.niuchen.mybatis.dao.EmpDAO">
<insert id="save" parameterType="com.niuchen.mybatis.entity.Emp">
INSERT INTO emp VALUES(emp_seq.nextval,#{name},#{age})
insert>
<select id="findAll" resultType="com.niuchen.mybatis.entity.Emp">
SELECT * FROM emp
select>
<select id="findById" parameterType="int" resultType="com.niuchen.mybatis.entity.Emp">
SELECT * FROM emp WHERE id=#{id}
select>
<update id="modify" parameterType="com.niuchen.mybatis.entity.Emp">
UPDATE emp SET name=#{name}, age=#{age} WHERE id=#{id}
update>
<delete id="delete" parameterType="int">
DELETE FROM emp WHERE id=#{id}
delete>
<select id="findById2" parameterType="int" resultType="map">
SELECT * FROM emp WHERE id=#{id}
select>
mapper>
测试
@Test
public void test7(){
EmpDAO dao = sqlSession.getMapper(EmpDAO.class);
Emp emp = new Emp();
emp.setName("Lily");
emp.setAge(22);
dao.save(emp);
sqlSession.commit();
sqlSession.close();
}
MyBatis会自动实现一个符合该接口要求的对象。