Spring的數據庫開發
Spring JDBC框架操作mysql數據庫
- Spring中的JDBC為我們省去連接和關閉數據庫的代碼,我們著重關注對數據庫的操作。Spring框架在數據庫開發中的應用主要使用的是JDBCTemplate類,該類作為Spring對JDBC支持的核心,提供了所有對數據庫操作功能的支持。我們將使用JDBCTemplate類完成對mysql數據庫的增、刪、改、查等操作。
- Spring框架提供JDBC支持主要由4個包組成,分別是core(核心包)、object(對象包)、dataSource(數據源包)和support(支持包),JdbcTemplate類就在核心包中,該類包含所有數據庫操作的基本方法。
- core核心包:包含了JDBC的核心功能,重要的類:JdbcTemplate類、SimpleJdbcInsert類、SimpleJdbcCall類以及NamedParameterJdbcTemplate類;
- dataSource:數據源包,訪問數據源的實用工具類,他有多種數據源的實現,可以在JavaEE容器外部測試JDBC代碼;
- object:對象包,以面向對象的方式訪問數據庫,它允許執行查詢并返回結果作為業務對象,可以在數據表的列和業務對象的屬性之間映射查詢結果;
- support支持包:core和object包的支持類,例如,提供異常轉換功能的SQLException類。
- 首先介紹一下項目創建前的準備,本地mysql數據庫安裝完成,且可以用root用戶登入,登入密碼為123;而且需要額外的一些jar包:
然后在mysql數據庫中創建名為User的數據庫,此時數據庫User中沒有任何表項:
然后在Eclipse下新建Java項目,并且在src目錄下新建lib文件夾,將jar包復制到lib文件夾下,對jar包配置路徑(Build Path),然后在src目錄下新建包com.jdbc,在包下新建applicationContext.xml文件,該文件為Spring的JDBC配置文件,文件如下:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<!-- 配置數據源 -->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<!-- 數據庫驅動 -->
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<!-- 連接數據庫的URL 數據庫名為已經創建好的User -->
<property name="url" value="jdbc:mysql://localhost/User"/>
<!-- 連接數據庫的用戶名 -->
<property name="username" value="root"/>
<!-- 連接數據的密碼 -->
<property name="password" value="123"/>
</bean>
<!-- 配置JDBC模板 -->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<!-- 默認必須使用數據源 -->
<property name="dataSource" ref="dataSource"/>
</bean>
</beans>
JdbcTemplate提供大量的查詢和更新數據庫的方法,如下我們分別介紹execute()方法、update()方法、query()方法。
- execute()方法
execute(String sql)方法能夠完成執行SQL語句的功能,下面以創建和刪除數據庫表的SQL語句為例,在如上創建的Java項目的src目錄的com.jdbc下創建Client類,調用JdbcTemplate對象的execute()方法,實現對數據庫表的創建和刪除。代碼如下:
public class Client {
public static void main(String[] args) {
// TODO Auto-generated method stub
//定義配置文件路徑
String path = "com/jdbc/JdbcTemplateBeans.xml";
//加載配置文件
ApplicationContext applicationContext = new ClassPathXmlApplicationContext(path);
//獲取jdbcTemplate實例
JdbcTemplate jdbcTemplate = (JdbcTemplate) applicationContext.getBean("jdbcTemplate");
String sql = "create table t_user(userID int primary key auto_increment, userName varchar(20), password varchar(32))";
jdbcTemplate.execute(sql);
/*
* //當t_user表創建完成后,下一次執行如下兩條語句,該數據庫表t_user將會被刪除
*
String deltable = "drop table t_user";
jdbcTemplate.execute(deltable);*/
}
}
- update()方法
update()方法可以完成插入、更新和刪除操作。在update方法中存在多個重載的方法,具體介紹如下:
- int update(String sql):該方法是最簡單的update方法重載形式,可以直接傳入SQL語句并返回受影響的行數;
- int update(PreparedStatementCreatorpsc):該方法執行從PreparedStatementCreatorpsc返回的語句,然后返回受影響的行數;
- int update(String sql, PreparedStatementSetterpss):該方法通過PreparedStatementSetterpss設置SQL語句中的參數,并返回受影響的行數;
- int update(String sql, Object...args):該方法使用Object...args設置SQL語句中的參數,要求參數不能為空,并返回受影響的行數。
接下來我們實現對用戶信息的插入、修改和刪除操作。首次按創建User類和UserFactory工廠類,代碼如下:
public class User {
private int userID; //用戶ID
private String userName; //用戶名
private String passwd; //用戶密碼
public int getUserID() {
return userID;
}
public void setUserID(int userID) {
this.userID = userID;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPasswd() {
return passwd;
}
public void setPasswd(String passwd) {
this.passwd = passwd;
}
}
/*
*用戶工廠類負責創建User對象
*/
public class UserFactory {
public User createUser(String name, int id, String password){
User user = new User();
user.setUserName(name);
user.setUserID(id);
user.setPasswd(password);
return user;
}
}
接下來創建UserDao接口,負責定義對User數據的操作,實現對User的增加、修改和刪除操作,然后定義具體的實現類UserDaoImpl類,代碼如下:
/*
*定義對User對象的操作
*/
public interface UserDao {
public int addUser(User user);
public int updateUser(User user);
public int deleteUser(User user);
}
/*
* UserDao接口的具體實現類
*/
public class UserDaoImpl implements UserDao{
private JdbcTemplate jdbcTemplate;
public void setJdbcTemplate(JdbcTemplate jdbc){
this.jdbcTemplate = jdbc;
}
@Override
public int addUser(User user) {
// TODO Auto-generated method stub
String sql = "insert into t_user(userid,username,password)values(?,?,?)";
Object[] obj = new Object[]{
user.getUserID(),
user.getUserName(),
user.getPasswd()
};
return this.execute(sql, obj);
}
@Override
public int updateUser(User user) {
// TODO Auto-generated method stub
String sql = "update t_user set username=?,password=? where userid=?";
Object[] obj = new Object[]{
user.getUserName(),
user.getPasswd(),
user.getUserID()
};
return this.execute(sql, obj);
}
@Override
public int deleteUser(User user) {
// TODO Auto-generated method stub
String sql = "delete from t_user where userid=?";
Object[] obj = new Object[]{
user.getUserID()
};
return this.execute(sql, obj);
}
//負責SQL語句的執行
private int execute(String sql, Object[] obj){
return this.jdbcTemplate.update(sql, obj);
}
}
UserDaoImpl類中有對JdbcTemplate類的引用,因此要在applicationContext.xml文件中實現UserDaoImpl對JdbcTemplate類的依賴注入,則在如上的applicationContext.xml文件的基礎上,需要增加如下代碼:
<bean id="userDao" class="com.jdbc.UserDaoImpl">
<property name="jdbcTemplate" ref="jdbcTemplate"/>
</bean>
客戶端首先實現對User對象的添加操作,代碼如下:
public class Client {
public static void main(String[] args) {
// TODO Auto-generated method stub
//定義配置文件路徑
String path = "com/jdbc/JdbcTemplateBeans.xml";
//加載配置文件
ApplicationContext applicationContext = new ClassPathXmlApplicationContext(path);
//獲取jdbcTemplate實例
JdbcTemplate jdbcTemplate = (JdbcTemplate) applicationContext.getBean("jdbcTemplate");
String sql = "create table t_user(userid int primary key auto_increment, username varchar(20), password varchar(32))";
jdbcTemplate.execute(sql); //創建數據庫表
UserDao userDao = (UserDao) applicationContext.getBean("userDao");
User user1 = new UserFactory().createUser("張三", 1, "qwer");
User user2 = new UserFactory().createUser("李四", 2, "password");
User user3 = new UserFactory().createUser("王五", 3, "wangwu");
//插入三條數據,輸出為1則表示插入成功,否則插入失敗
System.out.println(userDao.addUser(user1));
System.out.println(userDao.addUser(user2));
System.out.println(userDao.addUser(user3));
}
}
在數據庫端,通過輸入select * from t_user; 查詢數據庫表中的數據,如下圖所示:
如上圖中,我們看到李四用戶的密碼不太合理,需要更改其密碼值,則Client的代碼如下:
public class Client {
public static void main(String[] args) {
// TODO Auto-generated method stub
//定義配置文件路徑
String path = "com/jdbc/JdbcTemplateBeans.xml";
//加載配置文件
ApplicationContext applicationContext = new ClassPathXmlApplicationContext(path);
UserDao userDao = (UserDao) applicationContext.getBean("userDao");
User user2 = new UserFactory().createUser("李四", 2, "lisi");
//更新李四用戶的密碼為lisi
userDao.updateUser(user2);
}
}
查詢數據庫t_user表可以看到李四用戶的密碼已經更改為lisi:
最后我們實現對張三用戶的刪除操作,代碼就很簡單了,如下:
public class Client {
public static void main(String[] args) {
// TODO Auto-generated method stub
//定義配置文件路徑
String path = "com/jdbc/JdbcTemplateBeans.xml";
//加載配置文件
ApplicationContext applicationContext = new ClassPathXmlApplicationContext(path);
UserDao userDao = (UserDao) applicationContext.getBean("userDao");
User user1 = new UserFactory().createUser("張三", 1, "qwer");
System.out.println(userDao.deleteUser(user1));
}
}
最后可以看到張三用戶被無情的從數據庫表t_user中刪除了:
- query()方法
JdbcTemplate對JDBC的流程做了封裝,提供了大量的query()方法來處理各種對數據庫表的查詢操作,常用的query()方法如下:
- List query(String sql, PreparedStatementSetterpss, RowMapper rowMapper):該方法根據String類型參數提供的SQL語句創建PreparedStatement對象,通過RowMapper將結果返回到List中;
- List query(String sql,Object[] args, RowMapper rowMapper):該方法使用Object[]的值來設置SQL中的參數值,采用RowMapper回調方法可以直接返回List類型的數據;
- queryForObject(String sql,Object[]args, RowMapper rowMapper):該方法將args參數綁定到SQL語句中,通過RowMapper返回單行記錄,并轉換為一個Object類型返回;
- queryForList(String sql, Object[] args, class<T>elementType):該方法可以返回多行數據的結果,但必須是返回列表,elementType參數返回的是List元素類型。
接下來,我們嘗試一下從t_user表中查詢數據,在UserDao接口中增加按照id查詢的方法和查詢所有用戶的方法,在UserDaoImpl中具體實現兩個方法,代碼如下:
public interface UserDao {
//在原有代碼基礎上增加的兩個方法
public User findUserByID(int id);
public List<User> findAllUser();
}
/*
* UserDao接口的具體實現類
*/
public class UserDaoImpl implements UserDao{
@Override
public User findUserByID(int id) {
// TODO Auto-generated method stub
String sql = "select * from t_user where userid=?";
//將結果集通過Java的反射機制映射到Java對象中
RowMapper<User> rowMapper = new BeanPropertyRowMapper(User.class);
return this.jdbcTemplate.queryForObject(sql, rowMapper, id);
}
@Override
public List<User> findAllUser() {
// TODO Auto-generated method stub
String sql = "select * from t_user";
RowMapper<User> rowMapper = new BeanPropertyRowMapper(User.class);
return this.jdbcTemplate.query(sql, rowMapper);
}
}
然后在Client類中調用者兩個方法,實現對t_user表的查詢操作:
public class Client {
public static void main(String[] args) {
// TODO Auto-generated method stub
//定義配置文件路徑
String path = "com/jdbc/JdbcTemplateBeans.xml";
//加載配置文件
ApplicationContext applicationContext = new ClassPathXmlApplicationContext(path);
User user = userDao.findUserByID(2);
System.out.println(user);
List<User> userList = userDao.findAllUser();
for(User u : userList){
System.out.println(u);
}
}
}
同時呢,User類中應該覆寫toString()方法,輸出用戶ID、用戶名和用戶密碼:
public class User {
//在原有代碼基礎上覆寫toString()方法
@Override
public String toString(){
return "user ID:" + this.getUserID() + " userName:" + this.getUserName() + " user password:" + this.getPassword();
}
}
運行該程序發現在Java反射的過程中password屬性的值為null, 即沒有將數據庫中的值映射到User對象中 ,那么問題出在哪里呢?數據庫表t_user中密碼字段標簽為password,然而Java在反射的過程中,會在User類中找setPassword(String password)方法,而本片博客的User類中設置密碼的方法為setPasswd(String passwd),導致在反射過程中無法找到setPassword(String password)方法,最終才會導致查詢出來的password字段值為空,解決方法當然是將User類中的setPasswd(String passwd)方法改名為setPassword(String password)即可。
本片文章介紹了JdbcTemplate類對mysql數據庫的操作,包括execute()、update()、query()三種方法,并通過案例演示了三種方法的使用。
來自:http://www.cnblogs.com/zhanglei93/p/6233900.html