(spring)Dao

DAO

学习dao前有数据库基础,java与数据库连接使用的是jdbc,在此前我已学习过jdbc也不再介绍jdbc,直接使用Spring的DAO模块,而在使用Spring的DAO,最基础的DAO模块对JDBC的支持。依赖于commons-dbcp.jar和commons-pool.jar。在pox中新添依赖。


    
      org.springframework
      spring-jdbc
      4.2.6.RELEASE
    

    
      commons-dbcp
      commons-dbcp
      1.4
    
    
      commons-pool
      commons-pool
      1.6
    

    
      mysql
      mysql-connector-java
      5.1.6
    

在传统的JDBC中需要创建连接、打开、执行SQL、关闭连接一系列的步骤,Spring对JDBC进行了封装,我们只需使用封装好的JdbcTemplate执行SQL语句就可以了。通过JdbcDaoSupport获取JdbcTemplate对象。

DAO的学习使用mysql,通过下语句新建一个数据库并插入5个值。

USE test;
DROP TABLE IF EXISTS `t_user`;
CREATE TABLE `t_user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(45) DEFAULT NULL,
  `age` int(11) DEFAULT NULL,
  `money` decimal(10,2) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=gbk;

INSERT INTO `t_user` VALUES ('1', '张三', '24', '666.66');
INSERT INTO `t_user` VALUES ('2', '李四', '25', '888.88');
INSERT INTO `t_user` VALUES ('3', '王二', '26', '999.99');
INSERT INTO `t_user` VALUES ('4', '小明', '27', '555.55');
INSERT INTO `t_user` VALUES ('5', '小赵', '28', '333.33');

一、JdbcDaoSupport的使用

该例实现了对上述创建的数据库进行输出和插入的功能。

1、User类

新建User类,定义类字段与数据库字段对应,并声明构造函数。

public class User {
    @Override
    public String toString(){
        return "Id:"+this.getId()+" Name:"+this.getName()
                +" Age:"+this.getAge()+" Money:"+this.getMoney();
    }
    private int Id;
    private String Name;
    private int Age;
    private double Money;
    public User(){}
    public User(String name,int age,double money){
        Name = name;
        Age = age;
        Money = money;
    }
    public int getId() {
        return Id;
    }
    public void setId(int id) {
        Id = id;
    }
    public String getName() {
        return Name;
    }
    public void setName(String name) {
        Name = name;
    }
    public int getAge() {
        return Age;
    }
    public void setAge(int age) {
        Age = age;
    }
    public double getMoney() {
        return Money;
    }
    public void setMoney(double money) {
        Money = money;
    }
}

2、IUserDAO接口

QueryAllUser方法查询数据库所有信息,AddUser为插入信息操作。

public interface IUserDAO {
    public List QueryAllUser();
    public Boolean AddUser(User user);
}

3、Xml配置

配置了数据库源,数据库用户和密码,因为SpringDAODemo中继承了JdbcDaoSupport,所以要设置dapends-on,这样才能从数据源中操作。



    
        
            com.mysql.jdbc.Driver
        
        
            jdbc:mysql://127.0.0.1:3306/test
        
        
            root
        
        
            951753
        
    
    
        
    

4、SpringDAODemo

程序入口类,并继承JdbcDaoSupport和实现IUserDAO接口中的方法。从JdbcDaoSupport中获取JdbcTemplate对象,使用queryForList方法进行sql查询,使用update方法进行sql更新。

在获取查询结果时,是将查询结果中的各行放到一个Map中,再将各个Map放到List中。因此得到结果后还需转化成List

public class SpringDAODemo extends JdbcDaoSupport implements IUserDAO {
    public static void main (String [] args){
        ApplicationContext context = 
        new ClassPathXmlApplicationContext("DAO/app.xml");
        IUserDAO userDAO = (IUserDAO)context.getBean("userDao");
        User user = new User("JdbcDaoSupportTest",26,333.33);
        userDAO.AddUser(user);
        List list = userDAO.QueryAllUser();
        for(User u:list){
            System.out.println(u.toString());
        }
    }
    @Override
    public List QueryAllUser() {
        String sql = "select id,name,age,money from t_user order by id desc";
        List> list = getJdbcTemplate().queryForList(sql);
        List userList = new ArrayList<>();
        for(Map row:list){
            User user  = new User();
            user.setId((Integer)row.get("id"));
            user.setName((String)row.get("name"));
            user.setAge((Integer)row.get("age"));
            user.setMoney(Double.parseDouble(row.get("money").toString()));
            userList.add(user);
        }
        return userList;
    }
    @Override
    public Boolean AddUser(User user) {
        String sql = "insert into t_user(name,age,money) values (?,?,?)";
        int row = getJdbcTemplate().update(sql,new Object[]{user.getName(),user.getAge(),user.getMoney()});
        if(row>0){
            System.out.println("数据新增成功!");
            return true;
        }
        return false;
    }
}

运行结果

Id:1 Name:张三 Age:24 Money:666.66
Id:2 Name:李四 Age:25 Money:888.88
Id:3 Name:王二 Age:26 Money:999.99
Id:4 Name:小明 Age:27 Money:666.66
Id:5 Name:小赵 Age:28 Money:333.33
Id:6 Name:JdbcDaoSupportTest Age:26 Money:333.33

二、MappingSqlQuery的使用

刚刚的JdbcDaoSupport的使用是获取一个List>,这样必须要写一个转换的方法,如果使用MappingSqlQuery可以返回List类型的值。

MappingSqlQuery是一个抽风象类,在使用他时需要实现它的方法mapRow。

这里相当于将JdbcDaoSupport中的Map,转换成了User类型,当他获取到一行数据时,会自动使用该方法,封装成User返回。

public class UserMappingSqlQuery extends MappingSqlQuery {
    @Override
    protected User mapRow(ResultSet resultSet, int i) throws SQLException {
        User user = new User();
        user.setId(resultSet.getInt("id"));
        user.setName(resultSet.getString("name"));
        user.setAge(resultSet.getInt("age"));
        user.setMoney(resultSet.getDouble("money"));
        return user;
    }
}

在使用UserMappingSqlQuery时,需要传入DataSource和sql,然后执行compile编译。可以直接通过getDataSource()来获取到JdbcDaoSupport的DataSource属性。在sql语句中如果有类似预处理的?参数,可以使用setParameters()设置参数。

下面将原本SpringDAODemo.QueryAllUser()方法修改,输出表中全部信息的功能不变。返回为List.

   @Override
    public List QueryAllUser() {
        String sql = "select id,name,age,money from t_user where name=? or ?";
        UserMappingSqlQuery userQuery = new UserMappingSqlQuery();
        userQuery.setDataSource(getDataSource());
        userQuery.setSql(sql);
        userQuery.setParameters(new SqlParameter[]{
                new SqlParameter(Types.VARCHAR)
                ,new SqlParameter(Types.VARCHAR)
        });
        userQuery.compile();
        return userQuery.execute(new Object[]{"1","1=1"});
    }

将方法替换后,执行结果与使用JdbcDaoSupport结果一致。

三、SqlUpdate的使用

SqlUpdate主要用来更新,将某个功能模块化。下例中,通过构造函数设置必须的参数,再使用updateUserMoney调用继承的update函数来更新数据。

public class UserSqlUpdate extends SqlUpdate {
    public static void main(String [] args){
        ApplicationContext context = new ClassPathXmlApplicationContext("DAO/app.xml");
        UserSqlUpdate userSqlUpdate = (UserSqlUpdate)context.getBean("userSqlUpdate");
        userSqlUpdate.updateUserMoney("小明",666.66);
    }
    public UserSqlUpdate(DataSource ds){
        setDataSource(ds);
        setSql("update t_user set money=? where name=?");
        declareParameter(new SqlParameter(Types.DOUBLE));
        declareParameter(new SqlParameter(Types.VARCHAR));
        compile();
    }
    public Boolean updateUserMoney(String name,double money){
        int row = update(new Object[]{new Double(money), name});
        if(row>0){
            System.out.println("money更改成功");
            return true;
        }
        return false;
    }
}

xml配置中为userSqlUpdata配置。

    
        
    

四、Spring事务管理

Spring中的事务管理是将DataSourceTransactionManager作为JDBC的事务管理者,同时把被管理的对象使用TransactionProxyFactoryBean配置,使用的也是代理模式。

用转账来示例事务管理,在IUserDAO接口中增加转账方法transfer

public Boolean transfer(int fromUserId,int toUserId, float transferMoney);

在SpringDAODemo类中实现transfer,从fromUserId中扣钱增加到toUserId中。其中有一个人为的制作的错误int i = 1/0被注释。

   @Override
    public Boolean transfer(int fromUserId, int toUserId, float transferMoney) {
        Boolean out = outInMoney(fromUserId,-transferMoney);
//        int i = 1/0;
        Boolean in = outInMoney(toUserId,transferMoney);
        return out∈
    }
    private Boolean outInMoney(int toUserId,float money){
        String sql = "update t_user set money=money+? where id=?";
        int row = getJdbcTemplate().update(sql,new Object[]{money,toUserId});
        if(row>0){
            return true;
        }
        return false;
    }

xml中配置管理事务,代理模式的注入我们已经很熟悉,这里是创建一个事务管理者,然后将事务管理者和被管理的对象注入到TransactionProxyFactoryBean中生成代理对象。在xml中增加以下代码。


        
    

    

        

        

        
            
                PROPAGATION_REQUIRED
            
        
    

注意事务属性PROPAGATION_REQUIRED的意义。

假如当前正要执行的事务不在另外一个事务里,那么就起一个新的事务。

因为扣钱和加钱都在同一个方法中,这时两个事务实际在同一个事务中。若在方法transfer第一次事务发生前,并无事务,在扣钱时,这时事务已经产生,并在第二次操作进行加钱时进行事务判断,已有事务并在同一个事务中,这时将第二次操作添加到已有事务。方法结束该事务结束。当在该事务中发生任何异常,将回滚已在该事务中的任何操作。

main

public static void main (String [] args){
        ApplicationContext context = new ClassPathXmlApplicationContext("DAO/app.xml");
        IUserDAO userDAO = (IUserDAO)context.getBean("userDaoProxy");
        try{
            userDAO.transfer(1,2,100);
        }catch (Exception e){
            e.printStackTrace();
            System.out.println("事务回滚");
        }
    }

成功将张三的钱转账给李四。当发生事务回滚时,转账会被回滚

Id:6 Name:JdbcDaoSupportTest Age:26 Money:333.33
Id:5 Name:小赵 Age:28 Money:333.33
Id:4 Name:小明 Age:27 Money:666.66
Id:3 Name:王二 Age:26 Money:999.99
Id:2 Name:李四 Age:25 Money:988.88
Id:1 Name:张三 Age:24 Money:566.66

你可能感兴趣的:((spring)Dao)