Spring整合hibernate的一个例子:用事务买书
jar包:
基本的文件框架:
1.首先配置jdbc的连接数据,也就是db.properties
此处注意在url上,这里不是xml文件,不需要加上amp。用一个问号就可以
1 2 3 4 | user=root password= driverClass=com.mysql.jdbc.Driver url=jdbc:mysql: //localhost:3306/spring001?useUnicode=true&characterEncoding=UTF-8 |
2.在 spring-config.xml 的spring容器中配置好加载db.properites的语句:
1 2 3 4 5 6 7 8 9 10 11 12 | <context:property-placeholder location= "classpath:db.properties" /> <!--扫描的--> <context:component-scan base- package = "com" /> <!--数据源--> <bean id= "dataSource" class = "com.mchange.v2.c3p0.ComboPooledDataSource" > <property name= "user" value= "${user}" /> <property name= "password" value= "${password}" /> <property name= "driverClass" value= "${driverClass}" /> <property name= "jdbcUrl" value= "${url}" /> </bean> |
3.用idea从设计好的数据库表格生成实体类和映射文件
BooInfo.java和Buyer.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 | package com.entities; import javax.persistence.*; /** * Created by Anonymous on 2016/3/19. */ @Entity @Table(name = "book_info" , schema = "spring001" ) public class BookInfo { private int id; private String bookname; private Integer bookprice; private Integer booknum; @Override public String toString() { return "BookInfo{" + "id=" + id + ", bookname='" + bookname + '\ '' + ", bookprice=" + bookprice + ", booknum=" + booknum + '}' ; } @Id @Column(name = "id" , nullable = false ) public int getId() { return id; } public void setId( int id) { this .id = id; } @Basic @Column(name = "BOOKNAME" , nullable = true , length = 255 ) public String getBookname() { return bookname; } public void setBookname( String bookname) { this .bookname = bookname; } @Basic @Column(name = "BOOKPRICE" , nullable = true ) public Integer getBookprice() { return bookprice; } public void setBookprice(Integer bookprice) { this .bookprice = bookprice; } @Basic @Column(name = "BOOKNUM" , nullable = true ) public Integer getBooknum() { return booknum; } public void setBooknum(Integer booknum) { this .booknum = booknum; } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | package com.entities; import javax.persistence.Basic; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.Id; @Entity public class Buyer { private int id; private String user; private Integer money; @Id @Column(name = "ID" , nullable = false ) public int getId() { return id; } public void setId( int id) { this .id = id; } @Basic @Column(name = "USER" , nullable = true , length = 255 ) public String getUser() { return user; } public void setUser( String user) { this .user = user; } @Basic @Column(name = "MONEY" , nullable = true ) public Integer getMoney() { return money; } public void setMoney(Integer money) { this .money = money; } } |
4.在ioc配置文件中配置好sessionFactory,在这里写好了hibernate.cfg.xml的内容,就不用生成它了。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | <!--hibernate的工厂--> <bean id= "sessionFactory" class = "org.springframework.orm.hibernate5.LocalSessionFactoryBean" > <property name= "dataSource" ref= "dataSource" /> <property name= "mappingLocations" value= "classpath:*.hbm.xml" ></property> <property name= "hibernateProperties" > <props> <prop key= "hibernate.format_sql" > true </prop> <prop key= "hibernate.show_sql" > true </prop> <prop key= "hibernate.hbm2ddl.auto" >update</prop> <prop key= "hibernate.dialect" >org.hibernate.dialect.MySQL5InnoDBDialect</prop> </props> </property> </bean> |
映射文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | <?xml version= '1.0' encoding= 'utf-8' ?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" <hibernate-mapping> < class name= "com.entities.BookInfo" table= "book_info" schema= "spring001" > <id name= "id" > <column name= "id" sql-type= "int(11)" /> <generator class = "native" /> </id> <property name= "bookname" > <column name= "BOOKNAME" sql-type= "varchar(255)" not- null = "true" /> </property> <property name= "bookprice" > <column name= "BOOKPRICE" sql-type= "int(11)" not- null = "true" /> </property> <property name= "booknum" > <column name= "BOOKNUM" sql-type= "int(11)" not- null = "true" /> </property> </ class > </hibernate-mapping> |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | <?xml version= '1.0' encoding= 'utf-8' ?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" <hibernate-mapping> < class name= "com.entities.Buyer" table= "buyer" schema= "spring001" > <id name= "id" > <column name= "ID" sql-type= "int(11)" /> <generator class = "native" /> </id> <property name= "user" > <column name= "USER" sql-type= "varchar(255)" not- null = "true" /> </property> <property name= "money" > <column name= "MONEY" sql-type= "int(11)" not- null = "true" /> </property> </ class > </hibernate-mapping> |
5.写买书的一个接口好实现类:
SomeActions.java 和SomeActionsImpl.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | package com.com.actions; /** * Created by Anonymous on 2016/3/19. */ public interface SomeActions { //获取所有书本的信息 public void getBooksInfo(); //获取某一个本书的价格 public int checkBookPrice( String bookName); //买书后更新书的数量 public void updateBookNum( String bookName); //买书后更新人的钱 public void updateBuyerMoney( String userName, int price); } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 | package com.com.actions; import com.entities.BookInfo; import com.exceptions.BookNumException; import com.exceptions.CheckNullException; import com.exceptions.MoneyCheckException; import org.hibernate.Query; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Repository; import java.util.Iterator; import java.util.List; @Repository public class SomeActionsImpl implements SomeActions { @Autowired private SessionFactory factory; public Session getSession() { return factory.getCurrentSession(); } @Override public void getBooksInfo() { String hql = "From BookInfo" ; Query query = getSession().createQuery(hql); List<BookInfo> list = query.list(); Iterator it = list.iterator(); while (it.hasNext()) { BookInfo info = (BookInfo) it.next(); System.out.println(info); } } @Override public int checkBookPrice( String bookName) { String hql = "select bookprice from BookInfo where bookname=:bookname" ; Query query = getSession().createQuery(hql); query.setString( "bookname" , bookName); if (query.uniqueResult() == null ) { throw new CheckNullException( "检索数据库中无此内容,请检查输入内容是否包含在数据库中......" ); } else { return (Integer) query.uniqueResult(); } } @Override public void updateBookNum( String bookName) { String hql1 = "select bookprice from BookInfo where bookname=:bookname" ; int bookNum = (Integer) getSession().createQuery(hql1).setString( "bookname" , bookName).uniqueResult(); if (bookNum == 0 ) { throw new BookNumException( "库存不够了" ); } String hql = "update BookInfo set booknum=booknum-1 where bookname=:bookname" ; getSession().createQuery(hql).setString( "bookname" , bookName).executeUpdate(); } @Override public void updateBuyerMoney( String userName, int price) { String hql1 = "select money from Buyer where user=:user" ; Query query = getSession().createQuery(hql1).setString( "user" , userName); int money = (Integer) query.uniqueResult(); if (money < price) { throw new MoneyCheckException( "余额不够了....." ); } String hql = "update Buyer set money=money-:price where user=:user" ; getSession().createQuery(hql).setInteger( "price" , price).setString( "user" , userName).executeUpdate(); } } |
6.写几个简单的继承runtimeException的类,提示出错信息:三个内容一样,就是类名不一样:
BookNumException.java和CheckNullException.java和MoneyCheckException.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | package com.exceptions; /** * Created by Anonymous on 2016/3/19. */ public class MoneyCheckException extends RuntimeException { public MoneyCheckException() { super (); } public MoneyCheckException( String message) { super (message); } public MoneyCheckException( String message, Throwable cause) { super (message, cause); } public MoneyCheckException(Throwable cause) { super (cause); } protected MoneyCheckException( String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { super (message, cause, enableSuppression, writableStackTrace); } } |
7.开始写事务的类,买一本书的类BuyOneBook.java
接口与实现类
1 2 3 4 5 6 7 8 | package com.services; public interface BuyOneBook { public void purchase( String buyerName, String bookName); } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | package com.services; import com.com.actions.SomeActions; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @Service public class BuyOneBookImpl implements BuyOneBook { @Autowired private SomeActions actions; @Override public void purchase( String buyerName, String bookName) { actions.getBooksInfo(); int price = actions.checkBookPrice(bookName); actions.updateBookNum(bookName); actions.updateBuyerMoney(buyerName, price); } } |
买多本书的类,接口类与实现类:
1 2 3 4 5 6 7 8 9 10 11 12 | package com.services; import java.util.List; /** * Created by Anonymous on 2016/3/19. */ public interface BuySomeBooks { public void buySome( String buyerName, List< String > bookNames); } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | package com.services; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.List; @Service public class BuySomeBooksImpl implements BuySomeBooks { @Autowired private BuyOneBook buyOneBook; @Override public void buySome( String buyerName, List< String > bookNames) { for ( String s : bookNames) { buyOneBook.purchase(buyerName, s); } } } |
8.在ioc容器中配置事务方面的内容:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | <!--事务管理器--> <bean id= "transactionManager" class = "org.springframework.orm.hibernate5.HibernateTransactionManager" > <property name= "sessionFactory" ref= "sessionFactory" /> </bean> <!--配置切面,对哪些方法起作用,并且交给事务管理--> <tx:advice id= "conn" transaction-manager= "transactionManager" > <tx:attributes> <tx:method name= "purchase" propagation= "REQUIRED" /> <tx:method name= "get*" read-only= "true" /> <tx:method name= "*" /> </tx:attributes> </tx:advice> <!--配置切点,并且放到切面设置上--> <aop:config> <aop:pointcut id= "pointCut" expression= "execution(* com.services.*.*(..))" /> <aop:advisor advice-ref= "conn" pointcut-ref= "pointCut" ></aop:advisor> </aop:config> |
完整的ioc文件:spring-config.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | <!--事务管理器--> <bean id= "transactionManager" class = "org.springframework.orm.hibernate5.HibernateTransactionManager" > <property name= "sessionFactory" ref= "sessionFactory" /> </bean> <!--配置切面,对哪些方法起作用,并且交给事务管理--> <tx:advice id= "conn" transaction-manager= "transactionManager" > <tx:attributes> <tx:method name= "purchase" propagation= "REQUIRED" /> <tx:method name= "get*" read-only= "true" /> <tx:method name= "*" /> </tx:attributes> </tx:advice> <!--配置切点,并且放到切面设置上--> <aop:config> <aop:pointcut id= "pointCut" expression= "execution(* com.services.*.*(..))" /> <aop:advisor advice-ref= "conn" pointcut-ref= "pointCut" ></aop:advisor> </aop:config> |
测试类:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | package com.test; import com.com.actions.SomeActions; import com.services.BuyOneBook; import com.services.BuySomeBooks; import org.junit.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import javax.sql.DataSource; import java.sql.SQLException; import java.util.Arrays; public class Main { private ApplicationContext ac = null ; private BuyOneBook buyOneBook; private BuySomeBooks buySomeBooks; @Autowired private SomeActions someActions; public Main() { ac = new ClassPathXmlApplicationContext( "spring-config.xml" ); buyOneBook = ac.getBean(BuyOneBook. class ); buySomeBooks = ac.getBean(BuySomeBooks. class ); } @Test public void testBuyOne() { buyOneBook.purchase( "Tom" , "西游记" ); } @Test public void testBuySome() { buySomeBooks.buySome( "Tom" , Arrays.asList( "三国演义" , "西游记" )); } @Test public void testConnection() throws SQLException { DataSource dataSource = (DataSource) ac.getBean( "dataSource" ); System.out.println(dataSource.getConnection()); } } |