Day56

Spring整合JdbcTemplate及Mybatis和Spring整合Mybatis

1、jdbcTemplate

1.1、概述

它是 spring 框架中提供的一个对象,是对原始 Jdbc API 对象的简单封装。spring 框架为我们提供了很多的操作模板类。

操作关系型数据的:

JdbcTemplate

HibernateTemplate

操作 nosql 数据库的:

RedisTemplate

操作消息队列的:

JmsTemplate

我们今天的主角在 spring-jdbc.jar 中,我们在导包的时候,除了要导入这个 jar 包 外,还需要导入一个 spring-tx.jar(它是和事务相关的)。

1.2、jdbcTemplate对象创建

我们可以参考它的源码,来一探究竟:

public JdbcTemplate() { } public JdbcTemplate(DataSource dataSource) { setDataSource(dataSource); afterPropertiesSet(); } public JdbcTemplate(DataSource dataSource, boolean lazyInit) { setDataSource(dataSource); setLazyInit(lazyInit); afterPropertiesSet(); }

除了默认构造函数之外,都需要提供一个数据源。既然有set方法,依据我们之前学过的依赖注入,我们可以在配置文件中配置这些对象

1.3、配置数据源

1.3.1、环境搭建

1.3.2、配置文件

<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">   </beans>

1.3.3、配置DBCP数据源

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver"></property> <property name="url" value="jdbc:mysql://localhost:3306/ssm"></property> <property name="username" value="root"></property> <property name="password" value="root"></property> </bean>

Spring 框架也提供了一个内置数据源,我们也可以使用 spring 的内置数据源,它就在spring-jdbc.jar中

 <!-- 配置数据源--> <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">         <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>         <property name="url" value="jdbc:mysql://localhost:3306/ssm"></property>         <property name="username" value="root"></property>         <property name="password" value="root"></property> </bean>

以上这两种都可以使用,任意选一种即可。

1.4、增删改查

1.4.1、配置jdbcTemplate

<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans         http://www.springframework.org/schema/beans/spring-beans.xsd">     <!-- 配置一个数据库的操作模板:JdbcTemplate --> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> <property name="dataSource" ref="dataSource"></property> </bean>   <!-- 配置数据源 --> <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver"></property> <property name="url" value="jdbc:mysql://localhost:3306/ssm"></property> <property name="username" value="root"></property> <property name="password" value="root"></property> </bean> </beans>

1.4.2、基本用法

public static void main(String[] args) { DriverManagerDataSource ds = new DriverManagerDataSource(); ds.setDriverClassName("com.mysql.jdbc.Driver"); ds.setUrl("jdbc:mysql://localhost:3306/ssm"); ds.setUsername("root"); ds.setPassword("root"); //1.创建JdbcTemplate对象 JdbcTemplate jt = new JdbcTemplate(); //给jt设置数据源 jt.setDataSource(ds); //2.执行操作 jt.execute("insert into t_user(username,password)values('ccc','aaa')"); }

1.4.2、Spring整合后的基本用法

ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); JdbcTemplate jt = (JdbcTemplate) context.getBean("jdbcTemplate"); //jdbcTemplate.execute("insert into t_user(username,password)values('张美玲','888')"); // 查询所有 List<User> accounts = jt.query("select * from t_user",new UserRowMapper()); for (User account : accounts) { System.out.println(account); } System.out.println("--------"); User user = jt.queryForObject("select * from t_user where id = ?",new BeanPropertyRowMapper<User>(User.class),1); System.out.println(user); System.out.println("--------"); //返id大于3的总条数 Integer count = jt.queryForObject("select count(*) from t_user where id > ?", Integer.class, 3); System.out.println(count); //多条件查询 、模糊查询 List<User> ulist = jt.query("select * from t_user where t_user.username like ? and nickname like ? ",new UserRowMapper(),new Object[]{"%a%","%a%"}); System.out.println(ulist.size()); for (User user1 : ulist) { System.out.println(user1); }

定义User的封装策略

public class UserRowMapper implements RowMapper<User> { @Override public User mapRow(ResultSet rs, int i) throws SQLException { User u = new User(); u.setId(rs.getInt("id")); u.setUsername(rs.getString("username")); return u; } }

1.5、Dao中添加JdbcTemplate

1.5.1、实体类

public class User { private Integer id; private String username; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } @Override public String toString() { return "User{" + "id=" + id + ", username='" + username + '\'' + '}'; } }

1.5.2、定义IUserDao接口

public interface IUserDao { //添加一条用户信息 void add(User user); //根据id删除一条数据 void delete(Integer id); //修改一条数据 void update(User user); //根据条件查询用户信息列表 List<User> getUserList(User user); //根据id查询一条数据 User getUserById(Integer id); //获取总条数 Integer getListCount(); }

1.5.3、在UserDaoImpl实现类中添加jdbcTemplate

public class UserDaoImpl implements IUserDao { private JdbcTemplate jdbcTemplate; @Override public void add(User user) { String sql = " insert into t_user(username) values('"+user.getUsername()+"') "; jdbcTemplate.execute(sql); } @Override public void delete(Integer id) { String sql = "delete from t_user where id = "+id+""; jdbcTemplate.execute(sql); } @Override public void update(User user) { String sql = "update t_user set username = '"+user.getUsername()+"' where id = "+user.getId()+""; jdbcTemplate.execute(sql); } @Override public List<User> getUserList(User user) { String sql = " select * from t_user where 1=1 "; if(user.getUsername()!=null){ sql += "and username like '%"+user.getUsername()+"%'"; } return jdbcTemplate.query(sql,new UserRowMapper()); } @Override public User getUserById(Integer id) { String sql = " select * from t_user where id = "+id+" "; return jdbcTemplate.queryForObject(sql,new UserRowMapper()); } @Override public Integer getListCount() { String sql = "select count(*) from t_user where username like '%美%'"; return jdbcTemplate.queryForObject(sql,Integer.class); } public void setJdbcTemplate(JdbcTemplate jdbcTemplate) { this.jdbcTemplate = jdbcTemplate; } }

1.5.4、在配置文件中给UserDaoImpl注入jdbcTemplate

<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans         http://www.springframework.org/schema/beans/spring-beans.xsd">   <!-- 配置账户的持久层 --> <bean id="accountDao" class="com.tledu.dao.impl.UserDaoImpl"> <property name="jdbcTemplate" ref="jdbcTemplate"></property> </bean>   <!-- 配置一个数据库的操作模板:JdbcTemplate --> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> <property name="dataSource" ref="dataSource"></property> </bean>   <!-- 配置数据源 --> <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver"></property> <property name="url" value="jdbc:mysql://localhost:3306/ssm"></property> <property name="username" value="root"></property> <property name="password" value="root"></property> </bean> </beans>

1.5.5、测试

ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); JdbcTemplate jt = (JdbcTemplate) context.getBean("jdbcTemplate"); //jdbcTemplate.execute("insert into t_user(username,password)values('张美玲','888')"); // 查询所有 List<User> accounts = jt.query("select * from t_user",new UserRowMapper()); for (User account : accounts) { System.out.println(account); } System.out.println("--------"); //根据id查询一条数据 User user = jt.queryForObject("select * from t_user where id = ?",new BeanPropertyRowMapper<User>(User.class),1); System.out.println(user); System.out.println("--------"); //返id大于3的总条数 Integer count = jt.queryForObject("select count(*) from t_user where id > ?", Integer.class, 3); System.out.println(count); //多条件查询 、模糊查询 List<User> ulist = jt.query("select * from t_user where t_user.username like ? and nickname like ? ",new UserRowMapper(),new Object[]{"%a%","%a%"}); System.out.println(ulist.size()); for (User user1 : ulist) { System.out.println(user1); }

1.5.6、思考:

此种方式有什么问题吗?

答案:

有个小问题。就是我们的 dao 有很多时,每个 dao 都有一些重复性的代码。下面就是重复代码:

private JdbcTemplate jdbcTemplate;

public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {

this.jdbcTemplate = jdbcTemplate;

}

能不能把它抽取出来呢?请看下一小节。

1.5.7、继承JdbcDaoSupport

JdbcDaoSupport 是 spring 框架为我们提供的一个类,该类中定义了一个 JdbcTemplate 对象,我们可以直接获取使用,但是要想创建该对象,需要为其提供一个数据源:

具体源码如下:   public abstract class JdbcDaoSupport extends DaoSupport { //定义对象 private JdbcTemplate jdbcTemplate; //set 方法注入数据源,判断是否注入了,注入了就创建 JdbcTemplate public final void setDataSource(DataSource dataSource) { if (this.jdbcTemplate == null || dataSource != this.jdbcTemplate.getDataSource()) { //如果提供了数据源就创建 JdbcTemplate this.jdbcTemplate = createJdbcTemplate(dataSource); initTemplateConfig(); } } //使用数据源创建 JdcbTemplate protected JdbcTemplate createJdbcTemplate(DataSource dataSource) { return new JdbcTemplate(dataSource); } //当然,我们也可以通过注入 JdbcTemplate 对象 public final void setJdbcTemplate(JdbcTemplate jdbcTemplate) { this.jdbcTemplate = jdbcTemplate; initTemplateConfig(); } //使用 getJdbcTmeplate 方法获取操作模板对象 public final JdbcTemplate getJdbcTemplate() { return this.jdbcTemplate; }

1.5.8、UserDaoImpl实现类继承JdbcDaoSupport

public class UserDaoImpl2 extends JdbcDaoSupport implements IUserDao { //private JdbcTemplate jdbcTemplate; @Override public void add(User user) { String sql = " insert into t_user(username) values('"+user.getUsername()+"') "; super.getJdbcTemplate().execute(sql); } @Override public void delete(Integer id) { String sql = "delete from t_user where id = "+id+""; super.getJdbcTemplate().execute(sql); }

1.5.9、在applicationContext.xml中给UserDaoImpl注入dataSource

<bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver"></property> <property name="url" value="jdbc:mysql://localhost:3306/ssm"></property> <property name="username" value="root"></property> <property name="password" value="root"></property> </bean> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> <property name="dataSource" ref="dataSource"></property> </bean> <bean id="userDao" class="com.tledu.dao.impl.UserDaoImpl2"> <!--<property name="jdbcTemplate" ref="jdbcTemplate"></property>--> <property name="dataSource" ref="dataSource"></property> </bean>

1.5.10、测试

public class UserDaoImplTest2 { private ApplicationContext context; @Before public void before(){ context = new ClassPathXmlApplicationContext("applicationContext.xml"); } @Test public void add(){ IUserDao userDao = context.getBean(UserDaoImpl2.class); User user = new User(); user.setUsername("乔森"); userDao.add(user); } @Test public void delete(){ IUserDao userDao = context.getBean(UserDaoImpl2.class); userDao.delete(26); }

MyBatis相信很多人都会使用,但是当MyBatis整合到了Spring中,我们发现在Spring中使用更加方便了。例如获取Dao的实例,在Spring的我们只需要使用注入的方式就可以了使用Dao了,完全不需要调用SqlSession的getMapper方法去获取Dao的实例,更不需要我们去管理SqlSessionFactory,也不需要去创建SqlSession之类的了,对于插入操作也不需要我们commit。

既然那么方便,Spring到底为我们做了哪些工作呢,它如何将MyBatis整合到Spring中的呢,Spring在整合MyBatis时候做了哪些封装,以及做了哪些拓展,又是怎么实现这些封装以及拓展的,让我们来打开这一部分的源代码,一探究竟。

1、搭建环境

在Spring基础包之上,需要引入AOP、数据库连接池、MyBatis、MySQL、MyBatis-Spring以及jdbc和tx。

2、配置applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"> <!-- 引入AOP约束 --> <!-- 使用注解方式 --> <context:annotation-config /> <context:component-scan base-package="com.tledu" /> <!-- 引入jdbc配置文件 --> <context:property-placeholder location="classpath:jdbc.properties" /> <!-- 数据库连接池 --> <bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource"> <property name="driverClassName" value="${driver}"></property> <property name="url" value="${url}"></property> <property name="username" value="${user}"></property> <property name="password" value="${password}"></property> </bean> <!-- SqlSessionFactory配置 --> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource"></property> <property name="typeAliasesPackage" value="com.tledu.modle"></property> <property name="mapperLocations" value="classpath:com/tledu/mapper/*.xml"></property> <!--<property name="configLocation" value="classpath:mybatis-config.xml"></property>--> </bean> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <!--这是错误的一种方式,因为在注入sqlSessionFactory前${driver}并没有解析--> <!--<property name="sqlSessionFactory" ref="sqlSessionFactory" />--> <property name="basePackage" value="com.tledu.mapper" /> </bean> </beans>

3、创建UserMapper.xml放在与UserMapper接口同一个包下

<?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.tledu.mapper.UserMapper"> <insert id="add" parameterType="User" > insert into t_user (username,password,nickname,type) values (#{username},#{password},#{nickname},#{type}) </insert> <delete id="delete" parameterType="int"> delete from t_user where id = #{id} </delete> <update id="update" parameterType="User"> update t_user set username = #{username},password = #{password} where id = #{id} </update> <select id="getUserList" resultType="User"> select * from t_user; </select> <select id="getUserById" parameterType="int" resultType="User"> select * from t_user where id = #{id}; </select> </mapper>

4、创建项目结构如图,在UserServiceImpl中注入UserMapper对象

5、测试

public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); IUserService userService = (IUserService) context.getBean("userService"); List<User> ulist = userService.getUserList(); for (User user : ulist) { System.out.println(user); } 、 }

6、加入事务控制

6.1、xml方式

6.1.1、在applicationContext.xml中加入如下配置

<!--配置事务--> <bean name="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource" /> </bean> <!--配置事务通知--> <!-- name:指定要通知的方法 read-only:表示当前方法是否为读数据 isolation:隔离级别 propagation:事务传播行为默认值为 REQUIRED --> <tx:advice id="txAdvice" transaction-manager="transactionManager"> <tx:attributes> <tx:method name="add*" read-only="false" isolation="DEFAULT" propagation="REQUIRED" /> </tx:attributes> </tx:advice> <!--使用aop配置切点对指定的切点进行事务通知--> <aop:config> <aop:pointcut id="pointCut" expression="execution(public * com.tledu.service..*.*(..))"/> <aop:advisor advice-ref="txAdvice" pointcut-ref="pointCut" ></aop:advisor> </aop:config>

属性详解:Spring管理事务 - 程序员大本营

6.1.2、在UserServiceImpl实现类中的add方法添加如下

@Override public void add(User user) { userMapper.add(user); User u = new User(); u.setUsername("yyyyyyyyyyyyyyyyyyyyyyy");//长度超过设置的长度 u.setPassword("123456"); userMapper.add(u); }

6.1.3、测试

ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); IUserService userService = (IUserService) context.getBean("userService"); User user = new User(); user.setUsername("赵四"); user.setNickname("本山"); user.setType(1); userService.add(user);

6.1.4、结果

加入事物控制后两次添加的数据其中有一次添加有异常整个事物将不能被提交,没有加事物时会将没有问题的数据添加成功。

6.2、注解方式

6.2.1、在applicationContext.xml中加入如下配置

<!--配置事务--> <bean name="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource" /> </bean> <!--开启事务的注解支持--> <tx:annotation-driven transaction-manager="transactionManager"></tx:annotation-driven>

6.2.2、在UserServiceImpl实现类中的add方法上添加注解

@Override @Transactional(readOnly = false,propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT) public void add(User user) { User u = new User(); u.setUsername("yyyyyy"); u.setPassword("123456"); userMapper.add(u); userMapper.add(user); }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值