week 5.11-5.17
- | Study-update |
---|---|
-Mon | Spring-jdbc,使用Spring容器管理jdbcTemplate进行增删改查,使用JdbcDaoSupport修改Dao和Spring读取配置文件 |
-Tue | Spring外部配置,Spring中的事务(xml版) |
-Wes | 注解版事务,Spring整合mybatis |
-Thu | - |
-Fri | mybatis复习 |
-Sat | |
-Sun | mybatis复习,bean的工厂模式 |
5.11 Monday
Spring jdbc
UserDao接口
/**
* @author lzr
* @date 2020 05 10 22:03
* @description
*/
public interface UserDao {
//根据id查找用户
public User selectUserById(int id);
}
UserDao实现
/**
* @author lzr
* @date 2020 05 10 22:03
* @description
*/
public class UserDaoImpl implements UserDao{
private static ComboPooledDataSource pooledDataSource;
static {
//配置c3p0 连接数据库
try {
pooledDataSource=new ComboPooledDataSource();
pooledDataSource.setDriverClass("com.mysql.jdbc.Driver");
pooledDataSource.setJdbcUrl("jdbc:mysql://localhost:3306/webtest");
pooledDataSource.setUser("root");
pooledDataSource.setPassword("root");
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public User selectUserById(int id) {
JdbcTemplate jt = new JdbcTemplate(pooledDataSource);
String sql="select * from user where id=?";
User user=jt.queryForObject(sql, new RowMapper<User>(){
@Override
public User mapRow(ResultSet resultSet, int i) throws SQLException {//配置rowMapper
User user = new User();
user.setId(resultSet.getInt(1));
user.setUserName(resultSet.getString(2));
user.setPassword(resultSet.getString(3));
return user;
}
},id);
return user;
}
}
测试
ublic class JdbcTestTest {
@Test
public void test1() {
UserDao userDao=new UserDaoImpl();
User user=userDao.selectUserById(5);
System.out.println(user);
}
}
UserApplicationContext
<!--依赖关系 dao->jdbcTemplate->dataSource-->
<!--dataSource-->
<bean name="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="com.mysql.jdbc.Driver"/>
<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/webtest"/>
<property name="user" value="root"/>
<property name="password" value="root"/>
</bean>
<!--jdbcTemplate-->
<bean name="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"/>
</bean>
<!--dao-->
<bean name="UserDaoImpl" class="com.maaoooo.dao.UserDaoImpl">
<property name="jt" ref="jdbcTemplate"/>
</bean>
</beans>
UserDao
/**
* @author lzr
* @date 2020 05 10 22:03
* @description
*/
public class UserDaoImpl implements UserDao{
// private static ComboPooledDataSource pooledDataSource;
JdbcTemplate jt;
// static {
// //配置c3p0 连接数据库
// try {
// pooledDataSource=new ComboPooledDataSource();
// pooledDataSource.setDriverClass("com.mysql.jdbc.Driver");
// pooledDataSource.setJdbcUrl("jdbc:mysql://localhost:3306/webtest");
// pooledDataSource.setUser("root");
// pooledDataSource.setPassword("root");
// } catch (Exception e) {
// e.printStackTrace();
// }
// }
//保存用户
@Override
public void saveUser(User u) {
String sql="insert into user value(null,?,?)";
jt.update(sql,u.getUserName(),u.getPassword());
}
public void setJt(JdbcTemplate jt) {
this.jt = jt;
}
//删除用户
@Override
public void deleteUser(int id) {
String sql="delete from user where id=?";
jt.update(sql,id);
}
//更新用户
@Override
public void updateUser(User u) {
String sql="update user set username=?,password=? where id=?";
jt.update(sql,u.getUserName(),u.getPassword(),u.getId());
}
//根据id查询用户
@Override
public User selectUserById(int id) {
String sql="select * from user where id=?";
User user=jt.queryForObject(sql, new RowMapper<User>(){
@Override
public User mapRow(ResultSet resultSet, int i) throws SQLException {
User user = new User();
user.setId(resultSet.getInt(1));
user.setUserName(resultSet.getString(2));
user.setPassword(resultSet.getString(3));
return user;
}
},id);
return user;
}
//查询全部用户
@Override
public List<User> selectAllUser() {
String sql="select * from user";
List<User> userList=jt.query(sql, new RowMapper<User>() {
@Override
public User mapRow(ResultSet resultSet, int i) throws SQLException {
User u=new User();
u.setId(resultSet.getInt("id"));
u.setUserName(resultSet.getString("username"));
u.setPassword(resultSet.getString("password"));
return u;
}
});
return userList;
}
//查询用户数量
@Override
public int selectUserCount() {
String sql="select count(*) from user";
int count=jt.queryForObject(sql,int.class);
return count;
}
}
测试
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:ApplicationContext.xml")
public class JdbcTestTest {
@Autowired
private UserDaoImpl userDao;
//通过id查找用户
@Test
public void test1() {
User user=userDao.selectUserById(5);
System.out.println(user);
}
//增
@Test
public void test2() {
User user = new User();
user.setUserName("996");
user.setPassword("777");
userDao.saveUser(user);
}
//删
@Test
public void test3(){
userDao.deleteUser(6);
}
//改
@Test
public void test4(){
User user = new User(7,"BKB","wudi");
userDao.updateUser(user);
}
//查找全部用户
@Test
public void test5(){
List<User> userList=new ArrayList<User>();
userList=userDao.selectAllUser();
for (User user : userList) {
System.out.println(user);
}
}
//查看用户数量
@Test
public void test6(){
int count=userDao.selectUserCount();
System.out.println("用户数量是:"+count+"个.");
}
}
5.12 Tuesday
ApplicationContext 配置
<context:property-placeholder location="db.properties"/>
db.properties
jdbc.driverClass=com.mysql.jdbc.Driver
jdbc.jdbcUrl=jdbc:mysql://localhost:3306/webtest
jdbc.user=root
jdbc.password=root
事务相关知识
什么是事务:把多条数据库操作绑定在一起执行,要么都成功要么失败。
事务的原则ACID
原子性:事务包含的所有操作,要么全部成功写入数据库,要么失败全部回滚,失败不能对数据库有影响。
一致性:事务在执行前和执行后必须一致,A和B互相转账,无论怎么转,总额必须相同。
并发性:多个用户同时并发访问同一张表事,数据库为每一个用户开启新事务,事务之间不能相互影响,相互有隔离。
持久性:事务一旦提交,对数据库的影响是永久的,即使系统故障也不会丢失。
并发可能会引发的问题
脏读:一个事务读取到另一个事务未提交的数据
不可重复读:一个事务读取到另一个事务已提交(update)的数据,导致前后读不一样
幻读:一个事务读取到别的事务插入(insert)的数据,导致前后读不一样
AccountApplicationContext
<!--依赖关系 service->dao->dataSource-->
<context:property-placeholder location="db.properties"/>
<bean name="datasource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${jdbc.driverClass}"/>
<property name="jdbcUrl" value="${jdbc.jdbcUrl}"/>
<property name="user" value="${jdbc.user}"/>
<property name="password" value="${jdbc.password}"/>
<!--dao-->
</bean>
<bean name="acountDao" class="com.maaoooo.dao.AccountDaoImpl">
<property name="dataSource" ref="datasource"/>
</bean>
<!--service-->
<bean name="accountService" class="com.maaoooo.service.AccountServiceImpl">
<property name="accountDao" ref="acountDao"/>
</bean>
<!--配置事务核心管理器 不同平台不一样-->
<bean class="org.springframework.jdbc.datasource.DataSourceTransactionManager" name="TransactionManager">
<property name="dataSource" ref="datasource"/>
</bean>
<!--事务通知-->
<tx:advice id="txAccount" transaction-manager="TransactionManager">
<tx:attributes>
<tx:method name="transferAccount"/>
</tx:attributes>
</tx:advice>
<!--aop切面-->
<aop:config>
<aop:pointcut id="txpc" expression="execution(* com.maaoooo.service.*ServiceImpl.*(..))"/>
<aop:advisor advice-ref="txAccount" pointcut-ref="txpc"/>
</aop:config>
5.13 Wedesday
注解版事务
1,配置事务核心管理器
<!--配置事务核心管理器 不同平台不一样-->
<bean class="org.springframework.jdbc.datasource.DataSourceTransactionManager" name="transactionManager">
<property name="dataSource" ref="datasource"/>
</bean>
2.开启注解事务
<!--开启注解事务-->
<tx:annotation-driven/>
3,在service实现类打上注解
/**
* @author lzr
* @date 2020/5/12 15:26:49
* @description
*/
//全体配置
@Transactional(isolation = Isolation.DEFAULT,propagation = Propagation.REQUIRED,readOnly = true)
public class AccountServiceImpl implements AccountService{
//AccountDao账户dao
private AccountDao accountDao;
public void setAccountDao(AccountDao accountDao) {
this.accountDao = accountDao;
}
@Override
@Transactional(isolation = Isolation.DEFAULT,propagation = Propagation.REQUIRED,readOnly = false)//具体配置
public void transferAccount() {
//转账逻辑
//先给A账户扣款
accountDao.subMoney(1,50d);
// int i=1/0;
//再给B账户加钱
accountDao.addMoney(2,50d);
}
}
Spring整合mybatis
<?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.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
<!--数据源-->
<context:property-placeholder location="classpath:springConfig/db.properties"/>
<bean name="datasource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${jdbc.driverClass}"/>
<property name="jdbcUrl" value="${jdbc.jdbcUrl}"/>
<property name="user" value="${jdbc.user}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
<!--mybatis-->
<bean class="org.mybatis.spring.SqlSessionFactoryBean" name="sqlSessionFactory">
<property name="dataSource" ref="datasource"/>
<property name="configLocation" value="classpath:mabatisConfig/sqlMapperConfig.xml"/>
</bean>
<!--mapper工厂-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.maaoooo.mapper"/>
</bean>
</beans>
5.15 Friday
什么是框架?
JDBC:
Connection,preparedStatement,ResultSet
Sping的JDBC Template:
Spring中对JDBC的简单封装
Apache的DBUtils:
和Spring的Template相似,也是对JDBC的简单封装。
以上都不是框架,JDBC是规范,其他两个是工具类。
Mybatis 是一个持久层框架,使用java编写,它封装了很多细节,是我们专注于sql语句本身,而不用关注驱动注册,建立连接等繁杂过程。
它使用了ORM思想实现了结果集的封装。Object Relational Mapping,对象关系映射,就是把数据库表和实体类及实体类的属性对应起来,让我们可以实现操作实体类就操作数据库表.
mybatis的环境搭建
1,创建maven工程,并添加依赖 2,生成实体类和dao层接口 3,配置mybatis主配置文件sqlMapConfig 4,配置映射配置文件Mapper.xml.
mybatis主配置文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<!--mybatis的主配置文件-->
<configuration>
<!--配置环境-->
<environments default="">
<!--配置mysql的环境-->
<environment id="mysql">
<!--配置事务的类型-->
<transactionManager type="JDBC"></transactionManager>
<!--配置数据源 也叫连接池-->
<dataSource type="POOLED">
<!--配置连接数据库的4个基本信息-->
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/eesy_mybatis"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</dataSource>
</environment>
</environments>
<!--指定映射配置文件的位置-->
<mappers>
<!--resource用于指定文件位置-->
<mapper resource="com/maaoooo/bean/UserMapper.xml"/>
</mappers>
</configuration>
5.17 Sunday
通过代理增强方法,所以才不用写dao的实现类
public class MybatisTest {
/**
* 测试
*/
public static void main(String[] args) {
//读取配置文件
InputStream in= null;
try {
in = Class.forName("MybatisTest").getClassLoader().getResourceAsStream("SqlMapConfig.xml");
} catch (ClassNotFoundException e) {
System.out.println("读取配置文件失败");
e.printStackTrace();
}
//创建sqlSessionFactoryBuilder
SqlSessionFactoryBuilder ssfb=new SqlSessionFactoryBuilder();
//创建sqlSessionFactory
SqlSessionFactory ssf=ssfb.build(in);
//生产Session
SqlSession session=ssf.openSession();
//操作数据库 (实际上通过代理进行方法增强)
UserMapper userMapper=session.getMapper(UserMapper.class);
List<User> userList=userMapper.findAll();
//遍历集合
for (User user : userList) {
System.out.println(user.toString());
}
}
}
一个创建bean的工厂:
bean在计算机英语中有可重用组件的意思。
javabean:用java语言编写的可重用对象。
如何创建service和dao对象?
1,需要一个配置文件来配置service和dao。配置的内容:唯一标识=全限定名(key=value)
2,通过读取配置文件中的配置,反射创建对象。
配置文件可以是xml或者properties.
/**
* @author lzr
* @date 2020 05 17 17:25
* @description 工厂模式
*/
public class BeanFactory {
//定义一个properties对象
private static Properties properties;
static {
//实例化对象
properties=new Properties();
//获取properties文件的流对象
InputStream in= BeanFactory.class.getClassLoader().getResourceAsStream("bean.properties");
try {
properties.load(in);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 根据bean的名称获取bean对象
* @param beanName
* @return
*/
public static Object getBean(String beanName) throws ClassNotFoundException, IllegalAccessException, InstantiationException {
Object bean;
String beanPath=properties.getProperty(beanName);
bean=Class.forName(beanPath).newInstance();
return bean;
}
}
/**
* @author lzr
* @date 2020 05 17 13:10
* @description
*/
public class AccountServiceImpl implements IAccountService {
// private AccountDaoImpl accoutDao=new AccountDaoImpl();
//使用bean工厂获取对象
private IAccountDao accountDao= ((IAccountDao) BeanFactory.getBean("accountDao"));
public AccountServiceImpl() throws IllegalAccessException, InstantiationException, ClassNotFoundException {
}
public void save() {
accountDao.save();
}
}