发表于: 2018-03-30 23:39:16
1 564
今天完成的事情:(一定要写非常细致的内容,比如说学会了盒子模型,了解了Margin)
一、完成不需要spring的mybatis,基本配置如下
Dao层,model和service基本不变,主要是改变了PersonServiceImpl和配置文件
public class PersonServiceImpl implements PersonService{
private SqlSession session;
private IPersonDao personDao;
@Override
public List<Person> addAndList(Person person, Map map) throws Exception {
session= SqlSessionUtil.getSqlsession();
personDao=session.getMapper(IPersonDao.class);
personDao.addPerson(person);
List<Person> personList=personDao.listPerson(map);
session.close();
return personList;
}
@Override
public List<Person> DeleteAndList(int id, Map map) throws Exception {
session= SqlSessionUtil.getSqlsession();
personDao=session.getMapper(IPersonDao.class);
personDao.deletePerson(id);
List<Person> personList=personDao.listPerson(map);
session.close();
return personList;
}
@Override
public List<Person> updateAndList(Person person, Map map) throws Exception {
session= SqlSessionUtil.getSqlsession();
personDao=session.getMapper(IPersonDao.class);
personDao.updatePerson(person);
List<Person> personList=personDao.listPerson(map);
session.close();
return personList;
}
@Override
public List<Person> justList(Map map) throws Exception {
session= SqlSessionUtil.getSqlsession();
personDao=session.getMapper(IPersonDao.class);
List<Person> personList=personDao.listPerson(map);
session.close();
return personList;
}
@Override
public int justAdd(Person person) throws Exception {
session= SqlSessionUtil.getSqlsession();
personDao=session.getMapper(IPersonDao.class);
personDao.addPerson(person);
int id=person.getId();
session.close();
return id;
}
@Override
public Boolean justDelete(int id) throws Exception {
session= SqlSessionUtil.getSqlsession();
personDao=session.getMapper(IPersonDao.class);
Boolean bl=personDao.deletePerson(id);
session.close();
return bl;
}
@Override
public Boolean justUpdate(Person person) throws Exception {
session= SqlSessionUtil.getSqlsession();
personDao=session.getMapper(IPersonDao.class);
Boolean bl=personDao.updatePerson(person);
session.close();
return bl;
}
@Override
public void deleteAll() throws Exception {
session= SqlSessionUtil.getSqlsession();
personDao=session.getMapper(IPersonDao.class);
personDao.truncatePerson();
session.close();
}
}
相比起spring整合过的,每次都需要先建立连接,创建对象,最后需要手动关闭连接,其余变化不大,下面为mybatis-config.xml和applicationContext.xml的对比
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTDConfig 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<typeAliases>
<typeAlias type="com.task.model.Person" alias="Person"/>
</typeAliases>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/test"/>
<property name="username" value="root"/>
<property name="password" value="4096"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="mappers/PersonMapper.xml"/>
</mappers>
</configuration>
<?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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<context:annotation-config />
<context:component-scan base-package="com.task.service"/>
<!-- 连接jdbc数据库所需要的数据信息-->
<bean name="dataSource" class="com.alibaba.druid.pool.DruidDataSource"
init-method="init" destroy-method="close">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/test"/>
<property name="username" value="root"/>
<property name="password" value="4096"/>
<!--初始连接数-->
<property name="initialSize" value="1" />
<!--最小连接数-->
<property name="minIdle" value="5" />
<!--最大连接数-->
<property name="maxActive" value="20" />
<!-- 配置获取连接等待超时的时间 -->
<property name="maxWait" value="60000" />
<!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->
<property name="timeBetweenEvictionRunsMillis" value="60000" />
<!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->
<property name="minEvictableIdleTimeMillis" value="300000" />
<!--用来检测是否有效的sql,要求为查询语句-->
<property name="validationQuery" value="SELECT 'x'" />
<!--宕机时申请检测,不会影响性能-->
<property name="testWhileIdle" value="true" />
<!--申请连接时检测连接是否有效,会影响性能-->
<property name="testOnBorrow" value="false" />
<!--归还连接时检测连接是否有效,会影响性能-->
<property name="testOnReturn" value="false" />
<!-- 打开PSCache,对支持游标的数据库性能提升巨大 -->
<property name="poolPreparedStatements" value="true" />
<!--打开PSCache后配置其连接数量-->
<property name="maxPoolPreparedStatementPerConnectionSize" value="20" />
<!-- 配置监控统计拦截的filters -->
<property name="filters" value="stat" />
</bean>
<!-- sqlSessionFactory类,用于创建sqlSessionFactory-->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<!--指定连接数据库的数据源-->
<property name="dataSource" ref="dataSource"/>
<!--指定mapper文件存放的位置,如果和Dao文件同名同包,可以不写此行-->
<property name="mapperLocations" value="classpath:mappers/PersonMappers.xml"/>
<!--实体类所在的包,配置别名用的-->
<property name="typeAliasesPackage" value="com.task.model"/>
</bean>
<!--数据映射器类,将PersonMapper接口加入Spring中,注意只能是接口不能是具体实现类-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.task.dao"/><!--扫描Mapper类所在包-->
<!--<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>-->
</bean>
</beans>
忽略连接池,可以看到mybatis和spring-mybatis的配置文件只是差了一个数据映射器,一个sqlSessionFactory类,也就是注入personDao,自动创建连接的两样东西,其余的都是一样的几乎。
二、重写JDBCTempelate
1.Spring对数据库的操作在jdbc上面做了深层次的封装,使用spring的注入功能,可以把DataSource注册到JdbcTemplate之中。
2.JdbcTemplate主要提供以下五类方法:
execute方法:可以用于执行任何SQL语句,一般用于执行DDL语句;
update方法及batchUpdate方法:update方法用于执行新增、修改、删除等语句;batchUpdate方法用于执行批处理相关语句;
query方法及queryForXXX方法:用于执行查询相关语句;
call方法:用于执行存储过程、函数相关语句。
3.相关结构如下
配置文件只有最下面不一样
<?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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"
init-method="init" destroy-method="close">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/test"/>
<property name="username" value="root"/>
<property name="password" value="4096"/>
<!--初始连接数-->
<property name="initialSize" value="1" />
<!--最小连接数-->
<property name="minIdle" value="5" />
<!--最大连接数-->
<property name="maxActive" value="20" />
<!-- 配置获取连接等待超时的时间 -->
<property name="maxWait" value="60000" />
<!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->
<property name="timeBetweenEvictionRunsMillis" value="60000" />
<!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->
<property name="minEvictableIdleTimeMillis" value="300000" />
<!--用来检测是否有效的sql,要求为查询语句-->
<property name="validationQuery" value="SELECT 'x'" />
<!--宕机时申请检测,不会影响性能-->
<property name="testWhileIdle" value="true" />
<!--申请连接时检测连接是否有效,会影响性能-->
<property name="testOnBorrow" value="false" />
<!--归还连接时检测连接是否有效,会影响性能-->
<property name="testOnReturn" value="false" />
<!-- 打开PSCache,对支持游标的数据库性能提升巨大 -->
<property name="poolPreparedStatements" value="true" />
<!--打开PSCache后配置其连接数量-->
<property name="maxPoolPreparedStatementPerConnectionSize" value="20" />
<!-- 配置监控统计拦截的filters -->
<property name="filters" value="stat" />
</bean>
<!--配置一个JdbcTemplate实例,并注入一个dataSource数据源-->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"></property>
</bean>
</beans>public class PersonImpl implements IPersonDao {
//增加数据
@Override
public void addPerson(Person person) {
ApplicationContext ctx=new ClassPathXmlApplicationContext("applicationContext.xml");
JdbcTemplate jdbcTemplate=(JdbcTemplate)ctx.getBean("jdbcTemplate");
String sql="insert into person1 (created_at,name,age,personId) values (?,?,?,?)";
jdbcTemplate.update(sql,new Object[]{System.currentTimeMillis(),person.getName(),person.getAge(),person.getPersonID()});
}
//修改数据
@Override
public int updatePerson(Person person) {
ApplicationContext ctx=new ClassPathXmlApplicationContext("applicationContext.xml");
JdbcTemplate jdbcTemplate=(JdbcTemplate)ctx.getBean("jdbcTemplate");
String sql="update person1 set updated_at=?,name=?,age=?,personId=? where id=?";
return jdbcTemplate.update(sql,new Object[]{System.currentTimeMillis(),person.getName(),person.getAge(),person.getPersonID(),person.getId()});
}
//删除数据
@Override
public int deletePerson(int id) {
ApplicationContext ctx=new ClassPathXmlApplicationContext("applicationContext.xml");
JdbcTemplate jdbcTemplate=(JdbcTemplate)ctx.getBean("jdbcTemplate");
String sql="delete from person1 where id=?";
return jdbcTemplate.update(sql,id);
}
//查找全部
@Override
public List<Person> selectAll() {
ApplicationContext ctx=new ClassPathXmlApplicationContext("applicationContext.xml");
JdbcTemplate jdbcTemplate=(JdbcTemplate)ctx.getBean("jdbcTemplate");
String sql="select * from person1";
RowMapper<Person> rowMapper=new BeanPropertyRowMapper<Person>(Person.class);
List<Person> personList=jdbcTemplate.query(sql,rowMapper);
return personList;
}
//按照id查找
@Override
public Person selectById(int id) {
ApplicationContext ctx=new ClassPathXmlApplicationContext("applicationContext.xml");
JdbcTemplate jdbcTemplate=(JdbcTemplate)ctx.getBean("jdbcTemplate");
String sql="select * from person1 where id=?";
RowMapper<Person> rowMapper=new BeanPropertyRowMapper<Person>(Person.class);
Person person=jdbcTemplate.queryForObject(sql,rowMapper,id);
return person;
}
//按照姓名查找
@Override
public Person selectByName(String name) {
ApplicationContext ctx=new ClassPathXmlApplicationContext("applicationContext.xml");
JdbcTemplate jdbcTemplate=(JdbcTemplate)ctx.getBean("jdbcTemplate");
String sql="select * from person1 where name=?";
RowMapper<Person> rowMapper=new BeanPropertyRowMapper<Person>(Person.class);
Person person=jdbcTemplate.queryForObject(sql,rowMapper,name);
return person;
}
}单独测试方法都是可以跑通的,但是不知道为什么几个方法一起之后就会发现只有第一个方法起作用,后面就会报错。
百度报错发现居然是因为连接被占用完了。。。终于遇到了传说中的不随手关闭连接导致没有连接可以用。。。
但是查了资料,jdbcTemplate是不需要手动关闭连接的啊,为什么还会出现这种情况呢,而且我也设置了连接池。
最后在师兄的指点下发现了原因所在,是因为我的创立spring容器的过程放在了方法内部,这样每次调用方法都会产生一个容器,占用一条连接,所以最后处理数据多了就把连接池占用完了。
调整Impl中的连接位置即可
public class PersonImpl implements IPersonDao {
ApplicationContext ctx=new ClassPathXmlApplicationContext("applicationContext.xml");
JdbcTemplate jdbcTemplate=(JdbcTemplate)ctx.getBean("jdbcTemplate");
@Override
public void addPerson(Person person) {
String sql="insert into person1 (created_at,name,age,personId) values (?,?,?,?)";
jdbcTemplate.update(sql,new Object[]{System.currentTimeMillis(),person.getName(),person.getAge(),person.getPersonID()});
}此时恢复正常,剩余的项目明天完善,还需要service层,测试类,Main方法
明天计划的事情:(一定要写非常细致的内容)
1.完善jdbcTemplate
2.总结任务一知识点
遇到的问题:(遇到什么困难,怎么解决的)
1.mybatis中间写完PersonServiceImpl第一个方法后去写Main,试了下可以,全都写完再去试却发现死活跑不通,一直空指针异常,最后调试完发现是因为每个方法前都需要获取session和personDao,我只有第一个记得获取了,后面的都没获取,所以一致空指针。从这也可以看出来,spring整合过之后习惯性变得不先获取personDao,体现出了spring整合完的确方便很多。
2.就是晚上的spring容器创建重复问题,在方法内和方法外连接获取容器其实是不一样的
收获:(通过今天的学习,学到了什么知识)
1.了解了jdbcTemplate
2.对于spring容器这一概念了解更深入了
评论