title: mybkstore总结
date: 2018-07-28 11:06:59
tags: Spring
总结
项目改进过程
jsp
这部分纯碎使用jsp开发,目的是熟悉jsp的基础知识.
所用到的知识包括:
- JSP基础语法
- 生命周期
- 页面之间跳转
- 使用bean
生命周期
页面跳转
页面之间直接使用超链接进行跳转.href一般为本路路径下目标jsp文件位置.
例:
requst.getContextPath获取的是应用的根路径
使用Bean
例:
JDBC
初始时使用JDBC访问数据库.比较麻烦,访问数据库分为以下几个步骤:
- 向DriverManager注册驱动器
- 建立与数据库的链接 con = java.sql.DriverManager.getConnection(url, user, pass)
- 创建State对象,准备执行SQL语句 Statement stat = con.createStatement()
- 执行SQL语句 ResultSet set = stat.executeQuery("sql sentence")
- 访问set中的结果集
- 依次关闭Resultset Statement Connection
配置数据源
web.xml中声明数据源
DB Connection
jdbc/BookDB
javax.sql.DataSource
Container
代码中定位数据源
Context ctx = new InitialContext();
if (ctx == null) {
throw new Exception("No Context");
}
mDataSource = (DataSource)ctx.lookup("java:comp/env/jdbc/BookDB");
直接使用datasource 获取连接
mDataSource.getConnection();
Maven
项目结构图
Maven用来解决项目中的依赖问题
右键项目,选择 add fragment support,添加maven支持.便会自动生成.pox文件
需要将之间的webapp目录完全拷贝到src/main目录下,不然打包的时候无法将web.xml和.jsp文件放到war包中,自然也就无法运行
引入Spring
项目里使用Java Config,没有使用xml方式.
替代在web.xml中配置dispatchservlet和contextloderlistener
使用JDBCtemplate
初始阶段直接使用JDBC访问数据库.代码有重复,并且抛出的异常信息不明确,使用Spring提供的JDBCTemplate不仅可以减少不必要的代码,还可以提供更加明确的异常信息.
首先需要配置数据源 (JNDI数据源 连接池数据源 JDBC驱动数据源)
- 使用连接池数据源
@Bean
public BasicDataSource dataSource() {
BasicDataSource ds = new BasicDataSource();
ds.setDriverClassName("com.mysql.jdbc.Driver");
ds.setUrl("jdbc:mysql://127.0.0.1:3306/bookdb?useUnicode=true&characterEncoding=UTF-8");
ds.setUsername("root");
ds.setPassword("123456");
return ds;
}
- 注册模板
@Bean
public JdbcTemplate jdbcTemplate(BasicDataSource dataSource) {
return new JdbcTemplate(dataSource);
}
- 使用模板
@AutoWired
private JdbcOperations jdbcOperations; //interface of jdbctemplate
public List getBooks() {
List list = jdbcOperations.query("select * from book", new BookRowMapper());
return list;
}
private static final class BookRowMapper implements RowMapper {
public Book mapRow(ResultSet res, int rowNum) throws SQLException {
return new Book(res.getString(1), res.getString(2), res.getFloat(3), res.getString(4));
}
}
使用SessionFactory
使用模板解决了重复代码的问题,但需要手动建立对象和数据库表之间的映射关系.ORM解决了这个问题,常用的ORM框架有Hibernate\Mybaits
在Spring中如何集成Hibernate框架:
sessionfactory---> session, 通过session进行增删改查.
// RootConfig
@Bean
public LocalSessionFactoryBean sessionFactoryBean(BasicDataSource dataSource) {
LocalSessionFactoryBean sessionFactoryBean = new LocalSessionFactoryBean();
sessionFactoryBean.setDataSource(dataSource);
sessionFactoryBean.setPackagesToScan("mypack.pojo");
Properties properties = new Properties();
properties.setProperty("dialect", "org.hibernate.dialect.MySQLDialect");
sessionFactoryBean.setHibernateProperties(properties);
sessionFactoryBean.setAnnotatedClasses(new Class>[]{Book.class});
return sessionFactoryBean;
}
public List getAll() {
List list = (List)sessionFactory.getCurrentSession().createCriteria(Book.class).list();
return list;
}
添加依赖
org.hibernate
hibernate-core
4.3.0.Final
** 添加注解 **
在Repository类或方法上需要添加@Transactional注解;否则报错:
Could not obtain transaction-synchronized Session for current thread;
nested exception is org.hibernate.HibernateException:
Could not obtain transaction-synchronized Session for current thread实体需要添加@Entity和@Table注解,并注明primery key:
@Id
@Column(name = "id") //没有注解的话,默认属性名对应数据库中的列名,不一致会报错"Unknown column xx in 'field list'"
private String mBookId;
@Column(name = "name")
private String mBookName;
@Column(name = "price")
private float mPrice;
@Column(name = "writer")
private String mWriter;
- RootConfig需要添加@EnableTransactionManagement,并注册HibernateTransactionManager bean.
@Bean
public HibernateTransactionManager manager(SessionFactory sessionFactory) {
HibernateTransactionManager manager = new HibernateTransactionManager();
manager.setSessionFactory(sessionFactory);
return manager;
}
** 捕获异常**
JDBCTemplate中可以捕获Hibernate的异常并使用Spring的非检查型异常抛出;在这里使用session进行数据库操作,如何捕获抛出Hibernate中的异常呢?
//在所有@Repository注解的类中添加一个通知器,捕获并抛出异常
@Bean
public BeanPostProcessor persistantenceTransaction() {
return new PersistenceExceptionTranslationPostProcessor();
}
使用EntityManager
- 配置EntityManagerFactory
//位于 RootConfig
@Bean
public JpaVendorAdapter jpaVendorAdapter() {
HibernateJpaVendorAdapter adapter = new HibernateJpaVendorAdapter();
adapter.setDatabase(Database.MYSQL);
adapter.setShowSql(true);
adapter.setGenerateDdl(false);
adapter.setDatabasePlatform("org.hibernate.dialect.MySQLDialect");
return adapter;
}
@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactoryBean(DataSource dataSource, JpaVendorAdapter adapter) {
LocalContainerEntityManagerFactoryBean cef = new LocalContainerEntityManagerFactoryBean();
cef.setDataSource(dataSource);
cef.setJpaVendorAdapter(adapter);
cef.setPackagesToScan("mypack.pojo");
return cef;
}
- 使用EntityManager
@PersistenceContext //注解为JPA提供,需要注册PersistenceAnnotationBeanPostProcessor才能让Spring识别
private EntityManager em; //但我的代码中并未注册,也正常运行,不知道系统在哪注册了.
Spring data jpa
由Spring在运行时自动生成持久化方法
- 提供extends JpaRepository
的接口
@Repository
public interface BookRepository extends JpaRepository {
}
- 在Controller中直接使用
ServletContext servletContext = request.getSession().getServletContext();
ApplicationContext context = WebApplicationContextUtils.getRequiredWebApplicationContext(servletContext);
BookRepository repository = context.getBean(BookRepository.class);
List list = repository.findAll();